# 20.4. XMLを扱うモジュール群

ソースコード: Lib/xml/

PythonのXMLを扱うインタフェースは `xml` パッケージにまとめられています。

警告

XML モジュール群は不正なデータや悪意を持って作成されたデータに対して安全ではありません。信頼できないデータをパースする必要がある場合は XML の脆弱性 と defusedxml および defusedexpat パッケージ を参照してください。

注意すべき重要な点として、 `xml` パッケージのモジュールは SAX に対応した XML パーザが少なくとも一つ利用可能でなければなりません。Expat パーザが Python に取り込まれているので、 `xml.parsers.expat` モジュールは常に利用できます。

`xml.dom` および `xml.sax` パッケージのドキュメントは Python による DOM および SAX インタフェースへのバインディングに関する定義です。

XML に関連するサブモジュール:

- `xml.etree.ElementTree`: ElementTree API、シンプルで軽量な XML プロセッサ

- `xml.dom`: DOM API の定義

- `xml.dom.minidom`: 最小限の DOM の実装

- `xml.dom.pulldom`: 部分的な DOM ツリー構築のサポート

- `xml.sax`: SAX2 基底クラスと便利関数群

- `xml.parsers.expat`: Expat parser バインディング

## 20.4.1. XML の脆弱性

XML 処理モジュールは悪意を持って生成されたデータに対して安全ではありません。攻撃者は XML の機能を悪用して DoS攻撃、ローカルファイルへのアクセス、他マシンへのネットワーク接続、ファイアーウォールの迂回などを行うことが出来ます。

以下の表は既知の攻撃と各モジュールがそれに対し脆弱かどうかの概要を示しています。

種類 | sax | etree | minidom | pulldom | xmlrpc
--- | --- | --- | --- | --- | ---
billion laughs | 脆弱 | 脆弱 | 脆弱 | 脆弱 | 脆弱
quadratic blowup | 脆弱 | 脆弱 | 脆弱 | 脆弱 | 脆弱
external entity expansion | 安全 (4) | 安全 (1) | 安全 (2) | 安全 (4) | 安全 (3)
DTD retrieval | 安全 (4) | 安全 | 安全 | 安全 (4) | 安全
decompression bomb | 安全 | 安全 | 安全 | 安全 | 脆弱

1. `xml.etree.ElementTree` は外部エンティティを展開せず、エンティティが現れた場合は `ParserError` を送出します。

2. `xml.dom.minidom` は外部エンティティを展開せず、展開前のエンティティをそのまま返します。

3. `xmlrpclib` は外部エンティティを展開せず、除外します。

4. Since Python 3.8.0, external general entities are no longer processed by default since Python.

billion laughs / exponential entity expansion

  Billion Laughs 攻撃 -- または指数関数的エンティティ展開 (exponential entity expansion) -- は複数階層の入れ子になったエンティティを使用します。 各エンティティは別のエンティティを複数回参照し、最終的なエンティティの定義は短い文字列です。 指数関数的に展開されることで数 GB のテキストができ、多くのメモリと CPU 時間を消費します。

quadratic blowup entity expansion

  二次爆発攻撃 (quadratic blowup attack) はエンティティ展開を悪用する点で Billion Laughs 攻撃に似ています。 入れ子になったエンティティの代わりに、この攻撃は数千字の大きなエンティティを何度も繰り返します。 この攻撃は指数関数的なものほど効率的ではありませんが、パーザの深い入れ子になったエンティティを禁止する対抗手段をすり抜けます。

external entity expansion

  (外部エンティティ展開) エンティティの定義はただのテキスト置換以上のことが出来ます。 外部のリソースやローカルファイルを参照することも出来ます。 XML パーザはリソースにアクセスしてその内容を XML 文書に埋め込みます。

DTD retrieval

  Python の `xml.dom.pulldom` のような XML ライブラリは DTD をリモートやローカルの場所から読み込みます。 この機能には外部エンティティ展開の問題と同じことが予想されます。

decompression bomb

  解凍爆弾 (あるいは ZIP 爆弾) は、gzip 圧縮 HTTP ストリームや LZMA 圧縮ファイルなどの圧縮された XML ストリームをパースできる全ての XML ライブラリに対し行われます。 攻撃者は送信データ量を1/3以下に減らすことができます。

PyPI 上の defusedxml のドキュメントには既知の攻撃手法の詳細が例と文献付きであります。

## 20.4.2. `defusedxml` および `defusedexpat` パッケージ

defusedxml は潜在的に悪意のある操作を防ぐ、修正された stdlib XML parsers のサブクラスが付属している純 Python パッケージです。信頼出来ない XML データをパースするサーバーコードではこのパッケージの使用が推奨されます。パッケージには悪用の例に加え、XPath injection 等のさらなる XML の悪用の例があります。

defusedexpat はエンティティ展開を使った DoS 攻撃の対策をしている、修正された libexpat とパッチを当てた `pyexpat` モジュールを提供しています。 それでも、`defusedexpat` モジュールは常識的で設定可能な量のエンティティ展開を許可しています。 この修正は Python の将来のリリースに取り込まれるかもしれませんが、後方互換性を破壊するため Python のバグ修正リリースには取り込まれません。