XSSはブラウザ上でスクリプトが動き、CSRFはサーバー上でスクリプトが動く

昨日の日記で、DK祭りで使われている脆弱性XSSCSRFかという問題になった。どうも、XSSとCSRFがごっちゃになっている人もいるように見受けるので、簡単な整理を試みたい。
XSSCSRFには似た点がある。

  • どちらも「クロスサイト」という言葉が先頭につく
  • なりすましのようなことが結果としてできる
  • どちらも受動型攻撃である

それに対して、もちろん違う点もある。専門家から見れば「似てるも何も、そもそも全然違うものですよ」となるのだろうが、現に混同している人がいるのだから紛らわしい点もあるのだろう。
私思うに、XSSCSRFの決定的な違いは、以下の点ではないだろうか。

XSSは攻撃スクリプトがブラウザ上で動くが、CSRFはサーバー上で動く

このため、XSSでできる悪いことは、すなわちJavaScriptでできることであって、攻撃対象のCookieを盗み出すことが典型例となる。一方、CSRFでできる悪いことは、サーバー上でスクリプトを動かすことである。サーバー上のスクリプトはあらかじめサイトに用意されたものであるので、実際には任意のスクリプトが動かせるわけではなく、パラメータによって「悪いこと」を実現する。実行結果を攻撃者書が見ることは出来ない。
これだけでは少々分かりにくい。具体例を提示しよう。
ここに架空の人物、danとhamachanが登場する。架空の人物であるので、仮に二人が、読者の知っている実在の人物にどんなに似ていたとしても、それは偶然にすぎない。また、架空の人物であるので「スペルが違う」などの指摘は却下する。
hamachanは、Webサイトmaitterで、danに「俺、実はPerl嫌いなんだ....」と発言させたいと考えている。

まずは、XSSを利用した攻撃例

  • hamachanは罠を仕込んだWebサイトwana.netを用意し、danが閲覧するのを待つ
  • danがwana.netを閲覧する。
    • JavaScriptが実行され、danのブラウザはmaitterに攻撃用JavaScriptを含む内容をポストする
    • danのブラウザ上でmaitterが表示される。表示には攻撃用JavaScriptを含んでいる
    • 攻撃用JavaScriptが実行され、maitterドメインcookie値を読み、wana.netにポストする
  • hamachanは、wana.netにポストされたcookie値を悪用してdanになりすます
  • hamachanは、maitter上でdanになりすまし、「俺、実はPerl嫌いなんだ....」と発言する

次に、CSRFを利用した攻撃例

  • hamachanは罠を仕込んだWebサイトwana.netを用意し、danが閲覧するのを待つ
  • danがwana.netを閲覧する
    • JavaScriptが実行され、悪意を持ったパラメータをmaitterにポストするよう指令する。パラメータには「俺、実はPerl嫌いなんだ....」が含まれる
    • danのブラウザ上でmaitterに上記パラメータをポストする。Cookie値はdanのものであるため、danのセッションとして受理される。
  • danの発言として「俺、実はPerl嫌いなんだ....」が表示される

お分かりだろうか。JavaScriptを使ってmaitterにポストするところまでは同じなのだが、ポストする内容が異なる。XSSの場合では攻撃用JavaScriptを含んだ文字列をポストはするものの、ブラウザ上でそのJavaScriptが表示・実行された時点で初めて攻撃となる。一方、CSRFの方は、ポストすること自体が攻撃であって、その結果サーバー上で起こされる動作(上記の場合は「僕、実は....」の書き込み)が目的である。表にまとめると以下のようになる。

動作 XSS CSRF
ポストする内容 JavaScriptを含む文字列 書き込む内容など「僕、実は...」
サーバー上の副作用 攻撃には利用されない 副作用自体が攻撃「僕、実は...」
ブラウザ上の表示 JavaScriptなどの実行により攻撃 攻撃には利用されない

XSSの攻撃では、「俺、実はPerl嫌いなんだ....」と発言するのはhamachanである。それに対して、CSRFは「俺、実は....」という内容をポストするのは、dan自身である(本人の知らないうちに)。そのように仕組むのがCSRFなのだ。

結果として、「俺、実はPerl嫌いなんだ....」という発言がなされたとしても、両者には大きな差がある。XSSの場合は、セッションをハイジャックしているので、maitter上で発言する以外に、プロファイルの変更などdanのセッション上でできることはなんでもできる。ただし、パスワードの再入力が求められる機能については、XSS単体ではパスワードまでは知ることができないので、実行できない*1

CSRFを使っても、プロファイルの変更など出来る場合もある。それは、プロファイル変更画面にCSRF脆弱性があって、かつdanがその脆弱性を悪用した攻撃ページを閲覧してしまった場合のみだ。JavaScriptなどをうまく使えば、一連の動作をCSRFで実行させることはできるが、その場の会話の流れに応じて発言内容を変えていくことは難しい。先のDK祭りで悪用された脆弱性XSSではないかと推理した理由はここにある。

産総研の高木先生に「それCSRFだよね脳」と指導を受けないためにも、両者の違いをしっかりと身に着けよう。

*1:昨日の日記で指摘したような方法でパスワードを変更できるか、閲覧できる場合は別