woshidan's loose leaf

ぼんやり勉強しています

Ruby on Rails + rails-ujsを利用している場合のXSS対策について

この記事は情報セキュリティアドベントカレンダーの12日目の記事です。

開発組織でセキュリティをある程度のレベルに担保するための有効な施策として既にセキュリティ対策が施されているフレームワークを利用するようにする、というものがあります。

自分の勤めている会社では、そうした開発フレームワークとしてRuby on Railsを用いています。

Ruby on Railsでは、XSS対策としてViewに変数を表示するため、ERBの <%= %> を用いると、出力が自動的にエスケープされるため、自分でHTMLを出力するプログラムを書いて実行するよりも安全だといえます。

しかし、Railsを普通に使っていても出力がエスケープされない部分も存在します。

それが、rails-ujsでAjax操作する場合のdataパラメータの部分です。 rails-ujsはRailsを使って開発している際、ちょっとしたAjax操作を簡単に開発できるようにしてくれるライブラリです。

link_toヘルパーメソッドなどで、

<%= link_to '削除する', item_path(@item), method: :delete, data: { confirm: "#{@item.name}を削除しますか" } %>

のように、method属性を指定したり、data属性を指定したりして用います。この場合は、リンクをクリックすると「アイテム名を削除しますか」といったダイアローグが表示される動作となります。

Railsでは、基本テンプレートエンジン(ERB)の出力で出力内容をエスケープしてくれるのですが、このrails-ujsで出力される部分はテンプレートエンジンで出力されるのではなく、JavaScriptで出力されるのでエスケープされません。

上のコードの場合、"#{@item.name}を削除しますか"の部分がエスケープされずそのまま表示されることになり、XSS脆弱性が入り込むポイントとなります。

ですので、こういった箇所にはsanitizeメソッドで出力していいHTMLタグを制限したり、escapeHTML(別名h)メソッドでHTML入力文字を、無害なHTML表現形式に置き換えたりします。

このように、フレームワークを使ったから安心というわけではなく個別のメソッドをよく理解してセキュリティホールを埋め込まない体制を作っていきましょう。

参考