1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

KENROで学んだ!XML External Entity(XXE)脆弱性

Posted at

XML External Entity(XXE)脆弱性まとめ

このたび、GMO Flatt Security 開発者応援プログラム for バイブコーダー に選定いただき、セキュリティ学習サービス 「KENRO」 を1か月無料で利用できることになりました。

「KENRO」は、実践的な脆弱性診断やセキュリティ演習を通じて、開発者が 攻撃者の視点 から安全なシステム設計を学べるオンライン学習プラットフォームです。

本記事では、KENROの学習内容をもとに XML External Entity(XXE)脆弱性 についてまとめます。

XML の基礎

<?xml version="1.0"?>
<response>
  <message id="1">
    <content>Hello!</content>
    <by>Kenta</by>
  </message>
</response>
  • XML はタグの入れ子(木構造)で情報を表現する
  • DTD(Document Type Definition)やスキーマで文書構造を定義できる
  • 外部データ参照の取り扱いが脆弱性に直結することがある

DTD とエンティティ(Entity)

  • DTD 内で <!ELEMENT><!ATTLIST> により構造を定義できる
  • 名前付き定数(エンティティ)を宣言し、&name; で参照可能
  • SYSTEM "file:///..."SYSTEM "http://..." と指定すると External Entity(外部エンティティ)となり、外部リソースを参照できる
<!DOCTYPE top [
  <!ENTITY secret SYSTEM "file:///etc/passwd">
]>
<top>&secret;</top>

このような宣言を解決する設定のまま XML を処理すると、サーバ側のファイルが読み出される危険がある。

XXE(XML External Entity)とは

XXE は、XML パーサが DTD/外部エンティティを制限なく解釈する環境で発生する脆弱性。
攻撃者は XXE を利用して、以下のような攻撃を行うことができる。

  • 機密ファイルの読み出し
  • DoS(処理資源枯渇)
  • SSRF(サーバ経由での内部ネットワーク探索)

仕様上は単純だが、運用・設定の差異により発生しやすく、影響範囲が大きい。

攻撃例

1. サーバ内ファイルの読み出し

攻撃者が以下のような XML を送信すると、パーサが外部エンティティを解決し、/etc/passwd の内容が展開される可能性がある。

<!DOCTYPE top [
  <!ENTITY secret SYSTEM "file:///etc/passwd">
]>
<top><name>&secret;</name></top>

2. Denial of Service(Billion Laughs / XML Bomb)

再帰的なエンティティ展開により、展開量が指数的に増加し、CPUやメモリを大量消費させる。

<!DOCTYPE root [
<!ENTITY e0 "ha">
<!ENTITY e1 "&e0;&e0;&e0;">
<!ENTITY e2 "&e1;&e1;&e1;">
<!ENTITY e3 "&e2;&e2;&e2;">
]>
<root>&e3;</root>

このような攻撃は「Billion Laughs」や「XML Bomb」と呼ばれる。

3. SSRF(Server-Side Request Forgery)

外部エンティティに http://internal/secret などを指定し、サーバ自身に内部リソースへアクセスさせる。
クラウド環境では特に http://169.254.~.~(メタデータサービス)が狙われやすく危険。

実践:脆弱なサンプルと挙動(概観)

以下は、C# における脆弱な設定例。

XmlReaderSettings settings = new XmlReaderSettings();
settings.XmlResolver = new XmlUrlResolver();   // ← 外部参照を許可
settings.DtdProcessing = DtdProcessing.Parse;  // ← DTD を許可
using (XmlReader reader = XmlReader.Create(stream, settings))
{
    XDocument doc = XDocument.Load(reader);
    var name = doc.Descendants("name").First().Value;
}

上記のように XmlResolver を有効にし、DtdProcessing.Parse のままにすると、攻撃者が送った外部エンティティを解決してしまい、情報漏洩や SSRF、DoS を引き起こす可能性がある。

対策(共通方針と言語別実装例)

共通方針(優先順)

  1. 可能なら XML を使わない(JSON 等へ置換)
  2. XML パーサで DTD/外部エンティティを明示的に無効化する
  3. 安全化済みライブラリ(例:defusedxml 等)を利用する
  4. アップロード XML をそのまま出力しない/最小権限で解析する
  5. ライブラリとランタイムを常に最新化する

PHP

// 古いバージョン向けの対策例(環境に依存するため要確認)
libxml_disable_entity_loader(true);
libxml_set_external_entity_loader(function() { return null; });

※PHP のバージョン差に注意。明示的な無効化を行う。

Python

defusedxml の利用を強く推奨。
標準 SAX を使う場合の例:

import xml.sax
parser = xml.sax.make_parser()
parser.setFeature(xml.sax.handler.feature_external_pes, False)
parser.setFeature(xml.sax.handler.feature_external_ges, False)

Java

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
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);
factory.setXIncludeAware(false);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();

Go

標準 encoding/xml は外部エンティティを解決しないため原則安全。
ただし libxml2 等を利用するライブラリを使う場合は DTD 無効化を確認する。

Ruby

Nokogiri 等はオプション次第で外部エンティティを展開する。
NOENT 等の展開オプションを付けないよう注意。

C# (.NET)

XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit; // または Ignore
settings.XmlResolver = null;                     // 外部参照を無効化
using (XmlReader reader = XmlReader.Create(stream, settings))
{
    XDocument doc = XDocument.Load(reader);
}

まとめ

こんな感じでXMLについてをまとめてみました。
あまり聞きなじみのない脆弱性だったので学びになりました

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?