19.5. XMLを扱うモジュール群¶
PythonのXMLを扱うインタフェースは xml
パッケージにまとめられています。
警告
XML モジュール群は不正なデータや悪意を持って生成されたデータに対して安全ではありません。信頼できないデータをパースする必要がある場合は、 XML の脆弱性 を参照してください。
注意すべき重要な点として、 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 バインディング
19.6. XML の脆弱性¶
XML処理モジュールは悪意を持って生成されたデータに対して安全ではありません。攻撃者は脆弱性を使って、 DoS攻撃、ローカルファイルへのアクセス、他マシンへのネットワーク接続、ファイアーウォールの迂回などが可能になります。 XML に対する攻撃は、エンティティに対するインライン DTD (Document Type Definition) などのマイナーな機能を悪用します。
以下のテーブルは知られている攻撃と、各モジュールがそれに対して脆弱であるかどうかを示しています。
種類 | 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 とも呼ばれる – は、複数レベルにネストしたエンティティを用います。各エンティティは他のエンティティを複数回参照し、最後のエンティティ定義は小さい文字列を含みます。最終的に、その小さい文字列は数ギガバイトにまで展開されます。 exponential expansion は大量の CPU 時間も消費します。
- quadratic blowup entity expansion
- quadratic blowup 攻撃は Billion Laughs 攻撃と似ています。こちらもエンティティの展開を利用します。ネストしたエンティティを用いる代わりに、数千文字のエンティティ1つを繰り返し利用します。この攻撃は指数関数的な効率はありませんが、パーサーのエンティティのネスト対策を回避します。
- external entity expansion
- エンティティの定義はただのテキスト置換以上のことができます。 public identifier や system identifier を使って外部のリソースを参照することもできます。 system identifier は標準的な URI やローカルファイルを参照できます。 XML パーサーはリソースを HTTP や FTP リクエストを用いて取得し、その内容を XML ドキュメントに埋め込みます。
- DTD retrieval
- Python の
xml.dom.pulldom
のような XML ライブラリは DTD をリモートやローカルの場所から読み込みます。この機能には外部エンティティ展開の問題と同じことが予想されます。 - decompression bomb
- decompression bomb (ZIP bomb とも呼ばれる) 問題は、 gzipped HTTP ストリームや LZMA ファイルなどの圧縮された XML ストリームをパースできる全ての XML ライブラリに適用されます。攻撃者は送信するデータ量を1/3かそれ以下に減らすことができます。
PyPI にある defusedxml のドキュメントは、全ての知られている攻撃手法についてのさらなる情報を、例や参照つきで提供しています。
19.6.1. defused packages¶
これらの拡張パッケージは、信頼出来ない XML データを解析するあらゆるコードでの使用に推奨されます。
defusedxml は、潜在的に悪意のある操作を防止するように修正された標準 XML パーザのサブクラスを含む pure Python パッケージです。このパッケージには、さらに exploit の例や xpath インジェクションのようなより多くの XML exploit についての幅広いドキュメントが付属しています。
defusedexpat は libexpat を改造したものと、 pyexpat
にパッチを当てた拡張モジュールで、エンティティ展開を使った DoS 攻撃の対策をしています。
defusedexpat は、安全で設定可能な量のエンティティ展開を許可します。この改造は将来のバージョンの Python にマージされる予定です。
これらのワークアラウンドや改造は、後方互換性のためにパッチレベルのリリースには含められません。また、インライン DTD とエンティティ展開は、正しく定義された XML の機能です。