CyberFix Note
セキュアコーディング

XXEとは何か。XML外部実体参照で起きる情報漏えいの仕組みとDTD無効化による根本対策

対象の目安: XMLを扱うWebアプリ開発者 / 実務

ソウ攻撃・脆弱性リサーチ担当
・ 約15分で読めます
XXEとは何か。XML外部実体参照で起きる情報漏えいの仕組みとDTD無効化による根本対策

XMLを受け取って処理するアプリケーションでは、パーサやそのバージョンによっては、既定設定のまま外部実体を解決することがあります。すると、文書に紛れ込んだ「外部実体」への参照をパーサが素直に解決し、サーバー上のファイルの中身が読み出されたり、内部ネットワークへリクエストが飛んだりすることがあります。これがXXE(XML外部実体参照、XML External Entity、CWE-611)です。攻撃者が送り込むのは正しい構文のXMLであり、アプリのコードには一見おかしなところがないのに、パーサの機能そのものが悪用される点に難しさがあります。

この記事は、XMLを扱うコードを書くWebアプリ開発者に向けて、XXEがなぜ成立するのかという機構から、想定される影響、OWASP Top 10での位置づけの移り変わり、そしてDTDと外部実体の解決を無効化する根本対策までを順に整理します。攻撃の再現手順や動作するペイロードは載せず、仕組みの理解と防御に絞って解説します。検証は自分が管理する環境、または明示的に許可を得た対象に対してのみ行ってください。

XXEが成立する機構

XMLには、文書の先頭で文書型定義(DTD、Document Type Definition)を宣言し、その中で「実体(entity)」という短い名前に長い値を割り当てておき、本文からその名前で参照する仕組みがあります。実体には文書内で値を定義する内部実体のほかに、値を外部の場所から取り込む「外部実体(external entity)」があります。外部実体は<!DOCTYPE>宣言の中で、参照先をURIとして指定します。パーサはこのURIを解決し、取得した内容を実体の値として本文に埋め込みます。

XXEは、この外部実体の解決を有効にしたパーサが、攻撃者の送り込んだXMLに含まれる外部実体をそのまま解決してしまうことで起こります。参照先のURIにfile://で始まるローカルファイルのパスを書けば、パーサはそのファイルを読み込んで実体の値として展開します。展開された値が応答に反映される作りだと、ファイルの中身がそのまま画面や応答に現れてしまいます。

問題の核心は、アプリのコードではなくパーサの機能にあります。MITREのCWE-611は、XXEを「XMLを処理する製品が、想定した管理範囲の外にある文書へ解決されうるURIを持つXML実体を含む文書を処理し、その結果として誤った文書を自身の出力へ埋め込んでしまう」弱点として定義しています。アプリは正規のXML解析を行っているだけで、ただ参照先を攻撃者がすり替えられる、という一点が問題の本質です。

MITRE CWE-611は、外部実体を含むXMLをパーサが処理する際に参照先を検査しないと、攻撃者がローカルまたはリモートの任意のファイルを取り込ませて表示させうると説明しています。名称は Improper Restriction of XML External Entity Reference です。

何が起きるのか

外部実体が解決されると、パーサが到達できる範囲がそのまま攻撃面になります。OWASPとMITREが挙げる代表的な影響を整理します。

影響起こりうること
ローカルファイルの開示外部実体の参照先にサーバー上のファイルを指させ、設定ファイルや認証情報を読み出される
SSRF(内部リソースへの要求)参照先に内部URLを指させ、パーサを踏み台に内部のサービスやクラウドメタデータへ到達される
サービス妨害(DoS)実体を多重に入れ子で参照させ、展開量を爆発的に増やしてメモリやCPUを枯渇させる
情報の流出読み出した内容を外部へ送出させる細工により、直接応答に出ない情報まで持ち出される
限定条件下でのリモートコード実行脆弱なXML処理系やPHPのexpect等の拡張機能、特定の実行環境に依存する場合に限り、コード実行に至ることがある(一般的な影響ではなく処理系・拡張・環境に依存します)

サービス妨害の代表例が、Billion Laughs攻撃(実体展開爆発)です。ある実体を定義し、それを何段も入れ子で参照させると、実体の展開が指数的に膨らみ、わずかなXMLでも展開後は膨大なサイズになってメモリやCPUを消費し尽くします。ファイルの読み出しとは別系統ですが、DTDの実体解決を悪用するという根は同じです。

OWASP Communityの XML External Entity (XXE) Processing は、脆弱なXMLプロセッサが外部実体を解決すると、機微なデータの開示、サーバー側リクエストフォージェリ、サービス妨害などの被害につながりうると整理しています。

このうちSSRFは、外部実体の参照先を内部向けのURLにすることで、パーサに内部宛てのリクエストを送らせる経路です。パーサが置かれたネットワーク位置から内部資産へ到達されるという構図はSSRF単体の脆弱性と共通します。ただし、出口通信の制御(宛先の許可リストなど)は補助にはなりますが、XXEの根本対策はXMLパーサで外部実体の解決を無効化することです。

