XSS
XSS(クロスサイトスクリプティング)とは
Webアプリケーションでは、外部からの入力などに応じて表示が変化する箇所ページを実装したいことがしばしばある。
しかし、この部分のHTML生成の実装に問題があると、外部よりスクリプトを埋め込まれクッキーを盗まれたり、JavaScriptによる攻撃を受けてしまうおそれがある。
こういった攻撃手法をクロスサイトスクリプティングと言う。
XSSの攻撃例
では、実際にXSSの脆弱性を用いた攻撃例を見てみる。
ここでは登場人物を用いて説明する。
ユウスケ・・・ 一般ユーザ
タカシ ・・・攻撃を仕掛ける悪意のある者
1. タカシはXSSの脆弱性があるサイトに悪意のあるスクリプトを埋め込む
2. タカシは1.でスクリプトを埋め込んだサイトをリンクに指定する罠サイトを用意する
3. タカシはユウスケに罠サイトへ誘導するようなメールを送信する
4. ユウスケは罠サイトにアクセスし、タカシがスクリプトを埋め込んだサイトにアクセス
5. ユウスケのブラウザ上でタカシが埋め込んだスクリプトが実行される
ここで出てくる罠サイトとは、スクリプトを埋め込んだXSSの脆弱性のあるサイトへのリンクを含んでいるページのことをいう。
ここで実行されるスクリプトの例としては、cookieを攻撃者のサーバに送信されてしまったり、マルウェア(悪意のあるソフトウェア)を仕込んであるサイトにリダイレクトされウイルスに感染させられたりとJavascriptで記述することが可能なすべての攻撃を受けてしまう可能性がある。
XSSの対策
一般的な対策方法
XSSが発生する主要因として、フォームから入力されたHTMLタグがそのままページに反映されてしまっていることがあげられる。
したがって、XSSを防ぐためにはHTMLを生成する際に意味を持つ「"」や「<」を文字参照によってエスケープすることが基本となる。
文字参照
文字参照とはHTML上で直接記述できない特殊文字を表記する際に用いられる記法。例えば、HTML中に「<」もしくは「>」と記述するとこの二つはタグの初め、終わりと認識されてしまう。これでは文字列として上記の記号を用いることができない。そこで、文字参照を利用する。
変換前 | 変換後 |
---|---|
< | & lt; |
> | & gt; |
& | & amp; |
" | & quot; |
' | & #39; |
上の表は、XSSを対策する際にエスケープすべき特殊文字の一覧。これらの特殊文字を文字参照に変換して保存すれば、外部から埋め込まれたスクリプトが実行されることはない。
RailsでのXSS対策方法
ここまではXSSの一般的な対策方法。しかし、「先ほどのような対策はしていないから、XSSの脆弱性があるのでは」と考える人もいるかもしれない。
それでは実際にPictweetを例にとって試す。
1 2 |
> cd pictweet
> rails s
|
サーバを立ち上げたらlocalhost:3000/tweets/new
にアクセスして、投稿フォームに以下のように入力し、トップページに戻ってみる。
これは、XSSの脆弱性があるかどうかを確かめるスクリプト。
もしもXSSの脆弱性があるサイトの投稿フォームにこちらを送信した場合、送信した瞬間にアラートが出現する。
しかし、アラートはでないことがわかる。
実はRailsでは、先ほど説明したXSSの対策はあらかじめ行われている。
具体的には、Railsのerbという拡張子のついたファイルの中で<%= %>で囲まれたものが出力される際は、文字参照の変換が行われた状態で表示されるという仕組みになっている。
あまり使用することはないが、この文字参照の変換を無効にすることも可能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<div class="content_post" style="background-image: url(<%= tweet.image %>);">
<% if user_signed_in? && current_user.id == tweet.user_id %>
<div class="more">
<span><%= image_tag 'arrow_top.png' %></span>
<ul class="more_list">
<li>
<%= link_to '編集', "/tweets/#{tweet.id}/edit", method: :get %>
</li>
<li>
<%= link_to '削除', "/tweets/#{tweet.id}", method: :delete %>
</li>
</ul>
</div>
<% end %>
<p>
<%= raw(tweet.text) %>
</p>
<span class="name"><%= tweet.user.nickname %></span>
</div>
|
rawメソッド
1 |
raw(文字列)
|
localhost:3000/tweets/new
にアクセスし先ほどと同じように以下のように入力してトップページに戻ってみる。
すると以下のようにアラートが出てくる。
これはrawメソッドを使うことによって、文字参照が行われずtextを表示する領域にscriptタグが埋め込まれてしまい、その中に記述されているJavaScriptのコードが実行されるという仕組みになっている。
今回はアラートを出すというコードしか記述していないが、ここにマルウェアが埋め込まれているサイトへリダイレクトする処理を記述し、リダイレクト先でPCをウイルスに感染させることも可能。
まとめ
- XSSとはHTML生成の際の処理に問題があるサイトにスクリプトを埋め込む攻撃手法である
- XSSは主にJavaScriptを埋め込むことによって実現する攻撃なので、JavaScriptで実現可能なすべての攻撃手法を被る可能性がある
- XSSを防ぐにはHTML生成時に意味を持つ特殊文字列を文字参照によりエスケープする