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

What is the effect of ignoring DTD specification in java?

代码分析器工具正在通知 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. 有没有其他办法处理?

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

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

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;
          }
});

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

JAXP DocumentBuilderFactory 和 SAXParserFactory

DocumentBuilderFactory 和 SAXParserFactory XML 可以使用相同的技术配置解析器以保护它们免受 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 解析器允许设置各种属性和功能。

要保护 Java XMLInputFactory 免受 XXE 攻击,请执行以下操作:

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

不为 xml 禁用 DTD,您可以尝试使用 "SECURE_PROCESSING" 这会处理 xml 易受 XXE 和 dos 攻击的解析:

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

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