如何防止 TransformerFactory 上的 XML 外部实体注入

Posted

技术标签:

【中文标题】如何防止 TransformerFactory 上的 XML 外部实体注入【英文标题】:How to Prevent XML External Entity Injection on TransformerFactory 【发布时间】:2015-11-17 15:44:14 【问题描述】:

我的问题:

Fortify 4.2.1 将以下代码标记为易受 XML 外部实体攻击。

TransformerFactory factory = TransformerFactory.newInstance();
StreamSource xslStream = new StreamSource(inputXSL);
Transformer transformer = factory.newTransformer(xslStream);

我尝试过的解决方案:

    XMLConstants.FEATURE_SECURE_PROCESSING 的 TransformerFactory 功能设置为 true。

    研究了为 TransformerFactory 提供更多此类功能的可能性,就像我们为 DOM 和 SAX 解析器所做的那样。例如不允许 doctype 声明等。但 TransformerFactoryImpl 似乎不接受 XMLConstants.FEATURE_SECURE_PROCESSING 的任何其他内容。 Impl Code

请指出您认为我可能没有使用过的任何资源或可能解决此问题的方法。

【问题讨论】:

我对 Fortify 不熟悉,但您说对于 SAX 解析器,您知道如何满足 Fortify 的要求,在这种情况下,我想知道是否提供 SAXSource 而不是 StreamSource,您可以在其中设置所有必需的功能SAX 解析器,工作正常。 @MartinHonnen 谢谢,让我试试这个,我会回来的。 @RaviRanjan 我也有同样的问题。你能解决你的问题吗? @ThusithaThilinaDayaratne 我很难找到一个具体的解决方案,所以我只在 TransformerFactory 类上设置了 XMLConstants.FEATURE_SECURE_PROCESSING。另外,我可以指向 xalan 和 javas 自己的 TrasnformerFactoryImpl 实现类的实现,以针对您的问题的任何解决方案进行更多研究。如果您能够通过,请分享您的发现。 我也面临类似的问题如果有任何解决方案正在使用 java 1.6,请告诉我 【参考方案1】:

由于市场上有很多 xml 解析引擎,每个引擎都有自己的机制来禁用外部实体注入。请参阅您的引擎的文档。下面是使用 SAX 解析器时防止它的示例。

基础是不允许 DOCTYPE 声明。但是,如果需要禁用外部通用实体和外部参数实体,则不会欺骗底层 SAX 解析器进行 XXE 注入。

public class MyDocumentBuilderFactory

    public static DocumentBuilderFactory newDocumentBuilderFactory()

        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();

        try

            documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
            documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities",false);
            documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities",false);

        catch(ParserConfigurationException exp)
            exp.printStackTrace();
        

        return documentBuilderFactory;
    

【讨论】:

建议有效,但我认为参考 OWASP 建议很重要,因为它包含更多信息github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/…【参考方案2】:
TransformerFactory trfactory = TransformerFactory.newInstance();
trfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
trfactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
trfactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

我认为这就足够了。

Fortify 会建议以下功能,但这些功能不适用于 TransformerFactory

factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

我们可能需要更改为不同的解析器才能使用它们。

【讨论】:

谢谢,这是可能需要的change to a different parser to make use of them. 但是指向一些可靠的解析器可能会更有帮助。 如果您的 TransformerFactory 实现不支持此功能,这将引发错误 java.lang.IllegalArgumentException: Unknown configuration property http://javax.xml.XMLConstants/property/accessExternalDTD 这对我有用,谢谢):。在此之前,我尝试了 Fortify 建议的解决方案,但没有成功。 @user835199 我也得到了 java.lang.IllegalArgumentException: Unknown configuration property javax.xml.XMLConstants/property/accessExternalDTD 这个异常。

以上是关于如何防止 TransformerFactory 上的 XML 外部实体注入的主要内容,如果未能解决你的问题,请参考以下文章

如何防止具有 META-INF\services\javax.xml.transform.TransformerFactory 的 xalan.jar 接管 Xalan 实现中内置的 JDK 1.6?

如何在 Java 中选择撒克逊 TransformerFactory

TransformerFactory 和 Xalan 依赖冲突

是否可以避免使用 xalan TransformerFactory?

要求在多线程环境中明确 TransformerFactory 的 XSLT Transformer

使用Java生成XML文件时,如何能让文件自动换行?