第7章 エコーバック対策
スクリプト注入: #2 攻撃の解説
スクリプト注入攻撃
スクリプト注入(いわゆるクロスサイトスクリプティング)は、被害者のブラウザに悪意のスクリプト(主にJavaScriptのコード)が入り込み、ブラウザの内側からセキュリティ侵害が起こる問題である。
攻撃のメカニズム
スクリプト注入は、「攻撃者」「標的サイト」「被害者」の三者の間で、次のようなメカニズムによって起こる。
- 攻撃ページ
攻撃者は、スクリプト注入攻撃のHTMLページ(「攻撃ページ」)を用意する。攻撃者はこの攻撃ページを、被害者を騙して閲覧させるか、HTMLメールにて送りつける。 - 標的プログラムの呼び出し
この攻撃ページは、被害者がユーザとして日常アクセスしているあるひとつのWebサイト(「標的サイト」)の特定のプログラム(「標的プログラム」)を呼び出すよう作られている。このとき入力パラメータとして、悪意あるJavaScriptコード(「攻撃スクリプト」)がその標的プログラムに与えられるよう仕組まれている。 - 標的として狙われるプログラム
攻撃ページから呼び出される標的プログラムには、与えられた入力パラメータの文字列をそのままHTMLページ内に出力する─おうむ返しにする─ものが選ばれる。 - 悪意のスクリプトの実行
攻撃ページから投入されたHTTPリクエストに呼応して標的プログラム返されるレスポンスには、攻撃者が仕込んだ攻撃スクリプトが含まれており、これが被害者のブラウザの中で実行される。 - スクリプトによる侵害
被害者のブラウザの中で動作する攻撃スクリプトは、次のような侵害を行い得る。- 不正なページに誘導して被害者を騙す。例えば、正規ページのリンクを書き換えて不正なページに誘導し、意図しない商品の購入等を行わせる。
- 偽のページを表示して被害者を騙す。例えば、偽のログインフォームを表示して被害者にパスワード入力を促し、入力内容を攻撃者が用意したWebサーバに報告する(アカウント乗っ取り)
- Cookieを勝手に設定する。例えば、標的サイトに被害者がログインする前の時点で、攻撃者にとって都合の良い値をそのサイトで今後セッション管理に使われるであろうCookieに設定する(セッションフィクセーション→セッション乗っ取り)
- Cookieを盗み出す。標的サイトに被害者がログインしている状況下で、そのサイトでいま使われているCookieの値を盗み出し、攻撃者が用意したWebサーバに報告する(セッションIDの捕捉→セッション乗っ取り)
- Hiddenに設定してある値を盗み出したり、任意の値を設定する。例えば、Hiddenに個人情報やクレジットカード情報等があればそれらを攻撃者が用意したWebサーバに報告する(重要情報の搾取)
スクリプトが動作する箇所
HTMLドキュメント内には、スクリプトを記述し実行できる箇所が数多く存在する。たとえばつぎのような箇所である(図25)。
- <script>タグ等を用いたスクリプト直接記述
- <script>タグ等を用いたスクリプトファイルURLのリモート参照
- <img src="javascript:...">等、タグのURL属性中へのスクリプト直接記述
- <div style="...;z:expression(...);...">等、タグのstyle属性中へのスクリプト直接記述
- <span onmouseover="...">等、タグのイベントハンドラ属性中へのスクリプト直接記述
- <a href="&{...};">等、タグ属性値におけるエンティティ参照内のスクリプト記述(Netscape 4.x で動作)
攻撃者は、スクリプトが実行されるこれらの箇所にJavaScriptプログラムの文字列をあてはめるか、何も無いところにこのような構文が作り出されるようデータを工夫して送り込んでくる。

図25: スクリプトが動作する箇所
攻撃文字列
攻撃者がWebアプリケーションプログラムにエコーバックさせるべく投入してくる攻撃文字列には多くのバリエーションがあり得る。その一部を挙げると、例えば次のようなものである。
手口の例(1)
テキスト部分に直接タグを挿入する
- 攻撃文字列の例:
- <script>document.cookie='jsessionid=BAD'</script>
手口の例(2)
引用符と>を用いタグ属性値から脱出して<script>タグを挿入する
- 攻撃文字列の例:
- '"><script>document.cookie='jsessionid=BAD'</script>
手口の例(3)
コメント終了記号を用いHTMLコメントから脱出して<script>タグを挿入する
- 攻撃文字列の例:
- --><script>document.cookie='jsessionid=BAD'</script>
手口の例(4)
javascript:等スクリプトを起動するスキームを用いた文字列をタグのURL属性の値として与える
- 攻撃文字列の例:
- javascript:document.cookie='jsessionid=BAD'
手口の例(5)
expression()を用いてスタイル中にスクリプトを記述する
- 攻撃文字列の例:
- red;z:expression(document.cookie='jsessionid=BAD')
手口の例(6)
タグのイベントハンドラ属性内の文字列定数'xxx'から脱出してスクリプトを記述する
- 攻撃文字列の例:
- ';document.cookie='jsessionid=BAD
手口の例(7)
<script>...</script>の内側の文字列定数'xxx'から脱出してスクリプトを記述する
- 攻撃文字列の例:
- ';document.cookie='jsessionid=BAD (手口の例(6)と同一)