XXE攻撃対策のXMLパーサー設定方法|XML外部エンティティ攻撃の防止
2019年、ある大手企業のWebシステムがXXE(XML External Entity)攻撃を受け、顧客の個人情報約10万件が外部に漏洩する事件が発生しました。この企業のシステムは、XMLファイルを受け付ける機能を持っていましたが、XMLパーサーの設定が適切でなかったため、攻撃者に内部ファイルを読み取られてしまったの...
2019年、ある大手企業のWebシステムがXXE(XML External Entity)攻撃を受け、顧客の個人情報約10万件が外部に漏洩する事件が発生しました。この企業のシステムは、XMLファイルを受け付ける機能を持っていましたが、XMLパーサーの設定が適切でなかったため、攻撃者に内部ファイルを読み取られてしまったのです。
XXE攻撃は、XMLを扱うあらゆるWebシステムが標的になりえる脆弱性です。「うちは大企業じゃないから大丈夫」と考えるのは危険です。中小企業のシステムでも、XMLを使った機能があれば攻撃対象になります。
この記事では、XXE攻撃の仕組みから、Java・PHP・Python・.NETといった主要言語ごとの具体的な対策設定方法まで、非エンジニアの方にもわかりやすく解説します。自社システムの安全性を確認し、適切な対策を実装するための参考にしてください。
XXE(XML外部エンティティ)攻撃とは何か
XXE攻撃とは、XMLの「外部エンティティ」という機能を悪用した攻撃手法です。XMLファイルを処理する際、通常のデータだけでなく、外部ファイルの内容を読み込ませることで、本来アクセスできないはずの情報を盗み出します。
XXE攻撃の仕組み:エンティティ展開の悪用
XMLには「エンティティ」という、データの一部を別の値で置き換える機能があります。正常な使い方では、繰り返し使う文字列を定義しておき、コードを簡潔にするために使われます。
しかし、XMLパーサーの設定が適切でない場合、攻撃者は以下のような悪意あるXMLファイルを送信することで、サーバー内の機密ファイルを読み取ることができてしまいます。
- 外部エンティティの定義:攻撃者がXMLファイル内に、サーバー上のファイルパス(例:/etc/passwd)を指定した外部エンティティを記述
- エンティティの展開:XMLパーサーがそのファイルの内容を読み込み、レスポンスとして返してしまう
- 情報の窃取:攻撃者が本来アクセスできないはずの設定ファイルやデータベース接続情報などを入手
この仕組みは、XMLパーサーがデフォルトで外部エンティティの処理を有効にしている場合に成立します。つまり、開発時に意図的に無効化しない限り、脆弱性が残り続けるのです。
実際の攻撃例:ファイル読取とSSRF
XXE攻撃には、大きく分けて2つの攻撃パターンがあります。
1. ローカルファイルの読取攻撃
攻撃者は、サーバー上の機密ファイル(設定ファイル、パスワードファイル、アプリケーションのソースコードなど)を読み取ります。特に狙われやすいのは以下のようなファイルです。
- Linuxサーバーの/etc/passwdファイル(ユーザー情報)
- データベース接続情報が記載された設定ファイル
- AWSやAzureなどのクラウドサービスの認証情報
- 他のシステムとの連携に使用するAPIキー
2. SSRF(サーバーサイドリクエストフォージェリ)攻撃
XXE攻撃を起点として、外部エンティティに内部ネットワークのURLを指定することで、SSRF攻撃に発展するケースもあります。これにより、以下のような被害が発生します。
- ファイアウォールで保護された内部システムへのアクセス
- クラウドメタデータAPIからの認証情報窃取
- 社内の他のサーバーへの不正アクセス
XXE攻撃が成功する3つの条件
XXE攻撃が成功してしまうシステムには、共通する特徴があります。
- XMLパーサーの外部エンティティ処理が有効:デフォルト設定のまま使用しているケースがほとんど
- ユーザーからXMLファイルを受け付ける機能がある:アップロード機能、API連携、データインポート機能など
- エラーメッセージが詳細に表示される:攻撃者がファイルの内容を確認しやすい環境
独立行政法人情報処理推進機構(IPA)の調査によると、XXE脆弱性は開発段階での設定ミスや知識不足によって発生するケースが大半を占めています。
中小企業が狙われる理由:レガシーシステムの残存
中小企業のWebシステムがXXE攻撃の標的になりやすい理由は、主に以下の3点です。
古いフレームワークやライブラリの使用
セキュリティアップデートが行われていない古いバージョンのXMLパーサーを使い続けているケースがあります。特に、10年以上前に構築されたシステムでは、XXE対策が実装されていない可能性が高いとされています。
開発ベンダーのセキュリティ知識不足
システム開発を外部委託している場合、開発ベンダーがXXE脆弱性の存在を認識していないケースも少なくありません。納品時のセキュリティチェックが不十分だと、脆弱性がそのまま残ってしまいます。
セキュリティ診断の未実施
大企業に比べて、中小企業では定期的な脆弱性診断が実施されていないことが多いです。OWASP Top 10(世界的に認知されているWebアプリケーションの脆弱性トップ10)にもXXE攻撃は含まれていますが、実際に自社システムを診断していなければ発見できません。
XXE攻撃で起こりうる3つの被害
XXE攻撃が成功した場合、企業には深刻な被害が発生します。実際に報告されている事例をもとに、具体的な影響を見ていきましょう。
実際に発生した情報漏洩事例:顧客情報と設定ファイル流出
2017年、海外の大手不動産情報サイトでXXE脆弱性が発見され、顧客の個人情報や物件情報が外部に流出する可能性があることが判明しました。このサイトでは、ユーザーがXML形式でデータをアップロードできる機能があり、そこが攻撃の入口となりました。
日本国内でも、EC サイトや会員制サービスで同様の事例が報告されています。特に以下のような情報が狙われます。
- 顧客の個人情報:氏名、住所、電話番号、メールアドレス
- データベース接続情報:ユーザー名、パスワード、接続先IP
- APIキーや認証トークン:他のシステムとの連携に使用する秘密鍵
- ソースコード:アプリケーションのロジックや他の脆弱性が露呈
IPAの報告によると、このような情報漏洩が発生した場合、企業は平均して数千万円規模の損害(賠償金、システム改修費、信用失墜による売上減少など)を被るとされています。
業務システムへの影響:サービス停止と改ざん
XXE攻撃は情報漏洩だけでなく、業務システムそのものの停止や改ざんにもつながります。
サービス停止(DoS攻撃)
攻撃者が巨大なXMLファイルや、無限に展開される外部エンティティを送信することで、サーバーのメモリやCPUを消費させ、サービスを停止に追い込むケースがあります。これは「Billion Laughs攻撃」と呼ばれる手法で、短時間でシステムダウンを引き起こします。
データ改ざん
XXE攻撃と他の脆弱性を組み合わせることで、データベース内の情報を書き換えられる可能性もあります。例えば、受注情報や在庫データが改ざんされると、業務に直接的な混乱が生じます。
XXE脆弱性が放置される理由:開発時の見落とし
XXE脆弱性は、なぜ多くのシステムで放置されてしまうのでしょうか。主な理由は以下の3つです。
- 開発者の認識不足:XMLパーサーのデフォルト設定が危険であることを知らないまま実装してしまう
- テスト不足:機能テストは実施しても、セキュリティテストまで行われないケースが多い
- フレームワーク依存:使用しているフレームワークが内部でXMLを処理している場合、開発者が意識せずに脆弱性が残る
特に、外部のライブラリやフレームワークを使用している場合、その内部でどのようにXMLが処理されているかを把握していないと、気づかないうちに脆弱性を抱え込んでしまいます。
言語別XMLパーサーの安全な設定方法
XXE攻撃を防ぐには、XMLパーサーの設定で外部エンティティの処理を無効化することが最も効果的です。ここでは、主要な4つのプログラミング言語における具体的な設定方法を解説します。
Java環境での対策設定:外部エンティティ無効化
Javaでは、DocumentBuilderFactoryやSAXParserFactoryを使用してXMLを処理するケースが多いですが、デフォルト設定では外部エンティティが有効になっています。
対策方法
DocumentBuilderFactoryを使用する場合、以下の3つの設定を追加することで、XXE攻撃を防止できます。
- 外部DTDの無効化:setFeatureメソッドで「http://apache.org/xml/features/disallow-doctype-decl」をtrueに設定
- 外部エンティティの無効化:「http://xml.org/sax/features/external-general-entities」をfalseに設定
- 外部パラメータエンティティの無効化:「http://xml.org/sax/features/external-parameter-entities」をfalseに設定
これらの設定により、攻撃者が外部ファイルを読み込もうとしても、パーサーが処理を拒否するようになります。Oracle公式ドキュメントでも、この設定方法が推奨されています。
PHP環境での対策設定:libxml_disable_entity_loader設定
PHPでは、SimpleXMLやDOMDocumentを使ってXMLを処理しますが、こちらもデフォルトでは外部エンティティが有効です。
対策方法
PHPでは、libxml_disable_entity_loader関数を使用することで、外部エンティティの読み込みを無効化できます。ただし、PHP 8.0以降ではこの関数は非推奨となっており、デフォルトで外部エンティティが無効化されています。
PHP 7.x以前のバージョンを使用している場合は、以下の設定が必要です。
- libxml_disable_entity_loaderをtrueに設定:XML処理の前に必ずこの関数を呼び出す
- LIBXML_NOENTオプションを使用:SimpleXMLやDOMDocumentの読み込み時にこのオプションを指定
PHP公式マニュアルでも、これらの設定が推奨されており、特に古いバージョンのPHPを使用している場合は必須の対策です。
Python環境での対策設定:defusedxml使用
Pythonの標準ライブラリに含まれるxml.etree.ElementTreeやxml.domは、XXE攻撃に対して脆弱です。Python公式ドキュメントでも、この問題が明記されています。
対策方法
Pythonでは、defusedxmlという専用のライブラリを使用することが最も安全です。このライブラリは、標準のXMLパーサーをラップし、XXE攻撃を自動的に防止します。
- defusedxmlのインストール:pipコマンドでdefusedxmlをインストール
- 標準ライブラリの置き換え:xml.etree.ElementTreeの代わりにdefusedxml.ElementTreeを使用
- 自動的な保護:defusedxmlを使用するだけで、外部エンティティの処理が無効化される
OWASP(Open Web Application Security Project)の公式ガイドでも、Pythonでのxxe対策としてdefusedxmlの使用が推奨されています。
.NET環境での対策設定:DtdProcessing設定
.NETフレームワークでは、XmlReaderやXmlDocumentを使用してXMLを処理しますが、.NET Framework 4.5.2以降ではデフォルトで外部エンティティが無効化されています。
対策方法
ただし、古いバージョンの.NETや、互換性のために設定を変更している場合は、以下の設定が必要です。
- DtdProcessingをProhibitに設定:XmlReaderSettingsのDtdProcessingプロパティをProhibitに設定
- XmlResolverをnullに設定:外部リソースの解決を完全に無効化
- ProhibitDtdの使用(古いバージョン):.NET 4.0以前ではProhibitDtdプロパティをtrueに設定
Microsoft公式ドキュメントでも、これらの設定方法が詳しく解説されており、特にレガシーシステムを保守している場合は確認が必要です。
XXE対策の実装時の注意点と検証方法
XXE対策を実装する際には、単に設定を変更するだけでなく、いくつかの重要な注意点があります。また、対策が正しく機能しているかを検証することも欠かせません。
設定漏れが起きやすい3つのポイント
XXE対策を実装しても、以下のようなケースで設定漏れが発生しやすいので注意が必要です。
1. ライブラリやフレームワークの内部処理
アプリケーション本体では対策していても、使用しているライブラリやフレームワークが内部でXMLを処理している場合、そこが脆弱性の入口になる可能性があります。特に以下のようなケースで注意が必要です。
- SOAPなどのWeb サービス連携ライブラリ
- PDF生成ライブラリ(XMLベースの設定を使用する場合)
- 設定ファイル読み込みライブラリ(XML形式の設定ファイルを使用する場合)
使用しているライブラリのドキュメントを確認し、XMLパーサーの設定が適切かチェックすることが重要です。
2. 複数のXML処理箇所
1つのアプリケーション内で、複数の箇所でXMLを処理している場合、一部の箇所だけ対策を忘れてしまうケースがあります。開発時には、以下のような処理がないか全体を見直しましょう。
- ファイルアップロード機能
- API連携(SOAP、REST)
- データインポート・エクスポート機能
- 設定ファイルの読み込み
3. バージョンアップ時の設定リセット
フレームワークやライブラリをバージョンアップした際に、設定がデフォルトに戻ってしまうケースがあります。特に、メジャーバージョンアップ時には設定の見直しが必要です。
XXE脆弱性の検証手順:テスト方法と確認項目
XXE対策を実装した後は、実際に脆弱性が解消されているかテストすることが重要です。以下の手順で検証を行いましょう。
テスト環境での検証
- テスト用XMLファイルの作成:外部エンティティを含む悪意あるXMLファイルを準備(本番環境では絶対に実行しない)
- アップロード・送信テスト:作成したXMLファイルをシステムにアップロードまたはAPI経由で送信
- 結果の確認:外部ファイルが読み込まれないこと、エラーが適切に処理されることを確認
確認すべき項目
- 外部エンティティの展開が拒否されるか
- エラーメッセージに機密情報が含まれていないか
- ログにセキュリティイベントが記録されているか
自社で検証が難しい場合は、セキュリティ診断サービスの利用も検討しましょう。多くのセキュリティベンダーが、XXE脆弱性を含む診断サービスを提供しています。
開発委託時の確認事項:契約書と納品物チェック
システム開発を外部のベンダーに委託する場合、契約段階から以下の点を明確にしておくことが重要です。
契約書に含めるべき項目
- セキュリティ要件の明記:OWASP Top 10への対応を契約書に明記
- XXE対策の実装:具体的にXXE対策を実装することを仕様書に含める
- 脆弱性診断の実施:納品前に第三者による脆弱性診断を実施することを義務付け
- 保守契約でのセキュリティパッチ適用:納品後も定期的なセキュリティアップデートを含める
納品物のチェックポイント
納品時には、以下の資料やテスト結果の提出を求めましょう。
- 使用しているライブラリのバージョン一覧
- XXE対策の実装箇所を示すドキュメント
- セキュリティテストの実施報告書
- 脆弱性診断ツールのスキャン結果
特に、XMLを処理する機能がある場合は、その部分のソースコードレビューを実施することをおすすめします。開発ベンダーに対して「XXE対策は実装済みですか」と質問するだけでなく、実際の設定内容を確認することが重要です。
まとめ
この記事では、XXE攻撃の仕組みから言語別の具体的な対策方法まで解説しました。重要なポイントは以下の3つです。
- 外部エンティティの無効化:XMLパーサーの設定で外部エンティティ処理を必ず無効にすること
- 言語ごとの適切な設定:Java、PHP、Python、.NETそれぞれで推奨される設定方法が異なるため、公式ドキュメントを参照
- 定期的な検証:対策実装後も、脆弱性診断やセキュリティテストで効果を確認し続けること
XXE攻撃は、適切な設定を行うことでリスクを大幅に低減できる脆弱性です。自社システムがXMLを扱っている場合は、今すぐ設定を見直しましょう。
技術的な判断が難しい場合や、開発ベンダーとの調整に不安がある場合は、セキュリティの専門家に相談することをおすすめします。IPA(情報処理推進機構)の「安全なウェブサイトの作り方」など、無料で利用できる情報も活用しながら、自社システムの安全性を高めていきましょう。
関連記事
クリックジャッキング対策のX-Frame-Options設定|UIリダイレクト攻撃防止
自社サイトが気づかないうちに悪意のあるサイトに埋め込まれ、利用者が意図せずボタンをクリックしてしまう。このような「クリックジャッキング攻撃」は、透明なiframeを悪用した巧妙な手口で、SNSでの不正投稿や決済の誤操作など深刻な被害を引き起こします。
コマンドインジェクション対策のサニタイズ方法|OSコマンド実行防止術
企業のWebシステムやサーバーを狙うサイバー攻撃の中でも、特に深刻な被害をもたらすのが「コマンドインジェクション攻撃」です。この攻撃が成功すると、攻撃者がサーバー上で任意のOSコマンドを実行できてしまい、機密情報の漏洩やシステム全体の乗っ取りにつながる可能性があります。
CSRF対策のトークン実装方法|クロスサイトリクエストフォージェリ防止
2023年、ある地方自治体のWebサイトで不正な住民情報の変更が発生しました。原因はCSRF(クロスサイトリクエストフォージェリ)攻撃への対策不足でした。「うちのシステムは大丈夫だろうか」と不安に感じている開発担当者の方も多いのではないでしょうか。