如何修复 Java 中的“禁用 XML 外部实体 (XXE) 处理”漏洞

Posted

技术标签:

【中文标题】如何修复 Java 中的“禁用 XML 外部实体 (XXE) 处理”漏洞【英文标题】:how to fix 'Disable XML external entity (XXE) processing' vulnerabilities in java 【发布时间】:2019-11-08 15:56:12 【问题描述】:

我针对 sonarqube 运行了我的 java 代码,我得到了“禁用 XML 外部实体 (XXE) 处理”作为漏洞。我花了一些时间在谷歌上解决这个问题。我一直在尝试很多方法,但没有什么对我有用。我不知道我错过了什么

我的代码:

        final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        docFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
        docFactory.setFeature(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
        docFactory.setFeature(XMLInputFactory.SUPPORT_DTD, false);

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

        final DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        final Document doc = docBuilder.parse(filepath);

我正在使用 java 1.8,感谢任何帮助。谢谢

【问题讨论】:

您是否看过:***.com/questions/40649152/how-to-prevent-xxe-attack 以及来自 Sonar 的这条规则:sonarcloud.io/organizations/alexlittle-github/… 您的代码对我来说看起来不错,也许检查器只是愚蠢。此外,人们经常忘记的是,XXE 漏洞仅适用于处理不受信任的 XML。如果您知道 XML 的来源并信任生成它的代码,那么 XXE 就不是问题。不幸的是,尽管安全人员并不总是理解这种微妙之处。 嗨 iCrus。我已经尝试了 sonarqube 的所有这些可能性,但我仍然没有修复 【参考方案1】:

我最终添加了以下所有属性以避免 Sonar 抱怨此漏洞:

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        //REDHAT
        //https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf
        factory.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, true);
        factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
        factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");

        //OWASP
        //https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
        factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
        factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        // Disable external DTDs as well
        factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        // and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
        factory.setXIncludeAware(false);
        factory.setExpandEntityReferences(false);

        DocumentBuilder builder = factory.newDocumentBuilder();

【讨论】:

【参考方案2】:

只需设置这两个属性就足够了:

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

【讨论】:

【参考方案3】:

Java 9+ 解决方案:

对我来说,将 DocumentBuilderFactory.newInstance() 更改为 DocumentBuilderFactory.newDefaultInstance() 足以消除此警告。

【讨论】:

在 javax.xml.parsers.DocumentBuilderFactory 上看不到方法 newDefaultInstance() @Anand 它是在 Java 9 中引入的。 在没有附加信息的情况下,这听起来更像是一种击败 Sonar 的检查的方法(例如,它不知道这个方法,所以它不标记它),而不是解决底层漏洞。基本上,看起来你做了同样的事情,但在声纳的背后。 (再一次,没有额外的信息)。 @GPI 这可能是真的,我还没有调查过。如果有人知道这种行为背后的原因,请随时编辑答案添加它【参考方案4】:

我已经通过添加以下代码 sn-p 解决了这个问题:

saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
saxParserFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
saxParserFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);    
saxParserFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
saxParserFactory.setXIncludeAware(false);

【讨论】:

以上是关于如何修复 Java 中的“禁用 XML 外部实体 (XXE) 处理”漏洞的主要内容,如果未能解决你的问题,请参考以下文章

如何修复netbeans中的java语言级别错误

java - 如何修复Java中本机查询中的无效列名

Java:如何修复多种方法中的代码重复?

如何修复 Java 中的 OutOfMemory 错误?

如何修复“java.sql.SQLException:找不到列 'id'。” Spring Boot 中的错误

如何修复运行时错误-线程“main”java.util.NoSuchElementException中的异常