服务与支持 |咨询热线 0931-8733767
  • 金城在线
  • 公司简介
  • 发展历程
  • 企业文化
  • 售后服务
  • 工作机会
  • 联系我们

解析xml时如何防范dtd xsd访问外网

来源:发布时间:2018-3-12 9:28:18

做Java的同学估计都碰过类似的故障,就是突然有一天启动应用的时候告诉你由于没获取到dtd或xsd文件应用启动失败,而通常这个时候你才会发现原来自己应用的启动竟然还依赖了外网的某个url,我记得当年ibatis切域名的那一次,就是突然一批机器启动失败,差点造成大故障,还有一次印象深刻的海底光缆断掉的那一次,也是差点引发大故障。


对于上面这样的现象,最好的办法自然是确保本地有相应的dtd/xsd文件,从而避免去外网加载,但为什么要做到这点这么麻烦呢,原因在于dtd/xsd文件到底从哪加载是完全可以由解析XML的程序自行来决定的,于是就悲催了。


在解析XML时可自行实现EntityResolver接口,例如Spring的BeansDtdResolver,在这个类中,Spring会首先从当前类的classloader中来获取相应路径的dtd文件,如找不到则从指定的classloader中获取,仍然找不到的话就返回null,当返回null后,外层的ResourceEntityResolver则会访问相应的url去获取dtd,对于xsd文件的处理也基本类似。


唯一还好的就是基本所有解析xml的程序在对dtd/xsd的处理上,都遵循了先尝试从本地装载,之后再从url装载的先后顺序。


对于这个头疼的问题,我之前见过的解决方法有:

1.将所有的dtd/xsd涉及的域名都解析到本地的一台机器,以避免访问外网的现象出现,这个的问题在于无法做到穷举,因为可能不是你的程序需要解析XML,而是你引用的其他jar中有;

2.禁止服务器访问外网,这样的好处就是问题暴露的比较直接,但可能有些应用确实会有需要访问外网的需求;

3.将xml文件中的dtd/xsd改为本地相对路径,这种一个问题是上面的穷举问题,另一个问题是相对路径到底如何访问其实同样取决于自定义实现的xml解析程序;

4.在解析xml时绕过dtd的验证,如果能保证xml文件格式没问题的话,可以绕掉dtd的验证,但xsd就不行了,xsd文件是必须获取到的,否则xml文件压根就没法解析。


目前我们没采用以上4个方法,在前年的时候由于连续出了好几次dtd/xsd访问不了导致各种应用启动不了的现象,我就花了点时间想办法去解决掉这个问题,当时我的解决思路是上面的4个方法在我们的场景中都不能解决,看起来一个折中的办法就是在测试阶段就发现这个问题,然后强迫应用解决掉,这样就可以确保部署到线上的时候访问的一定是本地。


要在测试阶段发现这个问题怎么做呢,想到的办法是用btrace来跟踪URL.openConnection的调用,如URL的结尾是.dtd或.xsd,那么就在日志中输出错误信息和堆栈信息,启动脚本在检查到错误信息后就让进程退出,这样可以确保应用方必须解决掉这个问题。


相关文章
  • 预约专家

    为您提供一对一解决方案
    立即预约
  • 售前咨询

    周一至周五9:00——17:30
    立即咨询
  • 联系方式

    13919049954

    全国7×24小时热线服务
  • 免费报价

    专属专业顾问1对1报价
    免费报价