XML External Entity (XXE) Injection
XML 外部エンティティ (XXE) インジェクション
概要
XXE (XML External Entity) インジェクションは、アプリケーションが適切な検証を行わずに信頼できないソースからの 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