君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

ピザ◯ラから100枚のピザが届くまで 〜 CSRF対策とは(その2)

CSRF対策とは

  • その1「CSRF攻撃」について

  • その2「CSRF対策」について

  • その3「RailsにおけるCSRF対策」について

の「その2」です。

おさらい

CSRFとは

  • 悪い人が使うwebサイト攻撃方法
  • これをされるとすごく困る
  • 具体的には「ピザ◯ラから100枚のピザが届いたり」する

前回は、どうやって「ピザ◯ラから100枚のピザが届く」のかシミュレーションをしました。

問題点

f:id:karoten512:20171015194503g:plain

リクエストが正しいページから送られてきているのか

をサーバが判別することが出来ていないのが問題です。

今回はそれを解決します。

解決方法(抽象)

「今来たリクエスト、

 さっき俺(サーバ)が発行したページから来た正しいリクエストなのか?

 それともぜんぜん関係ないページから来たヤバいリクエストなのか?」

というサーバさんの悩みを解決すればよいということになります。

解決方法(具体)

サーバからページを発行する際に、「指紋(token)」をつけておき、

次回のリクエスト時にtokenを持っているか確認します。

以下、具体的にどうやっているのか説明していきます。

正常な場合

f:id:karoten512:20171015204114g:plain

ブラウザからページをリクエストされたサーバは、

token(特定の法則に従って作られた文字列)を作成しそれを保持します。

またそれをhtmlに含めて返します。

htmlのform要素(hidden)に含ませることが多いです。

f:id:karoten512:20171015202047g:plain

さて、購入ボタンが押されると、

data、cookieそして

hidden要素に含まれるtokenがサーバに送信されます。

サーバは送られてきたtokenとサーバ上に保持しておいたtokenを照合して、

「正しいページ」から情報が送られてきたことを確認します。

その後、ユーザ特定を行い、購入処理を行います。

CSRF攻撃された場合

f:id:karoten512:20171015202950g:plain

第3者が発行したページにはtokenが含まれないか、

間違ったtokenが含まれているので、以上のように購入処理が弾かれます。

まとめ

セキュリティを高めるには、

  • 正しい人からのリクエストであること(cookie

に加えて、

  • 正しいページからのリクエストであること(CSRF対策)

が重要ということがよくわかりました。

補足

ワンタイムトーク

なお、攻撃者がtokenを手に入れてしまうと悪いことをされてしまうので、

基本的にtokenは1回のリクエスト毎に新しくなります。

(ワンタイムトークンといいます)

tokenを保持する場所

今回hidden要素に含ませる方法を紹介しましたが、

http headerに含ませる方法もあります。

token照合の方法

今回簡単のために、

クライアント側で保持するtokenとサーバ側で保持するtokenを同一のものとして扱いました。

実際は文字列自体が異なっていることが多いらしいです。

クライアントから受け取ったtokenを、サーバ側でゴニョゴニョして照合するそう。

これについてはその3で触れられたらなあと思っております。