2016年6月2日木曜日

Ruby on Railsの潜在的なリモートスクリプトインジェクション脆弱性CVE-2016-2098

今年の2月末に、Ruby on Railsに潜在的なリモートスクリプトインジェクションの脆弱性CVE-2016-2098が報告されています。攻撃コード(PoC)も公開されていますが、現実の攻撃が行われているという発表はないようです。この脆弱性の内容と対策について報告いたします。

背景

Hello Worldのような以下のシンプルなアプリケーション(コントローラ)を考えます。
class HelloController < ApplicationController
  def index
    render 'hello/hello'
  end
end
これに対するテンプレート hello/hello.html.erb は以下だとします。
<div>Hello world</div>
ご覧のように、上記テンプレートを指定した場合、Hello worldが表示されます。
次に、以下のテンプレート hello/bye.html.erb を用意します
<div>Good bye world</div>
これを呼び出すには、コントローラにてrender 'hello/bye'を実行すればよいわけですが、helloとbyeを切り分けられるように、コントローラを以下のように修正します。
class HelloController < ApplicationController
  def index
    render params[:template]
  end
end
これを呼び出すには、以下のようにします。


しかし、renderメソッドの引数を外部から自由に指定できるようにするのは、危なっかしい感じです。

renderメソッドの inlineオプション

renderメソッドにはinlineオプションというものがあり、テンプレート文字列を指定することができます。
render :inline => "<%= Time.now %>"
実行結果を以下に示します。Time.nowメソッドの呼び出しにより、現在時刻が表示されています。


すなわち、外部からrenderメソッドを操作してinlineオプションを指定できれば、任意のRubyスクリプト(上記例ではTime.now)を実行できることになります。具体的には、renderメソッドに下記のハッシュを指定すればよいことになります。
hash = {:inline => "<%= Time.now %>"}
render hash
しかし、そんなことができるのでしょうか?

JSONによりハッシュを外部から指定できる

公開されているCVE-2016-2098のPoCでは、JSONによりrenderメソッドにハッシュを指定する方法が示されています。その様子を以下に示します(少し変えています)。以下の攻撃例では、FileUtils.touchメソッドにより、rootedというファイルを作成することで攻撃の証拠を示しています。


上記の攻撃で、ファイル rooted が作成された様子を下図に示します。
$ ls -l rooted
-rw-rw-r-- 1 ockeghem ockeghem 0  6月  1 22:29 rooted

対策

Ruby on Railsの以下のバージョンで修正されています(今年の2月29日公開)。
  • Rails 3.2.22.2
  • Rails 4.1.14.2
  • Rails 4.2.5.2
これらにバージョンアップすることで攻撃は防がれるようになりますが、そもそもrenderメソッドに任意の値を指定できることがとても危険な状態であると考えます。このため、以下を推奨します。
  • 可能な限りrenderメソッドの引数には外部由来の値を指定しない
  • やむを得ずrenderメソッドの引数を外部から指定する場合は、ホワイトリスト(たとえば指定可能なテンプレートファイル名の一覧)による検証を行う

まとめ

Ruby on Railsの潜在的なリモートスクリプトインジェクションの脆弱性CVE-2016-2098について説明しました。renderメソッドには強力なオプション指定機能があるため、外部から自由な値を指定できると危険です。そもそも、renderメソッドのinlineオプションでrubyスクリプトが実行できることは、脆弱性ではなく仕様です。
このため、この問題は本来Ruby on Railsの脆弱性というよりは、アプリケーション側の問題であと考えます。この問題が「潜在的な」脆弱性と表現されているのは、このような背景からだと思います。


【HASHコンサルティング広告】
HASHコンサルティング株式会社は、ウェブアプリケーションのセキュリティに関心のあるセキュリティエンジニアを募集しています。
興味のある方は、twitterfacebookのメッセージ、あるいは問い合わせページからお問い合わせください。

4 件のコメント:

  1. 記事拝読しました。

    このPoCは CVE-2016-0752、4.2系だとRails 4.2.5.1で改修済であるよう見受けられます。
    GitHubで公開されているPoCは、バージョン4.2.4(Gemfileに記載)で確認されたのではないかと思われ、4.2.5.1では攻撃が成功しません。

    検証時に使用されたRailsのバージョンを教えていただけないでしょうか。

    返信削除
    返信
    1. はい。当方も4.2.4でPoCの動作を確認しています。そして、ご指摘のように4.2.5.1では動作しないことも確認しております。しかし、完全に改修の内容を追いきれていないことと、当方の立場で「4.2.5.1では問題ない」とは言えませんので、保守的に公式な発表通りの記載としました。

      削除
    2. バージョン情報のご回答ありがとうございます。

      GitHubでも、PoCの作者に質問を出しました。回答が得られたら追ってご連絡します。

      削除
  2. 弊社ブログで解説記事を公開したことをご報告しようと思いましたが、既にご覧になった後のようですね(笑)
    コメントありがとうございました。

    返信削除

フォロワー

ブログ アーカイブ