はじめに
XML は長年、多くのシステムで設定ファイル・通信フォーマット・ドキュメント構造化などに利用され続けてきました。しかし XML Parsing(XML 解析)は単なるデータ処理に留まらず、設定次第で重大なセキュリティリスク(XXE)を生む という二面性を持っています。
この記事では次の内容をまとめて解説します:
- XML Parsing の基本と内部処理
- 代表的な XML パーサー(DOM / SAX / StAX / XPath)の特徴
- どこで XXE(XML External Entity)脆弱性が発生するのか
- 安全に XML を扱うための設定例
1. XML Parsing とは?
XML Parsing(XML 解析)とは:
XML ファイルを読み取り、プログラムが扱える内部構造に変換するプロセス
のことです。
通常、以下のような処理が自動的に行われます:
- XML タグをノード(要素・属性・テキスト)に分解
- 必要に応じて DTD や XML Schema に従って検証(validation)
- DOM ツリーやストリーミング構造に変換してプログラムから操作可能にする
XML パーサーは見た目より複雑で、構成によっては内部ファイルへアクセス可能な“危険な機能”も含む ため注意が必要です。
2. XXE(XML External Entity)が発生する理由
XXE とは、XML 内で定義された外部エンティティ(SYSTEM エンティティ)が悪用される攻撃です。
例:
<!DOCTYPE root [
<!ENTITY secret SYSTEM "file:///etc/passwd">
]>
<root>&secret;</root>
外部エンティティが有効な状態だと、パーサーは
&secret; → /etc/passwd の内容
へ置き換えてしまいます。
つまり:
- パーサーが 外部エンティティ読み込みを許可 していて
- XML を 攻撃者が送信できる仕組みがある
この 2 条件が揃うと XXE は発生します。
3. 代表的な XML パーサーと特徴(+XXE 視点)
ここでは、DOM / SAX / StAX / XPath の 4 種類を比較します。
DOM Parser(Document Object Model)
特徴
- XML 文書全体を メモリ上に完全再構築(ツリー構造)
- ランダムアクセスが自由で扱いやすい
- 中〜小規模 XML に適している
デメリット
- メモリ消費が大きい
- 巨大 XML には不向き
XXE リスク
高い
→ DTD を解釈しやすく、外部エンティティが読み込まれやすい。
安全化設定(Java DOMParser)
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
SAX Parser(Simple API for XML)
特徴
- イベントドリブン方式(逐次的に処理)
- メモリ効率が非常に良い
- 大規模 XML に強い
デメリット
- ランダムアクセス不可
- 状態管理がやや複雑
XXE リスク
中程度
→ DTD を読み込む設定であれば XXE が入りやすい。
安全化設定
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
StAX Parser(Streaming API for XML)
特徴
- SAX と同じストリーミング方式だが、処理タイミングをアプリ側が制御しやすい
- 柔軟性と効率のバランスが良い
- 多くのフレームワークで利用されている
XXE リスク
低〜中
→ StAX は外部エンティティ無効化が容易で、より安全。
安全化設定
XMLInputFactory factory = XMLInputFactory.newFactory();
factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
XPath Parser
特徴
- XML を SQL の WHERE のように問い合わせる技術
- DOM または SAX を基盤として動く
- XSLT や構造検索に利用される
XXE リスク
パーサーの設定次第
XPath 自体が脆弱になるのではなく、
XPath 処理の前段に使われる DOM/SAX の設定が甘いと脆弱になる。
4. パーサー比較表(実務で迷わないためのまとめ)
| パーサー | メモリ効率 | 柔軟性 | XXE リスク | 主な用途 |
|---|---|---|---|---|
| DOM | 低い | 高い | 高い | XML 全体を自由に操作したい場合 |
| SAX | 非常に高い | 低い | 中 | 巨大 XML / ストリーム処理 |
| StAX | 高い | 中 | 低〜中 | SAX より柔軟なストリーム処理 |
| XPath | DOM 次第 | 高い | DOM に依存 | クエリ検索・XSLT |
5. XML を安全に扱うための要点(XXE 防止)
XXE を防止するための鉄則は以下のとおり:
-
DOCTYPE を禁止する
-
外部エンティティ(SYSTEM, PUBLIC)を無効化
-
DTD の読み込みを禁止
-
ライブラリ・フレームワークの既定値を信用しない
ほとんどの XXE 脆弱性は「パーサー設定がデフォルトのまま」から生まれます。
まとめ — XML Parsing の本質は「設定」にある
XML Parsing は便利ですが、設定を誤ると簡単に内部ファイル漏洩・SSRF・ネットワークスキャンまでつながる脆弱性を生みます。
逆に言えば:
正しいパーサー設定を行えば、XXE は完全に防止できる。
DOM / SAX / StAX のどれを選んでも安全に扱えます。
重要なのは「何を使うか」ではなく「どう設定するか」。