【问题标题】:What is the effect of ignoring DTD specification in java?在java中忽略DTD规范有什么影响?
【发布时间】:2018-05-31 23:41:42
【问题描述】:

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

【问题讨论】:

    标签: java code-injection dtd xml


    【解决方案1】:

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

    JAXP DocumentBuilderFactory 和 SAXParserFactory

    DocumentBuilderFactory 和 SAXParserFactory XML 解析器都可以使用相同的技术进行配置,以保护它们免受 XXE 攻击。 此处仅介绍 DocumentBuilderFactory 示例。

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

    • 每个 XML 处理器实现都有自己的特性来控制 DTD 和外部实体的处理方式。

    对于 DocumentBuilderFactory 的语法高亮代码 sn-p,请单击 here

    对于 SAXParserFactory 的语法高亮代码 sn-p,请单击 here

    这些链接将为您提供如何将 DTD 用于两个解析器的完整详细信息。

    Xerces 1 特点:

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

    Xerces 2 特点:

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

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

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

    【讨论】:

      【解决方案2】:

      理想情况下,我们不应禁用 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;
                }
      });
      

      【讨论】:

      • 如果对你有帮助,你能接受答案吗?谢谢。
      【解决方案3】:

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

      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
      
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.parse(input);
      

      【讨论】:

        猜你喜欢
        • 2012-07-04
        • 2012-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-25
        • 1970-01-01
        相关资源
        最近更新 更多