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 | 脆弱 |
安全 (1) |
安全 (2) |
脆弱 |
安全 (3) |
DTD retrieval | 脆弱 |
安全 |
安全 |
脆弱 |
安全 |
decompression bomb | 安全 |
安全 |
安全 |
安全 |
脆弱 |
xml.etree.ElementTree
は外部エンティティを展開せず、エンティティが現れた場合はParserError
を送出します。xml.dom.minidom
は外部エンティティを展開せず、展開前のエンティティをそのまま返します。xmlrpclib
は外部エンティティを展開せず、除外します。
- 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 のバグ修正リリースには取り込まれません。