クロスサイトリクエストフォージェリ(CSRF)[トークン]

2016年2月3日

PHP

クロスサイトリクエストフォージェリ(以下CSRF)とは、攻撃者があるウェブページを作り、そこに訪れた第三者に対して罠をしかけたリンクを踏ませ、知らないうちに別のサイトへ書き込みを行わせるといった攻撃法です。つまり、サイトをまたがって(クロス・サイト)、偽物(forgery)のリクエストを送るという手法です。

 

パソコン遠隔操作事件では、このCSRFの罠にはめられた被害者が、知らぬうちに横浜市の公式ページに書き込みを行っていたという被害が出ています。

 

 

スポンサーリンク

 

 

CSRFの対策は、送信されてきたデータが、正規のフォーム画面からのデータなのかを判定することによって行います。

 

今回は、セッションIDをハッシュ化したトークン(固定トークン)を利用することによる判定を行います。

 

仕組み


 

まずユーザがフォーム画面にアクセスしてきたら、サーバ側でセッションIDを元にして作成したトークンを発行します。それと同時にそのトークンをフォームのhiddenに埋め込みます。データを受け取った際にhiddenのトークンとサーバ上のトークンを比べて、もし一致していなければ、サーバ外のフォームから送信されたデータと判定できます。

 

CSRF

 

1. ユーザがフォーム画面にアクセスしてきたらサーバ側でトークンを発行します。トークンはセッションIDをハッシュ関数に通してハッシュ値として生成します。

 

2. トークンをhiddenに埋め込みます。

 

3. データを受け取ったら、サーバ側のトークンを比べます。もし一致していなければ送信されたhiddenのトークンは、サーバ上のフォーム画面からの送信でないと判定できます。

 

実際に簡単なデモ画面を作成したのでご参照下さい。はじめのページ(csrf1.php)を開くとサーバ上でトークンが生成されます。送信ボタンをクリックすると次ページ(csrf2.php)へと遷移し、トークンが一致している様子を見ることができます。

 

デモ画面

 

csrf1.php

 

7行目・21行目

セッションID( session_id() )の値を、ハッシュ関数sha1でハッシュ化しています。この値をトークン(token)としています。

 

 

csrf2.php

 

次にcsrf1.phpのフォームの部分を以下のように変えて、ご自身のPHPの環境にてブラウザを開き、送信してみて下さい。ご自身の環境のトークンと、action先のURL上のトークンは一致しないはずです。このようにして、偽物(forgery)のリクエストかどうかを判定することができます。

 

csrf1_forgery.phpのフォーム部分

 

トークンの生成方法については以下サイトもご参照下さい。

CSRF対策のトークンをワンタイムにしたら意図に反して脆弱になった実装例

CSRF対策の実際

 

 

参照文献


 

 

Copyright © 2017 ウェブの葉 All Rights Reserved.  プライバシーポリシー