【入門編】XXE(XML外部エンティティ)攻撃の仕組みとXMLパーサーの安全な設定 – アプリケーションセキュリティ & 安全な開発防御ガイド

「XMLを読み込ませるだけ」で家の中まで覗かれる? XXE攻撃の正体と鉄壁の守り方

こんにちは。現場で泥臭いインシデント対応を重ねていると、たまに「えっ、まさかそんなところが?」という意外な穴から攻撃者が侵入してくるケースに遭遇します。

今回解説するXXE(XML External Entity)攻撃は、まさにその代表格。一見すると「ただのデータのやり取り」に見えるXMLが、実は「泥棒に合鍵を渡してしまう」ような危うい側面を持っているんです。

「難しそう…」と身構える必要はありません。まずは身近な例から、この攻撃の仕組みを紐解いていきましょう。

—

1. XXE攻撃を「家の防犯」で例えると?

XMLは、システム間で情報をやり取りするための「手紙」のようなものです。例えば、あなたがウェブサイトで注文をする際、裏側では「商品名」や「数量」がXMLという形式で書かれた手紙が送られています。

通常、この手紙には「リンゴを3つください」といった情報しか書かれていません。しかし、XXE攻撃者はここに「この手紙を読み込むついでに、家の金庫(サーバー内の重要ファイル)の中身も見て、結果を教えてね」という「不正な命令」をこっそり書き加えます。

これがXXEの恐ろしいところです。XMLパーサー(手紙の開封役)が、その「不正な命令」を律儀に実行してしまうことで、本来見せてはいけないサーバー内のパスワードファイルや設定ファイルが、攻撃者の元へ送信されてしまうのです。

—

2. なぜそんなことが起きるのか?

XMLには「外部エンティティ」という、離れた場所にある情報を参照してくる便利な機能があります。本来は「別の場所にある長い文章を引用する」といった用途で使われるものなのですが、攻撃者はこれを使って「サーバー内部のファイルを呼び出す」という悪用をします。

開発者が「便利な機能だから」とデフォルト設定のままパーサーを使うと、まるで「どんな手紙の指示でも断らずに実行する執事」を雇っているような状態になってしまうわけですね。

—

3. 「執事」を賢くする!安全なXMLパーサーの設定

では、どうすればこの執事を守れるのでしょうか? 答えは簡単です。「外部からの指示(外部エンティティ)を無視するように設定する」こと。これだけで、XXE攻撃のほとんどは無効化できます。

代表的な言語での設定例を見てみましょう。

Java (DocumentBuilderFactory) の場合

Javaでは、外部エンティティを無効にする設定を明示的に記述する必要があります。

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

// ここが重要!外部エンティティの読み込みを禁止します
factory.setFeature(“http://xml.org/sax/features/external-general-entities”, false);
factory.setFeature(“http://xml.org/sax/features/external-parameter-entities”, false);
factory.setFeature(“http://apache.org/xml/features/disallow-doctype-decl”, true);

DocumentBuilder builder = factory.newDocumentBuilder();
// これで安全にXMLを解析できます!

PHP (libxml) の場合

PHPでは libxml_disable_entity_loader 関数を使います(PHP 8.0以降はデフォルトで無効になっていますが、念のため意識しておきましょう)。

// 外部エンティティの読み込みを無効にする設定
libxml_disable_entity_loader(true);

// XMLを読み込む処理を実行
$dom = new DOMDocument();
$dom->loadXML($xml_string);

—

4. 開発者として覚えておきたい「鉄の掟」

これから開発をする皆さんに、これだけは覚えておいてほしいことがあります。

1. デフォルトを信用しない: フレームワークやライブラリの多くは「利便性」を優先しています。セキュリティ設定は必ず自分たちで確認し、意図的に「オフ」にしてください。
2. XML以外も選択肢に入れる: もし可能であれば、XMLではなくJSON形式の利用を検討してください。JSONにはXMLのような「外部エンティティ」という概念自体がありません。攻撃の入り口を一つ減らすことができます。
3. 最新版を使う: セキュリティはいたちごっこです。使用しているライブラリが古いままだと、既知の脆弱性を突かれるリスクが高まります。

—

まとめ:一歩ずつ、安全な開発を

XXE攻撃は、決して「プロしか防げない魔法」ではありません。今回紹介したように、XMLパーサーの「設定」を少し変えるだけで、あなたのサービスを守る頑丈な鍵をかけることができます。

「自分の書いたコードが、誰かの財産を守っている」。そう考えると、少しだけセキュリティの設定が楽しくなりませんか?

もし開発中に「これって設定できているのかな?」と不安になったら、いつでもまたここを覗きに来てください。一緒に、安全な開発現場を作っていきましょう!

コメント

タイトルとURLをコピーしました