在java中忽略DTD规范会有什么影响?

时间:2015-08-13 04:36:36

标签: java code-injection xml-dtd

代码分析工具正在通知XML Entity Expansion Injection,因为没有实现DTD规范。

所以我想通过

禁用DTD规范检查
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

所以我想知道

  1. 它会破坏实际的代码流吗?
  2. 它会导致问题吗?
  3. 还有其他办法可以处理吗?

3 个答案:

答案 0 :(得分:3)

要安全地使用解析器,您必须在您使用的解析器中显式禁用XXE。下面介绍如何在最常用的Java XML解析器中禁用XXE。

JAXP DocumentBuilderFactory和SAXParserFactory

可以使用相同的技术配置DocumentBuilderFactory和SAXParserFactory XML Parsers,以保护它们免受XXE的侵害。 此处仅显示了DocumentBuilderFactory示例。

  • JAXP DocumentBuilderFactory setFeature方法允许开发人员 控制哪些特定于实现的XML处理器功能 启用或禁用

  • 每个XML处理器实现都有自己的功能,用于管理DTD和外部实体的处理方式。

对于DocumentBuilderFactory的语法高亮显示的代码段,请点击here

有关SAXParserFactory的语法高亮显示的代码段,请点击here

链接将为您提供有关如何将DTD用于解析器的完整详细信息。

Xerces 1特点:

通过将此功能设置为false,不要包含外部实体。 通过将此功能设置为false,不要包含参数实体。

Xerces 2特点:

通过将此功能设置为true来禁止内联DTD。 通过将此功能设置为false,不要包含外部实体。 通过将此功能设置为false,不要包含参数实体。 StAX和XMLInputFactory 诸如XMLInputFactory之类的StAX解析器允许设置各种属性和特性。

要保护来自XXE的Java XMLInputFactory,请执行以下操作:

xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD,false); //这将完全禁用该工厂的DTD

答案 1 :(得分:1)

理想情况下,我们不应禁用DTD规范检查。 相反,如果找不到特定的DTD,请使用EntityResolver绕过DTD检查。

以下是创建一个将忽略所有外部引用实体的DocumentBuilder的方法,包括DTD:

final DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(new EntityResolver() {
    @Override
        public InputSource resolveEntity(String publicId, String systemId) {
                // it might be a good idea to insert a trace logging here that you are ignoring publicId/systemId
                return new InputSource(new StringReader("")); // Returns a valid dummy source
        }
    });

或者,您也可以执行以下操作:

final DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(new EntityResolver() {
          public InputSource resolveEntity(java.lang.String publicId, java.lang.String systemId)
                 throws SAXException, java.io.IOException
          {
            if (publicId.equals("--DTDpublicID--"))
              // this deactivates the DTD
              return new InputSource(new ByteArrayInputStream("<?xml version='1.0' encoding='UTF-8'?>".getBytes()));
            else return null;
          }
});

答案 2 :(得分:1)

没有为xml禁用DTD,您可以尝试使用&#34; SECURE_PROCESSING&#34; 这会处理易受XXE和dos攻击影响的xml解析:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(input);