如何预防XXE攻击 [英] How to prevent XXE attack

查看:71
本文介绍了如何预防XXE攻击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们对代码进行了安全审核,并提到我们的代码容易受到XML EXternal Entity(XXE)攻击.

说明

XML外部实体攻击得益于XML功能,可以在处理时动态生成文档.XML实体允许动态包含来自给定资源的数据.外部实体允许XML文档包含数据来自外部URI.除非配置为其他方式,否则外部实体会强制XML解析器访问指定的资源取决于URI,例如本地计算机或远程系统上的文件.此行为将应用程序公开给XML External实体(XXE)攻击(可用于执行本地系统的拒绝服务)获得未经授权的访问,其中包括本地计算机,扫描远程计算机,并拒绝远程系统的服务.

以下XML文档显示了XXE攻击的示例.

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

如果XML解析器尝试将实体替换为XML的内容,则该示例可能会使服务器(在UNIX系统上)崩溃./dev/random文件.

推荐

应正确配置XML解组器,以便不允许将外部实体作为传入XML的一部分文档.

为避免XXE注入,请不要使用直接将XML源作为 java.io.File java.io.Reader java.io.InputStream .使用安全配置的解析器解析文档,并使用将安全解析器作为XML源的解组方法,如以下示例所示:

  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false);DocumentBuilder db = dbf.newDocumentBuilder();文档document = db.parse(< XML Source>);模型模型=(模型)u.unmarshal(文档); 

下面的代码是审计发现XXE攻击的位置:

  Transformer转换器= TransformerFactory.newInstance().newTransformer();Transformer.setOutputProperty(OutputKeys.INDENT,"yes");System.out.println(输出到:" + outputLocation);文件outputFile =新File(outputLocation);StreamResult结果=新的StreamResult(outputFile);DOMSource source =新的DOMSource(doc);Transformer.transform(来源,结果); 

如何在我的代码中实现以上建议?我在哪里想念东西?

解决方案

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

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

要使每个人都自动使用此功能,您需要创建自己的实现(通过扩展当前使用的实现;使用调试器进行查找).在构造函数中设置功能.<​​/p>

然后,您可以将新工厂传递给Java VM的系统属性 javax.xml.parsers.DocumentBuilderFactory 中使用,

We had a security audit on our code, and it mentioned that our code is vulnerable to XML EXternal Entity (XXE) attacks.

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);

The code below is where the audit found the XXE attack:

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);

How can I implement the above recommendation in my code? Where am I missing things?

解决方案

You can use the same approach with DocumentBuilderFactory:

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

To make everyone use this automatically, you need to create your own implementation (by extending the one which you're currenly using; use your debugger to find out). Set the feature in the constructor.

Then you can pass the new factory to use in the System property javax.xml.parsers.DocumentBuilderFactory to the Java VM and everyone will use it.

这篇关于如何预防XXE攻击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