java - 如何防止XXE攻击

标签 java xml xml-parsing transform

我们对我们的代码进行了安全审计,它提到我们的代码容易受到 XML 外部实体 (XXE) 攻击。

Explanation

XML External Entities attacks benefit from an XML feature to build documents dynamically at the time of processing. An XML entity allows inclusion of data dynamically from a given resource. External entities allow an XML document to include data from an external URI. Unless configured to do otherwise, external entities force the XML parser to access the resource specified by the URI, e.g., a file on the local machine or on a remote system. This behavior exposes the application to XML External Entity (XXE) attacks, which can be used to perform denial of service of the local system, gain unauthorized access to files on the local machine, scan remote machines, and perform denial of service of remote systems.

The following XML document shows an example of an XXE attack.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///dev/random" >]><foo>&xxe;</foo>

This example could crash the server (on a UNIX system), if the XML parser attempts to substitute the entity with the contents of the /dev/random file.

Recommendation

The XML unmarshaller should be configured securely so that it does not allow external entities as part of an incoming XML document.

To avoid XXE injection do not use unmarshal methods that process an XML source directly as java.io.File, java.io.Reader or java.io.InputStream. Parse the document with a securely configured parser and use an unmarshal method that takes the secure parser as the XML source as shown in the following example:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(<XML Source>);
Model model = (Model) u.unmarshal(document);

下面的代码是审计发现 XXE 攻击的地方:

Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
System.out.println("outputing to : " + outputLocation);
File outputFile = new File(outputLocation);
StreamResult result = new StreamResult(outputFile);
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);

如何在我的代码中实现上述建议?我哪里遗漏了什么?

最佳答案

您可以对 DocumentBuilderFactory 使用相同的方法:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
...

为了让每个人都能自动使用它,您需要创建自己的实现(通过扩展您当前使用的实现;使用您的调试器找出答案)。在构造函数中设置特征。

然后您可以将要在系统属性 javax.xml.parsers.DocumentBuilderFactory 中使用的新工厂传递给 Java VM,每个人都会使用它。

关于java - 如何防止XXE攻击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40649152/

相关文章:

xml - 我可以在 *.xml 文件上使用 tr ("") 和 lupdate 吗?

java - 解码长 XML 文件的单个非根节点

Android SeekBarPreference 自定义 View

c++ - 使用 libxml2 解析 XMPP 流

java - 了解在 TableView 中添加 ChangeListener

java - Spring Boot 请求 : to "re-run your application with ' debug' enabled"- how do I?

从数组转换为 vector 时的java泛型问题

java - 将 xml 从第 n 个元素拆分为第 x 个元素

C# : The best solution to parse the xml file?

java - PMD 多个规则集通过构建,但单个规则集构建失败