hiyoko-programingの日記

プログラミングを勉強したてのひよっ子。   エンジニア目指して勉強中。

XSS

XSSクロスサイトスクリプティング)とは

Webアプリケーションでは、外部からの入力などに応じて表示が変化する箇所ページを実装したいことがしばしばある。
しかし、この部分のHTML生成の実装に問題があると、外部よりスクリプトを埋め込まれクッキーを盗まれたり、JavaScriptによる攻撃を受けてしまうおそれがある。
こういった攻撃手法をクロスサイトスクリプティングと言う。

XSSの攻撃例

では、実際にXSS脆弱性を用いた攻撃例を見てみる。
ここでは登場人物を用いて説明する。

ユウスケ・・・ 一般ユーザ
タカシ ・・・攻撃を仕掛ける悪意のある者

1. タカシXSS脆弱性があるサイトに悪意のあるスクリプトを埋め込む
2. タカシは1.でスクリプトを埋め込んだサイトをリンクに指定する罠サイトを用意する
3. タカシユウスケに罠サイトへ誘導するようなメールを送信する
4. ユウスケは罠サイトにアクセスし、タカシスクリプトを埋め込んだサイトにアクセス
5. ユウスケのブラウザ上でタカシが埋め込んだスクリプトが実行される


ここで出てくる罠サイトとは、スクリプトを埋め込んだXSS脆弱性のあるサイトへのリンクを含んでいるページのことをいう。

https://tech-master.s3.amazonaws.com/uploads/curriculums//91f0a8e8236d05eb5d9ddf106bea145d.jpeg

ここで実行されるスクリプトの例としては、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
にアクセスして、投稿フォームに以下のように入力し、トップページに戻ってみる。

スクリーンショット 2015-10-10 15.08.08.png

これは、XSS脆弱性があるかどうかを確かめるスクリプト
もしもXSS脆弱性があるサイトの投稿フォームにこちらを送信した場合、送信した瞬間にアラートが出現する。
しかし、アラートはでないことがわかる。
実はRailsでは、先ほど説明したXSSの対策はあらかじめ行われている。
具体的には、Railsのerbという拡張子のついたファイルの中で<%= %>で囲まれたものが出力される際は、文字参照の変換が行われた状態で表示されるという仕組みになっている。

あまり使用することはないが、この文字参照の変換を無効にすることも可能。

/app/views/tweets/_tweet.html.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
にアクセスし先ほどと同じように以下のように入力してトップページに戻ってみる。

スクリーンショット 2015-10-10 15.08.08.png

すると以下のようにアラートが出てくる。

https://tech-master.s3.amazonaws.com/uploads/curriculums//dacf20e89481e1afcd9b65595e9b594f.png

これはrawメソッドを使うことによって、文字参照が行われずtextを表示する領域にscriptタグが埋め込まれてしまい、その中に記述されているJavaScriptのコードが実行されるという仕組みになっている。

今回はアラートを出すというコードしか記述していないが、ここにマルウェアが埋め込まれているサイトへリダイレクトする処理を記述し、リダイレクト先でPCをウイルスに感染させることも可能。

まとめ

  • XSSとはHTML生成の際の処理に問題があるサイトにスクリプトを埋め込む攻撃手法である
  • XSSは主にJavaScriptを埋め込むことによって実現する攻撃なので、JavaScriptで実現可能なすべての攻撃手法を被る可能性がある
  • XSSを防ぐにはHTML生成時に意味を持つ特殊文字列を文字参照によりエスケープする