学習忘備録

学習のアウトプットや感じた事を発信していきます

XML外部実体参照

書籍を読んで

www.amazon.co.jp

こちらの書籍を読んでWebアプリケーションを作る際に重要な要点を自分用としてアウトプットします。

XML外部実体参照(XXE)

概要

XMLには外部実体参照という機能があり、外部ファイルの内容を取り込むことができる。 XMLデータを外部から受け取るプログラムは、外部実体参照の形でWebサーバ内部のファイルなどを不正に読み取られる可能性がある。 この攻撃をXML実体参照攻撃と呼び、XML外部実体参照ができてしまう脆弱性XML外部実体参照脆弱性と呼ぶ。 ※XML外部実体参照という用語は長いので、XXE(XML External Entity)と省略する。

脆弱性が生まれる原因

XMLの外部実体参照を使うとXML中に外部のファイルを流し込むことが出来ることはXMLが元々持つ機能。 従って、XXEはXMLの機能を悪用するものであり、プログラムにコーディング上のバグがあるというものではない。

対策

XXEはXMLの機能を悪用するものなので、外部実体参照を禁止する指定を行うことが基本となる。 PHPの場合以下のいずれかの方法でXXE対策が可能。

XMLの代わりにJSONを用いる

外部から与えられた信頼できないXMLを解析しないことでXXE対策となる。 しかし、XMLは外部とのデータ交換に用いられることも多いため、単にXMLの受け取りをやめるというのは難しい場合がある。 このため、外部とのデータ交換には、XMLの代わりにJSONを用いる方が安全である。 JSONの場合、安全でないデシリアライゼーションやXXEなどの問題は通常発生しない。 ただし、SOAPのようにプロトコルXMLを採用している場合には、XMLをやめるわけにはいかないので、以下の外部実体参照を禁止する方法で対策する。

libxml2のバージョン2.9以降を用いる

PHPXML処理には、内部でlibxml2というライブラリが用いられている。 libxml2の2.9以降では、デフォルトで外部実体参照を停止する設定となっており、XXEに対して脆弱ではない。 ただし、PHP側で外部実体参照を許可する設定にしている場合は例外となる。 ※メジャーなLinuxディストリビューションに関して、サポート継続中、かつ最新のパッチを適用していれば、libxml2側で外部実体参照を停止していることが確認されている。

libxml_disable_entity_loader(true)を呼び出す

PHPにはlibxml_disable_entity_loaderという関数が用意(PHP5.2.11以降)されていて、これを呼び出すことにより、libxml2やPHP側の処理内容に関わらず外部実体参照が禁止される。

まとめ

XXEが最初に報告されたのが2002年なので、かなり古くから知られている問題だが、これまで大きく取り上げられることはなかった。 しかし、OWASP TOP10の2017年版に4番目のリスクとしてランクインしたことにより大きな注目を集めることになる。 PHPを使う限り、libxml2のバージョンアップあるいはパッチ適用に対策されるが、Java言語の場合アプリケーション側での対策が必要となるため、PHP以上に注意が必要である。