あわせて読みたい

SSRFとは何か。サーバーを踏み台にする脆弱性の仕組みと許可リスト方式の防御を解説

注意

XXEの検証は、必ず自分が管理する環境、または明示的に許可を得た対象に対してのみ行ってください。他者のサーバーに内部宛てのリクエストを送らせたりファイルを読み出させたりする行為は、不正アクセス禁止法をはじめとする法令に抵触するおそれがあります。本記事は自社サービスの防御を確認する目的で読み進めてください。

OWASP Top 10での位置づけの移り変わり

XXEはOWASP Top 10の版によって置かれる場所が変わってきたため、対応する社内基準を参照するときは版の違いに注意が必要です。

2017年版では、XXEはA4:2017 XML External Entitiesとして独立した項目でした。当時のページは、古いXMLプロセッサの多くが既定で外部実体の指定を許しており、処理時にそのURIが解決されて評価されると説明し、対策としてすべてのXMLパーサでXML外部実体とDTDの処理を無効化することを求めていました。

2021年版では、XXEは独立項目ではなくなり、A05:2021 Security Misconfigurationに統合されました。A05のページには、対象となる主要なCWEとしてCWE-611が明記されています。XXEはXMLパーサが安全でない設定のまま使われることで成立する、という理解に基づく整理で、設定不備の一種として束ねられた形です。2025年版でもこの整理は引き継がれ、A02:2025 Security MisconfigurationのNotable CWEとしてCWE-611が引き続き含まれています。位置づけは変わりましたが、攻撃の機構も対策も変わりません。Top 10全体の版ごとの構成と、各リスクの関係を俯瞰しておくと、XXEがどの分類に入っても対応の軸がぶれません。

OWASP Top 10のA05:2021 Security Misconfigurationは、対象となる代表的なCWEにCWE-611 Improper Restriction of XML External Entity Referenceを含めています。2017年版でA4として独立していたXXEが、設定不備のカテゴリに統合されたことを反映しています。

OWASP Top 10のA02:2025 Security Misconfigurationも、Notable CWEとしてCWE-611を引き続き挙げています。設定不備のカテゴリにXXEが含まれる整理が2025年版でも維持されています。

あわせて読みたい

OWASP Top 10とは。開発者が押さえるべきWebの代表的リスクと対策を一気に理解する

根本対策はDTDと外部実体の解決を無効にすること

XXEの根本対策は、XMLパーサにDTDと外部実体を解決させないことに尽きます。OWASPのXML External Entity Prevention Cheat Sheetは、XXEを防ぐ最も安全な方法は常にDTD、特にその中で定義される外部実体を完全に無効化することだと述べています。DTDそのものを禁止すれば、外部実体の参照も実体の多重展開も入口の時点で成立しなくなり、ファイル読み出しとSSRFに加えてBillion Laughs型のDoSまで同時に塞げます。

  1. 1

    DTD(DOCTYPE宣言)そのものを禁止する

    パーサにDOCTYPE宣言を許可しない設定があるなら、それを有効にします。DTDを禁止すれば外部実体を定義する場所自体がなくなり、XXEもBillion Laughs型のDoSも同時に防げます。Cheat Sheetはこれを第一の対策として挙げています。

  2. 2

    DTDを完全に禁止できない場合は外部実体を無効にする

    仕様上どうしてもDTDを受け付ける必要がある場合は、外部一般実体と外部パラメータ実体の解決を無効にし、外部DTDの読み込みも止めます。参照先を取りに行く機能を落とすことで、外部への到達を断ちます。

  3. 3

    安全処理モードとXIncludeや外部スキーマの無効化を重ねる

    パーサが備える安全処理(secure processing)モードを有効にし、XIncludeや外部スキーマ、外部スタイルシートの読み込みなど、外部リソースを取り込む周辺機能も併せて無効化します。DTDを塞いでも別経路で外部を参照させる余地を残さないためです。

  4. 4

    実行環境の権限と出口通信を絞る

    パーサを動かすプロセスに不要なファイルへの読み取り権限を与えず、サーバーからの外部通信も必要な宛先だけに限定します。万一設定が漏れても、到達できる範囲を狭める保険になります。

外部実体を無効化する具体的な設定は、言語やパーサごとに設定名が異なります。JavaのDOM系パーサ(DocumentBuilderFactory)では、http://apache.org/xml/features/disallow-doctype-declという機能をtrueに設定してDOCTYPE宣言そのものを禁止するのが最も確実だとCheat Sheetは示しています。これを有効にできない事情がある場合に限り、http://xml.org/sax/features/external-general-entitieshttp://xml.org/sax/features/external-parameter-entitiesをいずれもfalseにして外部一般実体と外部パラメータ実体を無効化し、あわせてhttp://apache.org/xml/features/nonvalidating/load-external-dtdfalseにして外部DTDの読み込みも止めます。JDK環境では、jdk.xml.dtd.supportプロパティをdenyまたはignoreに設定してDTDの処理自体を抑止する方法もあります。StAX系のXMLInputFactoryではXMLInputFactory.SUPPORT_DTDfalseにしてDTDを無効にします。.NETやPHP、Pythonなど他の言語でも、Cheat Sheetがパーサごとの設定を列挙しているので、使用するライブラリの該当箇所を確認して同じ方針を適用します。

