13919049954

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

作者:金城在线 日期:2018/3/12 9:28:18 人气:312

做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,那么就在日志中输出错误信息和堆栈信息,启动脚本在检查到错误信息后就让进程退出,这样可以确保应用方必须解决掉这个问题。


            金城在线专注网站、软件、APP、微信公众平台、小程序、抖音、头条等开发推广,如果您有这方面的需求或者不同的观点,欢迎联系交流。

    官方微信

    本文网址:http://lz.net.cn/zixunzhongxin/762.html
    读完这篇文章后,您心情如何?
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    上一篇: 聊聊 JSONP 的 P
    更多>>网友评论
    发表评论