在 XMLReader (XXE) 中忽略 XML 文档类型声明

Ignore XML doctype declarations in XMLReader (XXE)

我使用非验证读取来显示或处理不受信任的 XML 文档,其中我不需要支持内部实体,但我确实希望能够处理,即使显示了 DOCTYPE .

随着 disallow DOCTYPE-decl feature of SAX I can make sure parsing a XML document has no risk of external entities or billion laughter DOS expansions. This is also recommended by the OWASP XXE prevention cheat-sheet.

XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);

reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

// or
reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
reader.setFeature("http://xml.org/sax/features/external-general-entities", false);    
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

然而不幸的是,这会在给出 DOCTYPE 时中止解析:

org.xml.sax.SAXParseException; systemId: file:... ; lineNumber: 2; columnNumber: 10;
    DOCTYPE is disallowed when the
    feature "http://apache.org/xml/features/disallow-doctype-decl" set to true.

如果我忽略这个致命错误,那么它将愉快地解析内部实体,正如您在此处看到的:https://gist.github.com/ecki/f84d53a58c48b13425a270439d4ed84a

我想知道,是否有功能的组合,所以我可以阅读但不评估 doctype 声明(特别是避免递归扩展)。

我希望避免定义我自己的特定于 Apache 的 security-manager 属性 或特殊的解析器。

根据 core-lib-devXMLReaderFactory 将在 Java 9 中弃用,获得 XMLReader 的方法是使用 SAX 解析器。

在这种情况下,可以使用 FSP(它建立了一些资源限制并删除了 ACCESS_EXTERNAL_DTD_SCHEMA 的远程模式处理程序):

SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setXIncludeaware(false);
// when FSP is activated explicit it will also restrict external entities
spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
XMLReader reader = spf.newSAXParser().getXMLReader();