OWASPのXML External Entity Prevention Cheat Sheetは、XXEを防ぐ最も安全な方法はDTDを完全に無効化することだとし、JavaのDocumentBuilderFactoryでは disallow-doctype-decl 機能を有効にすることを推奨しています。完全な無効化ができない場合は、外部一般実体と外部パラメータ実体を無効にし、XIncludeが有効でないことも確認するよう求めています。

XMLより単純な形式を選ぶ判断

そもそもXXEは、外部実体という強力な機能を持つXMLを解釈することで生じます。データの受け渡しにその機能が要らないなら、XMLより単純なデータ形式を使うのが最も確実な回避策になります。OWASPのCheat Sheetも、可能ならJSONのようなより単純で堅牢なデータ形式を使い、機微なデータの直列化を避けることを勧めています。JSONにはDTDや外部実体に相当する仕組みがなく、XXEの発生余地そのものがありません。

新規に設計する機能でXMLを選ぶ理由が「なんとなく慣れているから」であれば、JSONで足りないかを先に検討する価値があります。ただし、SOAPやSAML、各種業務標準のように、仕様としてXMLが前提の場面は残ります。その場合はXMLを使いつつ、前章のパーサ設定で外部実体を確実に無効化するのが現実的な答えになります。

なお、入力検証や許可リストは、XXEに対しては補助にとどまります。XXEを引き起こすのは正しい構文のXMLであり、危険な文字列を弾く発想では取りこぼしが避けられないためです。PortSwiggerの解説も、XXEを確実に防ぐには、パーサの機能のうちアプリケーションが必要としないものを無効化することが基本だとしています。入力検証の役割と限界を、XSSやインジェクションを含めた共通の土台として押さえておくと、XXEでなぜ検証が主対策にならないかも整理できます。

あわせて読みたい

入力バリデーションと出力エスケープの原則。入口で検証し、出口で文脈別にエスケープする

XXEはファイルの参照先をすり替えられる点で、パスの解決をユーザー入力に委ねてしまうパストラバーサルと問題の質が近い面があります。どちらも「参照先や解決先を攻撃者が動かせる」ことが根にあるため、あわせて理解すると防御の勘所がつかめます。

あわせて読みたい

パストラバーサルとは何か。基準ディレクトリの外へ解決されるパスの脆弱性と根本対策を解説

まとめ

XXEは、XMLパーサが外部実体の参照を解決してしまうことで、サーバー上のファイル読み出しや内部リソースへのリクエスト、実体展開によるサービス妨害を招く脆弱性です。攻撃者が送るのは正しい構文のXMLで、悪用されるのはパーサの機能そのものだからこそ、対策はコードの小手先ではなくパーサの設定に行き着きます。DTDと外部実体の解決を無効にし、可能ならXMLより単純な形式を選ぶ。OWASP Top 10での位置づけは2017年版のA4から2021年版のA05へ移り、2025年版でもA02 Security Misconfigurationに引き続き含まれますが、この根本対策は版をまたいで変わりません。

XXE対策チェックリスト

  • XMLを解釈する箇所を洗い出し、外部から入力を受け取るパーサを特定しているか
  • パーサでDTD(DOCTYPE宣言)そのものを禁止できているか
  • DTDを禁止できない場合、外部一般実体と外部パラメータ実体を無効化し、外部DTDの読み込みを止めているか
  • XIncludeや外部スキーマなど、外部リソースを取り込む周辺機能も無効化しているか
  • 使用するライブラリ固有の設定を、OWASPのCheat Sheetで確認して適用しているか
  • 新規機能でXMLが必要か、JSONなど単純な形式で代替できないか検討したか
  • 入力検証を根本対策ではなく補助として位置づけているか

出典・参考

この記事をシェア

関連する記事

セキュアコーディング

パストラバーサルとは何か。基準ディレクトリの外へ解決されるパスの脆弱性と根本対策を解説

ユーザー入力がファイルパスに連結され「../」で基準ディレクトリの外へ到達されるパストラバーサル(CWE-22)を、なぜ成立するのかという機構から、任意ファイル読取などの想定影響、正規化と許可リストによる根本対策までWebアプリ開発者向けに体系的に整理します。

セキュアコーディング

入力バリデーションと出力エスケープの原則。入口で検証し、出口で文脈別にエスケープする

セキュアコーディングの土台である入力バリデーションと出力エスケープを、それぞれの役割の違いから整理します。入口の検証は防御の一段目、出口の文脈別エスケープがXSSやインジェクションの根本対策である理由を、原理と実務の判断基準まで掘り下げます。