XML外部实体注入(XXE)

XML外部实体注入(XXE)

XML外部实体注入(XML eXternal Entity Injection,XXE)是一种针对解析XML输入的应用程序的攻击。当应用程序处理包含不受信任的外部实体引用的XML输入,并使用配置不当的XML解析器时,就可能发生这种攻击。此类攻击可能导致机密数据泄露、拒绝服务攻击(DoS)、服务器端请求伪造(SSRF)以及从解析器所在服务器进行端口扫描等一系列系统安全问题。

XXE攻击的危害

  1. 机密数据泄露:攻击者可以利用XXE攻击读取系统中的机密文件或数据。
  2. 拒绝服务攻击(DoS):攻击者可以构造恶意的XML文档,导致解析器陷入无限循环或消耗大量资源,从而造成拒绝服务。
  3. 服务器端请求伪造(SSRF):攻击者可以利用XXE攻击,让服务器发送请求到任意地址,执行端口扫描或访问内部系统。
  4. 其他系统影响:包括但不限于代码执行、数据篡改和权限提升。

防止XXE攻击的有效措施

除了通用的输入验证,还可以采用以下方式有效防止XXE攻击:

  1. 禁用XML外部实体和DTD处理:在应用程序的所有XML解析器中禁用XML外部实体和DTD处理。
  2. 实施基于“白名单”的服务器端输入验证:过滤或清理XML文档、头信息或节点中的恶意数据。
  3. 验证XML或XSL文件上传功能:使用XSD验证或类似方法对输入进行验证。
  4. 及时打补丁或升级XML处理器和库:使用依赖项检查工具,确保使用最新版本的处理器和库,并将SOAP更新到SOAP 1.2或更高版本。

Java中的防范措施示例

防止XXE的最安全方法是完全禁用DTD(外部实体)。根据不同的解析器,方法如下:

1. SAXBuilder

SAXBuilder builder = new SAXBuilder(true);
Document doc = builder.build(new InputSource());

或者:

SAXBuilder builder = new SAXBuilder();
builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
builder.setFeature("http://xml.org/sax/features/external-general-entities", false);
builder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
builder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
Document doc = builder.build(new InputSource());

2. SAXReader

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

3. SAXTransformerFactory

SAXTransformerFactory sf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
StreamSource source = new StreamSource(new InputSource());
sf.newTransformerHandler(source);

4. SchemaFactory

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
StreamSource source = new StreamSource(new InputSource());
Schema schema = factory.newSchema(source);

5. TransformerFactory

TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
StreamSource source = new StreamSource(new InputSource());
tf.newTransformer().transform(source, new DOMResult());

6. ValidatorSample

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
Validator validator = schema.newValidator();
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
StreamSource source = new StreamSource(new InputSource());
validator.validate(source);

7. XMLReader

XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
reader.parse(new InputSource(new InputSource()));

.Net中的防范措施示例

1. LINQ to XML

在默认情况下,System.Xml.Linq库中的XElement和XDocument对象不会受到XXE注入攻击,但会受到DoS攻击。为了在不同攻击类型之间提供安全保障,请参考微软关于如何防止.NET中的XXE和XML拒绝服务攻击的指南。

2. XmlDictionaryReader

System.Xml.XmlDictionaryReader在默认情况下是安全的,因为当它试图解析DTD时,编译器会抛出一个异常。但是,如果使用不同的不安全XML解析器构造,它会变得不安全。

3. XmlDocument

在.NET Framework 4.5.2版本之前,System.Xml.XmlDocument在默认情况下是不安全的。以下是确保其安全的示例:

static void LoadXML()
{
   string xxePayload = "<!DOCTYPE doc [<!ENTITY win SYSTEM 'file:///C:/Users/testdata2.txt'>]>"
                     + "<doc>&win;</doc>";
   string xml = "<?xml version='1.0' ?>" + xxePayload;
   XmlDocument xmlDoc = new XmlDocument();
   // 设置为NULL以禁用DTD - 默认情况下不是NULL
   xmlDoc.XmlResolver = null;
   xmlDoc.LoadXml(xml);
   Console.WriteLine(xmlDoc.InnerText);
   Console.ReadLine();
}

在4.5.2及以上版本中,XmlDocument的XmlResolver默认设置为空。

4. XmlNodeReader

System.Xml.XmlNodeReader对象在默认情况下是安全的,即使使用不安全的解析器构造或包装在另一个不安全的解析器中也会忽略DTD。

5. XmlReader

System.Xml.XmlReader对象在默认情况下是安全的。在.NET版本4.5.2及以后,XmlReaderSettings的XmlResolver默认设置为null,提供了额外的安全保障。

6. XmlTextReader

在.NET Framework 4.5.2版本之前,XmlTextReader默认情况下是不安全的。以下是不同版本中的安全设置方法:

a) .NET 4.0之前
XmlTextReader reader = new XmlTextReader(stream);
// 需要设置为TRUE,因为默认是FALSE
reader.ProhibitDtd = true;
b) .NET 4.0 - .NET 4.5.2
XmlTextReader reader = new XmlTextReader(stream);
// 需要设置为Prohibit,因为默认是Parse
reader.DtdProcessing = DtdProcessing.Prohibit;
c) .NET 4.5.2及以上

在4.5.2及以上版本中,XmlTextReader的XmlResolver默认设置为空。如果创建自己的非空XmlResolver并使用默认设置或不安全设置,则会变得不安全。

参考链接

  1. OWASP XXE Prevention Cheat Sheet:https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
  2. Microsoft .NET Framework Security Guidelines:https://docs.microsoft.com/en-us/dotnet/standard/security/
  3. Java Secure Coding Guidelines:https://www.oracle.com/java/technologies/javase/seccodeguide.html

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑风风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值