XMLインジェクションとは、XML入力を操作して、アプリケーションがデータを解析したり解釈したりする方法を変更することです。これは、ユーザが制御する入力が、適切な検証なしに XML ドキュメントに挿入されることで発生し、攻撃者は、制御フローを変更したり、ロジックをバイパスしたり、危険なパーサの動作をトリガしたりするノード、属性、エンティティ、またはペイロードを注入することができます。今日のAPIを多用し、統合を重視するエコシステムにおいて、XMLインジェクションは、セキュリティチームが無視できない現実の脅威であり続けています。
単純な入力改ざんとは異なり、XMLインジェクションはXMLの表現力そのものを悪用するため、SOAP、SAML、IoTデバイス、企業統合、レガシー金融システムなどの複雑なシステムに影響を与える。
なぜXMLインジェクションはまだ重要なのか
JSONが現代のアプリケーションを支配しているとはいえ、XMLは企業ソフトウェア、認証プロトコル、バックエンドの統合に深く組み込まれています。攻撃者はXMLの構造を悪用することができます:
- ビジネスロジックを改ざんする
- 不正なノードを注入する
- XPathクエリを操作する
- XXEスタイルのファイル公開のトリガー
- スキーマ検証の中断
- XMLベースのサービス拒否を引き起こす
XMLの柔軟性は、その悪用を特に強力なものにする。
実際のCVEの例CVE-2025-13526
CVE-2025-13526 は、単純な XML 解析の設定ミスがファイルの完全な漏洩につながることを示している。このシステムは XML 設定ファイルのアップロードを許可していたが、 外部エンティティ解決を無効にすることに失敗していた。
悪意のあるペイロードの例:
xml
<!DOCTYPE data [...
]> <!
&xxxe;。
サーバーは /etc/passwdXMLインジェクションとXXEを組み合わせることで、どのように重要なファイルが公開されるかを示す。
XMLインジェクションの攻撃対象
攻撃者は罵倒する:
- ノード・インジェクション
- 属性インジェクション
- XPathクエリの操作
- スキーマ(XSD)の操作
- XXEペイロード
- DoSのためのエンティティ拡張
- XMLベースのワークフロー内のロジックバイパス
各カテゴリーは、システムの異なる層に影響を与える。
攻撃例(同量保存)
- ノード・インジェクションの操作
xml
商品>商品></商品
注入されたペイロード:
pgsql
true
その結果、XMLは構造的に破損し、不正な権限を付与する可能性がある。
XPathインジェクション
パイソン
query = f"//users/user[username/text()='{user}']"
悪意のある入力:
バッシュ
または'1'='1
これにより、不正なユーザー記録が暴露される。
XXEペイロード
xml
<!DOCTYPE foo [
]>&payload;。
スキーマの操作
xml
とする。
これは期待される検証動作を無効にする。
億の笑いDoS
xml
<!ENTITY a "ha"><!ENTITY b "&a;&a;"><!ENTITY c "&b;&b;">
大量展開はパーサーに過負荷をかける。
ディフェンステクニック
実体解決を無効にする
パイソン
parser = etree.XMLParser(resolve_entities=False, no_network=True)
安全なライブラリを使用する
パイソン
ETとしてdefusedxml.ElementTreeをインポートする。
強力なスキーマ検証
パイソン
schema.validate(input_xml)
XML文字列を連結しない
より安全なアプローチ
パイソン
el = Element("user") name_tag.text = user_input
比較表
| タイプ | ターゲット | 重大性 | インパクト |
|---|---|---|---|
| XMLインジェクション | 構造操作 | ミディアム-ハイ | ロジックバイパス |
| XPathインジェクション | クエリーコントロール | 高い | 不正アクセス |
| ゼクセ | パーサーの誤用 | 高い | ファイル読み込み/SSRF |
| スキーマ・インジェクション | バリデーション・バイパス | ミディアム | 完全性リスク |

