从XXE漏洞修复引起Not supported: http://javax.xml.XMLConstants/property ...

打印 上一主题 下一主题

主题 938|帖子 938|积分 2814

引子 
  在使用Fortify扫描时代码报XML External Entity Injection,此漏洞为xml实体注入漏洞,XXE攻击可利用在处理时动态构建文档的 XML 功能。修复方案也包含了增加安全配置,使它不允许将外部实体包含在传入的 XML 文档中。
    具体在修复过程中,代码在解析drools的transfer.xls时,调用代码中增加内容,包括serFeature和setAttribute
  1. TransformerFactory factory = TransformerFactory.newInstance();                <br>factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
  2. factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,"");
复制代码
  1. 但在执行第二行,<br>
复制代码
  1. factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); 
复制代码
时,抛出异常
  1. 不支持:http://javax.xml.XMLConstants/property/accessExternalDTD  <br>at org.apache.xalan.processor.TransformerFactoryImpl.setAttribute(TransformerFactoryImpl.java:571)  <br>at XlsJava.main(XlsJava.java:10)
复制代码
 
跟踪与定位    
    仔细查看代码,定义为javax.xml.transform.TransformerFactory的factory在setAttribute时却进入到了路径为org\apache\xalan\processor\TransformerFactoryImpl.class的类。
     出现这个情况,因为项目中依赖了xalan的包,而在xalan包中指定了META-INF\services

因为这个设置,将完全限定名称为javax.xml.transform.TransformerFactory类的方法映射到了路径为
  1. org.apache.xalan.processor.TransformerFactoryImpl
复制代码
的类上,而在此类中经过一系列判断最终抛出异常

解决方案
    解决这个问题的方法也很简单,只需要在调用此段代码的工程之下,覆盖xalan包的设置即可。具体实现为,在调用
  1. factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
复制代码
的工程下配置META-INF/services路径,新建名称为
  1. javax.xml.transform.TransformerFactory
复制代码
的文件,其文件内容为
  1. com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
复制代码
如图

SPI机制
  SPI是Service Provider Interface 的简称,即服务提供者接口的意思。上文所使用的处理方法就是SPI机制的实例。SPI自jdk1.6开始引入,此后便有了广泛的应用,最常见的就是数据库连接,JDK提供了一个java.sql.Driver接口,根据不同的数据库厂商来引入不同的JDBC驱动包,比如MySQL这些数据库驱动其实都会实现这个驱动类。SPI机制要求拓展内容需存放在resources/META-INF/services目录下,META-INF用于存储服务提供者(service provider)的配置文件,serviceloader从META-INF/services中文件查找service的实现,该文件具有与service接口相同的限定名,其内容包括实现的限定名列表。如此,serviceloader将调用META-INF/services中文件的具体实现。所以,
  1. javax.xml.transform.TransformerFactory
复制代码
类的实现,却在调用方法的时候定位到了
  1. org.apache.xalan.processor.TransformerFactoryImpl
复制代码
  为什么必须是META-INF/services之下?看了源码你可能就会明白
  1. public final class ServiceLoader<S> implements Iterable<S>{
  2.     private static final String PREFIX = "META-INF/services/";
  3. }
复制代码
  
SPI机制的优缺点
优点

  • 其核心思想就是解耦,让接口和实现分离开来
  • 提高框架的扩展性,可以使框架根据实际业务情况启用扩展或替换框架组件
缺点

  • serviceloader对实现类的加载使用的是懒加载,在使用循环遍历时,即使是不必要加载的类同样会被实例化,造成浪费
  • serviceloader不是线程安全的
更多的关于SPI的相关内容,参考官方文档https://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
 
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

莫张周刘王

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表