跳转至

XML External Entity (XXE) Injection

XML 外部实体 (XXE) 注入

描述

XXE(XML External Entity,XML 外部实体)注入是一个严重的安全性缺陷,当应用程序在没有适当验证的情况下解析来自不可信来源的 XML 输入时,就会产生此问题。攻击者通过在 XML 数据中注入外部实体来利用此漏洞,可能导致对服务器上敏感文件或目录(如 /etc/passwd)的未授权访问。这种破坏可使攻击者能够提取机密信息、破坏应用程序功能或执行任意代码。XXE 漏洞通常由于输入验证松懈和 XML 解析器配置不当导致,这使得恶意实体能够操纵 XML 结构。

示例

Java

//Input example : 
String xmlInput = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
    "<!DOCTYPE foo [<!ENTITY xxe SYSTEM \"file:///etc/passwd\">]>\n" +
    "<foo>&xxe;</foo>";

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(xmlInput.getBytes()));

// Process the XML document
// Access the parsed data, which could potentially include sensitive information

Javascript

const app = require("express")();
const libxml = require("libxmljs");
app.post("/path", (req, res) => {
  Element = libxml.parseXml(req.body, { noent: true });
 // Processing the XML element
});

PHP

<?php
$xmlInput = '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<foo>&xxe;</foo>';

$doc = new DOMDocument();
$doc->loadXML($xmlInput);

echo $doc->saveXML();
?>

建议

为了降低 XML 外部实体漏洞的风险,建议:

  • 禁用外部实体的解析。
  • 禁用对 XInclude 的支持。
//Input example : 
String xmlInput = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
    "<!DOCTYPE foo [<!ENTITY xxe SYSTEM \"file:///etc/passwd\">]>\n" +
    "<foo>&xxe;</foo>";

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

// Enable secure processing mode to mitigate common XML security vulnerabilities
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

// Disable external DTDs and stylesheets to prevent potential XXE attacks
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(xmlInput.getBytes()));
const app = require("express")();
const libxml = require("libxmljs");
app.post("/path", (req, res) => {
  Element = libxml.parseXml(req.body);
 // Processing the XML element
});
<?php
$loadEntities = libxml_disable_entity_loader(true);

$xmlInput = '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<foo>&xxe;</foo>';

$doc = new DOMDocument();
$doc->loadXML($xmlInput);

libxml_disable_entity_loader($loadEntities);

echo $doc->saveXML();
?>

链接

标准

  • CWE_TOP_25:
    • CWE_611
  • GDPR:
    • ART_25
    • ART_32
  • PCI_STANDARDS:
    • REQ_6_4
    • REQ_6_5
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_3_4
    • CC_4_1
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5
  • HIPAA_CONTROLS:
    • SECURITY212
    • SECURITY213
    • SECURITY255