自動ペネトレーションテストにおけるXMLインジェクション
Penligentのような最新のAI駆動型侵入テストプラットフォームは、構造変異、XMLファジング、XPathペイロードテスト、パーサ誤設定検出を実行します。これらのプラットフォームは
- XMLベースの攻撃サーフェスを発見する
- 注入ポイントの特定
- スキーマの動作を自動学習
- 適応ペイロードの生成
- 複数の設定下でパーサーの動作を検証する
これにより、検出範囲が大幅に拡大した。
セキュリティ・ベースラインと自動修正勧告
自動化されたプラットフォームも提供できる:
- パーサー設定監査
- 安全でないXMLライブラリの検出
- エンティティの解像度設定の検証
- 厳格なXSD検証の実施
- 安全でないXML操作のCI/CDブロック
これにより、検出が実行可能な是正措置に変わる。
スクリプト例
Semgrepルール - Python XMLインジェクション/XXE/安全でない解析
ファイルを作成する:
semgrep-rules/python-xml-injection.yaml
ヤムル
ルール:
ルール 1:xml.etreeの安全でない使用 - デフォルトのパーサーはXXEに弱い
- id: python-unsafe-xml-etree severity:ERROR メッセージ:| xml.etree.ElementTree は信頼されていない XML に対して安全ではありません。代わりに defusedxml を使ってください。代わりに defusedxml を使用してください:「CWE-611" owasp: "A04:2021 XML External Entities" パターン:
- パターンを使用します:| import xml.etree.ElementTree as ET languages:[python]
ルール2:xml.dom.minidomの直接使用 - 安全でないXMLパーサー
- id: python-unsafe-xml-minidom severity:ERROR メッセージ:| xml.dom.minidom は DTD や ENTITY の展開を無効にしません。メタデータ: cwe:「CWE-611" パターン:| import xml.dom.minidom languages:[python]
ルール 3: 危険な lxml XMLParser で resolve_entities=True を指定する。
- id: python-lxml-resolve-entities-enabled severity:ERROR メッセージ:| resolve_entities=True の lxml XMLParser() は XXE を有効にします。resolve_entities=False と load_dtd=False を設定してください:「CWE-611" パターン:| XMLParser(resolve_entities=True, ...) languages:[python]
ルール4:load_dtd=Trueのlxml - 危険
- id: python-lxml-load-dtd severity:警告メッセージ| load_dtd=True は DTD 処理を有効にし、エンティティの展開を許可します。メタデータ: cwe:「CWE-611" パターン:| XMLParser(load_dtd=True, ...) languages:[python]
ルール 5:lxml.fromstring()使用時に安全なパーサ設定がない。
- id: python-lxml-fromstring-no-safe-config severity:警告メッセージ:| 警告メッセージ: lxml.fromstring() が安全な XMLParser なしで呼び出されています。resolve_entities=False, no_network=True を確認してください:「CWE-611" パターン:
- パターン:| lxml import etree - パターン:| etree.fromstring($XML) languages:[python]
ルール6:外部 XML を解析する際に defusedxml を使用しない。
- id: python-defusedxml-notused severity:INFO メッセージ:| メタデータ: cwe:「CWE-611" pattern-either:
- パターン:| ET.parse($X) - パターン:| etree.parse($X) languages:[python]
RULE 7: 解除されたパーサーを強制しないxmltodict
- id: python-xmltodict-unsafe severity:警告メッセージ| 警告メッセージ: xmltodict は XXE を許可する XML パーサを呼び出すことができます。使用する
defusedxmlパーサを代わりに使います:| xmltodict.parse($X) languages:[python]
ルール8XML 由来の入力に対する eval() の危険な使用
- id: python-eval-from-xml severity:CRITICAL メッセージ| メッセージ: XML 由来の入力に対する eval() は RCE を引き起こす可能性があります。パースされた XML の値を直接評価しないでください:「CWE-95" owasp: "A03:2021 Injection" パターン:
- パターン:| $VAL = $XML.xpath(...) - パターン:| eval($VAL) languages:[パイソン]
ルール 9:XMLソースデータに対する安全でないpickle.loads
- id: python-pickle-on-xml severity:CRITICAL メッセージ| メッセージ: XML 由来の入力に対する pickle.loads() は任意のコードの実行につながる可能性があります。メタデータ: cwe:「CWE-502" パターン
- パターン:| $DATA = etree.fromstring(...) - パターン:| pickle.loads($DATA) languages:[python]`
完全な Python SAST スキャナー
これはSemgrepを補完するもので、以下のような危険なパターンをスキャンする:
- 安全でないXMLパーサのインポート
- ENTITY / DOCTYPE usage
評価,エグゼック,ピクルス,連邦保安官,yaml.loadパターン- のXXEトリガー
.xml,.xsd,.wsdlファイル
創造する: python_sast_scanner.py
パイソン
#!/usr/bin/env python3″"" python_sast_scanner.py 軽量で高速なPython専用のSASTスキャナです:
- XMLインジェクション/XXE
- 安全でないパーサの使用
- 危険な関数(eval、exec、pickle.loads、yaml.load) CIにとって安全である。JSONを出力し、発見された場合は0以外で終了する。"""import os, re, json, sys PATTERNS = {# XML / XXE "xml_etree": r "imports+xml.etree\.ElementTree", "xml_minidom": r "imports+xml.dom\.minidom", "lxml_resolve_entities": r "resolve_entities *=\sTrue", "lxml_load_dtd": r "load_dtds=s*True", "doctype_in_xml": r"<!DOCTYPE", "entity_in_xml": r"<!ENTITY"、

危険な機能
"eval_usage": r"\\beval\\s*\\(","exec_usage": r"\\bexec\\s*\\(","pickle_loads": r"pickle\\.loads\\s*\\(","marshal_loads": r"marshal\\.loads\\s*\\(","yaml_unsafe_load": r"yaml\\.load\\s*\\(",
}IGNORED = {".git", "venv", "env", "pycache", "dist", "build", "node_modules"} def scan_file(path): findings = []try:with open(path, "r", encoding="utf-8″, errors="ignore") as f:for i, line in enumerate(f, 1):for rule, regex in PATTERNS.items():if re.search(regex, line): findings.append({"rule": rule, "line": line.strip(), "lineno": i, })except Exception:pass return findings def walk(root="."): results={}for dp, dirs, files in os.walk(root): dirs[:] = [d for d in d if d not in IGNORED]for f in files:if f.endswith((".py",".xml",".xsd",".wsdl")): full = os.path.join(dp, f) hits = scan_file(full)if hits: results[full] = hitsreturn results def main(): root = sys.argv[1] if len(sys.argv)>1 else "." results = walk(root)print(json.dumps({"results": results, "file_count": len(results)}, indent=2))if results: sys.exit(3) sys.exit(0) if name == "main": main()`
パイソンSASTスコープ
XMLインジェクション/XXE
安全でないXMLパーサー ✔ lxml with resolve_entities=True DTD の読み込み(潜在的に危険) ✔ 保存された XML ファイル内の XXE マーカー
コード注入
✔ eval() ✔ exec()
安全でないデシリアライズ
✔ pickle.loads() ✔ marshal.loads() 安全でない yaml.load()
その他の危険なパターン
のENTITY / DOCTYPE .xml, .xsd, .wsdl 硬化パーサなしのxmltodict
結論
XMLインジェクションは、依然として適切かつ危険な脆弱性のカテゴリーである。その影響は、ビジネス・ロジックのバイパスから、ファイル公開やサービス拒否に及びます。XML の振る舞いを理解し、パーサを保護し、構造を検証し、自動化された侵入テストを組み込むことは、堅牢なアプリケーショ ン・セキュリティを確保するために不可欠なステップです。

