「XMLを使ったAPIがあるけど、セキュリティって特別に何か気をつけることある?」
そう聞かれたとき、「パラメータのバリデーションをしておけば大丈夫」と答えてしまうエンジニアは少なくありません。しかし、XMLを処理するシステムには、バリデーションとは別の落とし穴があります。
それが XXE(XML外部エンティティ注入) です。
XMLパーサーの設定を1か所見落とすだけで、攻撃者はサーバー上の /etc/passwd を読み取り、データベースの接続情報を盗み出すことができます。この記事では、XXEの仕組み・実際の被害リスク・そして今すぐ実施できる防御策を現場目線で解説します。

XXEとは?(XML外部エンティティ注入の概要)
XXE(XML External Entity injection:XML外部エンティティ注入)は、XMLを処理するアプリケーションの脆弱性を突いた攻撃手法です。
XMLには「エンティティ」という仕組みがあります。エンティティとは、XMLドキュメント内で使える変数のようなもので、繰り返し使う文字列などを定義しておくときに役立ちます。問題は、この「外部エンティティ(External Entity)」機能を使うと、外部のファイルやURLの内容をXMLドキュメント内に取り込める点にあります。
脆弱なXMLパーサーがこの機能を有効にしたまま動いている場合、悪意のあるXMLを送り込まれると、攻撃者が指定したファイルの内容がアプリのレスポンスとして返ってきます。
OWASPのTop 10(Webアプリケーションの主要脆弱性ランキング)にも過去に掲載(A4:2017-XML External Entities)された脆弱性であり、現在もJavaやPHPで書かれた多くの業務システムやAPIで発見されています。
XXE攻撃の仕組み(敵を知る)
攻撃者が送信するXMLがどのような構造をしているか、概念として把握しておきましょう。
# 攻撃者が送るXMLペイロードの例(概念) <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <foo>&xxe;</foo>
このXMLがパーサーに処理されると、&xxe; の部分がサーバーの /etc/passwd の内容に展開されます。脆弱なアプリがこの値をレスポンスに含めた場合、攻撃者はサーバーのユーザー一覧を入手できます。
攻撃が成功した場合の主な被害は以下のとおりです。
・ローカルファイルの読み取り: /etc/passwd、Webアプリの設定ファイル(config.php 等)、SSHの秘密鍵など機密情報の漏洩
・内部ネットワーク探索(SSRF): 外部エンティティに内部IPを指定して、ファイアウォール内の別システムへの踏み台として悪用
・DoS(サービス妨害): エンティティを再帰的に展開する「Billion Laughs攻撃」でメモリを枯渇させる
・リモートコード実行: 特定の環境(PHPのexpect://スキームが有効など)ではコマンド実行につながる場合がある
XXEは「ファイルが見られるだけ」と軽視されがちですが、読み取られた設定ファイルにはデータベースの接続情報やクラウドプロバイダのAPIキーが含まれているケースも多く、そこから被害が拡大します。
XXEが発生しやすい環境
すべてのXML処理がリスクというわけではなく、特定の条件が重なったときに脆弱性が表面化します。
・XMLパーサーがデフォルト設定のまま: 多くのパーサーはデフォルトで外部エンティティを有効にしている
・古いライブラリを使用: JavaのJAXP、PHPのlibxml2など、古いバージョンのまま使い続けているシステムに多い
・ユーザー入力のXMLをそのまま処理: APIエンドポイントやファイルアップロード機能でXMLを受け取る場合
・SOAPやXMLベースのAPI: RESTfulなJSON APIよりもXML処理が多いシステムで残りやすい
・Officeドキュメントの処理機能: .docxや.xlsxはZIPアーカイブ内にXMLが含まれており、これを処理するアプリも対象になりうる
自社開発のシステムだけでなく、購入したパッケージシステムや外部サービスとのXMLデータ連携にも潜在している可能性があります。
具体的な防御手順
1. 外部エンティティ処理を無効化する
最も確実な対策は、XMLパーサーの設定で外部エンティティ処理を明示的に無効にすることです。言語・ライブラリごとに設定方法が異なります。
Java(DocumentBuilderFactory の場合)
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); # 外部エンティティとDTD処理を無効化する dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); dbf.setExpandEntityReferences(false);
PHP(libxml2 の場合)
# PHP 7.x 以前は明示的に無効化が必要 libxml_disable_entity_loader(true); # PHP 8.0 以降はデフォルトで無効化済み # simplexml_load_string 等を使う場合は動作確認を忘れずに
Python(lxml の場合)
from lxml import etree # 安全なパーサーを明示的に作成する parser = etree.XMLParser( resolve_entities=False, no_network=True ) tree = etree.fromstring(xml_data, parser)
設定方法の詳細は、OWASPが公開する「XML Security Cheat Sheet」を参照してください。使用しているバージョンや環境によって有効な設定が異なる場合があります。
2. XMLパーサーとライブラリを最新版に保つ
古いバージョンのパーサーには、設定で無効化しても回避できる手法が存在する場合があります。定期的なバージョンアップが防御の基本です。
・Java: JAXP / Apache Xerces のバージョンを最新に維持する
・PHP: PHP本体とlibxml2のバージョンを定期確認する(PHP 8.0以降を推奨)
・Python: lxml、xmltodictなどのライブラリを定期的にアップデートする
・Node.js: xml2js、fast-xml-parser等のNPMパッケージのセキュリティアドバイザリを確認する
Linuxサーバーでパッケージを運用している場合、dnf/aptによる自動アップデートの設定も有効です。詳しい設定方法は、姉妹サイトLinuxMaster.JPでも解説しています。
3. WAFでXXEペイロードを検知する
パーサー側の対応と並行して、WAF(Webアプリケーションファイアウォール:通信を監視してWeb攻撃を遮断するシステム)でXXEペイロードの特徴的なパターンを検知・ブロックする設定を追加することも有効です。
代表的な検知パターンは以下のとおりです。
・リクエストボディに SYSTEM キーワードを含むXMLリクエスト
・DOCTYPE 宣言を含むXMLデータ
・file://、http://、expect:// などのURIスキームを含む外部エンティティ参照
ただしWAFはあくまで補助的な防御策です。パーサー設定の無効化を省いてWAFだけで守ろうとするのは、攻撃者に回避の余地を与えることになります。
4. JSONへの移行を検討する
新規開発や大規模改修のタイミングでは、XMLからJSONへの移行を検討してください。JSONにはエンティティの概念がないため、XXEリスクを根本から排除できます。
既存のXMLベースAPIとの互換性を維持する必要がある場合でも、内部処理でJSONに変換してから処理するアーキテクチャを採用することで、リスクを低減できます。
中小企業でも今日からできること
「XMLを使っているかどうかよくわからない」という中小企業の情シス担当の方向けに、まず確認すべきポイントをまとめます。
・社内システムのXML利用確認: ERPパッケージ・会計ソフト・EDI連携システムはXMLを使っているケースが多い。ベンダーの仕様書で確認する
・アクセスログの確認: Webサーバーのアクセスログに「DOCTYPE」「SYSTEM」を含むリクエストがあれば探索の痕跡の可能性がある
・ベンダーへの問い合わせ: パッケージシステムのベンダーに「XXE対応済みか、パーサー設定はどうなっているか」を質問する。回答できるかどうか自体も判断材料になる
・脆弱性診断の定期実施: OWASP ZAPや商用のDASTツールでXXEを含む診断を年1回以上実施する
・ペネトレーションテストの委託: 社内にリソースがない場合は、外部のセキュリティ会社に診断を依頼することも現実的な選択肢
すぐにできることとして、まずベンダーへの問い合わせとアクセスログの定期確認から始めてみてください。コストゼロで実施できます。
よくある誤解と注意点
【誤解1】うちはJSONを使っているから関係ない
JSONメインのシステムでも、バックエンドのライブラリや処理フローの内部でXMLが使われている場合があります。Javaの一部フレームワークやMavenプラグインなどは内部でXML処理を行うものがあります。「表面上はJSON API」でも、依存ライブラリのXXE対策は別途必要です。
【誤解2】HTTPS化してあれば安全
HTTPS(TLS暗号化)は通信の盗聴を防ぐためのものであり、XXEのようなアプリケーション層の脆弱性とは別の話です。通信が暗号化されていても、悪意のあるXMLペイロードはそのまま届きます。
【誤解3】設定ファイルを1か所直せば全体が安全
同じシステム内に複数のXML処理箇所がある場合、1か所だけ修正しても他の箇所から攻撃される可能性が残ります。コードベース全体でXML処理を洗い出し、すべての箇所に対策を施すことが必要です。
【注意】ブラインドXXEは見つけにくい
「ブラインドXXE」と呼ばれる手法では、レスポンスに直接ファイル内容が含まれない場合でも、DNSルックアップや外部への帯域外通信(OOB)を使って情報を盗み出します。通常の動作確認だけでは検知が難しいため、専用の診断ツールによる確認が不可欠です。
本記事のまとめ
| 項目 | 内容 |
|---|---|
| XXEとは | XMLの外部エンティティ機能を悪用してサーバー上のファイルを読み取る攻撃 |
| 主な被害 | 設定ファイル・秘密鍵の漏洩、内部ネットワーク探索(SSRF)、DoS |
| 発生しやすい環境 | デフォルト設定のXMLパーサー、古いライブラリ、SOAPやXMLベースのAPIを持つシステム |
| 最優先の対策 | XMLパーサーで外部エンティティ処理を明示的に無効化する |
| 補助的な対策 | ライブラリの最新化、WAFによる検知、JSONへの移行検討 |
| 中小企業でできること | ベンダーへの確認、アクセスログ監視、年1回の脆弱性診断 |
XXEは「設定1つで防げる脆弱性」の代表格です。しかし、その設定を知らなければ防げません。現在運用しているシステムのXML処理を一度洗い出し、パーサーの設定を確認するところから始めてみてください。
XXE以外にも、見落としがちな脆弱性が気になりますか?
脆弱性対策は個別の知識だけでなく、体系的な視点があってこそ機能します。
正しいセキュリティ知識を体系的に身につけたい方へ、メルマガで実践的なセキュリティ対策ノウハウをお届けしています。


コメント