代码之家  ›  专栏  ›  技术社区  ›  Sasikumar Murugesan

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

  •  2
  • Sasikumar Murugesan  · 技术社区  · 9 年前

    代码分析器工具正在通知 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 回复  |  直到 5 年前
        1
  •  3
  •   Jagadish Sharma U    9 年前

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

    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

        2
  •  1
  •   Dinesh Chitlangia    9 年前

    理想情况下,我们不应该禁用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;
              }
    });
    
        3
  •  1
  •   Bosco Han    6 年前

    在不禁用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);