XML外部エンティティ(XXE)攻撃:あなたのサーバーの「鍵」が実は開けっ放し!?
こんにちは!今日は、Webアプリ開発やサーバー管理の世界で、実はとても身近なのに意外と見落とされがちな「XXE(XML External Entity)」という攻撃についてお話しします。
セキュリティと聞くと難しく感じるかもしれませんが、まずは「家の防犯」に例えて考えてみましょう。この記事を読み終える頃には、あなたの書いているコードがどれだけ安全か、あるいはどこを直すべきか、きっと自信を持って答えられるようになりますよ!
—
1. 家の鍵を「勝手に作られる」魔法、それがXXEです
Webの世界で「XML」という形式は、システム同士が情報をやり取りするための「手紙の封筒」のようなものです。
XXE攻撃を家に例えると、こんな感じです。
あなたが郵便受け(XMLパーサー)を設置して、届いた手紙(XMLデータ)を読み込ませようとします。ところが、悪意ある攻撃者がその手紙に「ついでに、家の金庫の場所と鍵の形も教えてよ」という細工を仕込んで送ってきたらどうなるでしょう?
もし、あなたの家の郵便受けに「外部からの指示を忠実に実行する」というお人好しな機能がついていたら……その指示に従って、家の中の機密情報を外部に持ち出されてしまう。これがXXE攻撃の仕組みです。
なぜこれが起こるのか?
XMLには「エンティティ」という、長い文章や特定の情報を短縮して呼び出す便利な機能があります。攻撃者はこの機能が悪用できることを知っていて、外部のファイル(例えばサーバー内のパスワードファイル)を読み出すよう、パーサー(手紙を読み解く機械)を「洗脳」するのです。
—
2. 実際に起きていること:攻撃のメカニズム
例えば、あるWebサービスでユーザーがXML形式でプロフィールを送信するとします。攻撃者は以下のようなコードを送信します。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!-- 攻撃者の罠:サーバー内の機密ファイルを読み込む指示 -->
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>
<name>&xxe;</name> <!-- ここで罠が発動! -->
</root>
このコードを処理するサーバーが「外部からの指示を許可」する設定になっていると、サーバーは本来返すべきユーザー名の代わりに、サーバーの心臓部である etc/passwd (ユーザー一覧などが書かれたファイル)の中身を読み込んで、画面に表示してしまいます。これが「情報漏洩」の瞬間です。
さらに恐ろしいのは、この仕組みを使って「SSRF(サーバーサイド・リクエスト・フォージェリ)」という攻撃もできてしまうこと。これは、サーバーを「踏み台」にして、外部からは見えない社内ネットワークの別のサーバーへ、攻撃者の代わりにアクセスさせる手法です。まさに、あなたの家から隣の家の様子を覗き見させるようなものです。
—
3. 一歩ずつ対策を学んでいきましょう!
「そんな怖いこと、どうやって防ぐの?」と思うかもしれませんが、対策は意外とシンプルです。「外部からの怪しい指示を聞かないように設定する」、これに尽きます。
対策1:XMLパーサーの設定を厳格にする(最重要)
多くのプログラミング言語では、デフォルトで「外部エンティティを読み込む」という危険な設定がONになっている場合があります。これをコード内で無効化しましょう。
PHPを例に挙げます。以下のように libxml_disable_entity_loader を設定して、外部からの読み込みを封じます。
<?php
// 外部エンティティの読み込みを無効化する(これが「鍵」をかける行為です)
libxml_disable_entity_loader(true);
// XMLの解析処理
$dom = new DOMDocument();
$dom->loadXML($xml_input);
?>
対策2:不要なXML機能は使わない
もし可能であれば、JSON形式への移行を検討してください。JSONはXMLのような複雑なエンティティ機能を持たないため、そもそもXXE攻撃の対象になりません。現代の開発では、XMLよりもJSONが主流です。
—
4. まとめ:今日からできる防犯チェック
今日のポイントを振り返りましょう。
- XMLは「手紙」であり、その処理機能に悪意ある指示が隠されている可能性がある。
- 「外部エンティティ(External Entity)」を許可することは、家の鍵を誰かに渡すのと同じ。
- 対策は「パーサーの設定を厳しくする」こと。
もしあなたが開発担当なら、一度「今使っているXMLライブラリで、外部エンティティが無効になっているか?」を公式ドキュメントで確認してみてください。
セキュリティは、一度設定して終わりではありません。家の鍵をかけるように、コードを書いていく中で常に意識することが、あなた自身の、そしてユーザーの安全を守ることにつながります。
一歩ずつ、着実に。今日学んだ知識で、より強固なアプリケーションを作っていきましょう!応援しています。
コメント