前回は、
CSRF(クロスサイトリクエストフォージェリ)
CSRFはどのように引き起こされるのか
CSRFとは、
たとえば、
<form method="POST" action="/board">
<label for="username">お名前</label>
<input type="text" id="username" name="username">
<label for="message">メッセージ</label>
<textarea id="message" name="message"></textarea>
<input type="submit" value="書き込み">
</form>
このフォームを用いて、
POST /board HTTP/1.1 Host: example.jp Content-Type: application/x-www-form-urlencoded username=田中&message=こんにちは。
本来は、
B0%E4%B8%AD&message=%E3%81%93%E3%82%93%E3%81
%AB%E3%81%A1%E3%81%AF%E3%80%82`のようになりますが、
サーバ側は、
このような掲示板に対して、
<body onload="document.forms[0].submit()">
<form method="POST" action="http://example.jp/board">
<input type="text" name="username" value="名無しさん">
<textarea name="message">これは犯罪の予告です。XX月XX日、YYYにて大規模な犯罪を行います。</textarea>
</form>
</body>
フォーム自体は攻撃者のサイトであるhttp://
攻撃者は、
ユーザーがうっかりこのURLをクリックして攻撃者の用意した罠サイトを訪問すると、
POST http://example.jp/board HTTP/1.1 Host: example.jp Content-Type: application/x-www-form-urlencoded username=名無しさん&message=これは犯罪の予告です。XX月XX日、YYYにて大規模な犯罪を行います。
掲示板への書き込みのリクエストは、
このように、
ログインを利用してメールアドレスを強制的に変更してしまう仕組み
では次に、
たとえば、
<form method="POST" action="/changeaddr">
<label for="email">メールアドレス</label>
<input type="email" id="email" name="email" value="yourmail@example.jp">
<input type="submit" value="メールアドレスを変更する">
</form>
このフォームを用いて、
POST /changeaddr HTTP/1.1 Host: example.jp Cookie: sessionid=25283FB24C9DEE32 Content-Type: application/x-www-form-urlencoded email=newaddr@example.jp
すでにWebアプリケーションにはログイン済みであるため、
サーバ側は、
このような設定画面を持つWebアプリケーションに対して、
<body onload="document.forms[ 0 ].submit()">
<form method="POST" action="http://example.jp/changeaddr">
<input type="email" name="email" value="hijack@attacker.example.com">
</form>
</body>
攻撃者はこのような罠ページを用意したのち、
すでにログイン済みのユーザーがこのURLを訪問すると、
POST http://example.jp/changeaddr HTTP/1.1 Host: example.jp Cookie: sessionid=25283FB24C9DEE32 Content-Type: application/x-www-form-urlencoded email=hijack@attacker.example.com
ユーザー自身はWebアプリケーションにすでにログイン済みですので、
このように、
CSRFへの対策
CSRFへの対策としては、
- フォーム内にhiddenを用いてトークンを埋め込む
- サーバ側でリクエストを受け取ったときに、
そのトークンを確認する
という方法がもっとも広く使われています。たとえば以下の例では、
<form method="POST" action="/changeaddr">
<label for="email">メールアドレス</label>
<input type="email" id="email" name="email" value="yourmail@example.jp">
<input type="hidden" name="token" value="C2A8DDEF926432BD">
<input type="submit" value="メールアドレスを変更する">
</form>
<form>
サーバ側では、
トークンを利用する方法以外にも、
オープンリダイレクト
オープンリダイレクトはどのように引き起こされるのか
Webアプリケーション内に、
たとえば、
GET /go?url=/next.html Host: example. jp HTTP/ 1. 1 302 Moved Temporarily Location: /next. html Content-Length: 0
このような同一サイト内でのほかのページへのリダイレクトを想定して作られている機能において、
GET /go?url=http://attacker.example.com/evil.html Host: example.jp HTTP/1.1 302 Moved Temporarily Location: http://attacker.example.com/evil.html Content-Length: 0
オープンリダイレクトによって、
オープンリダイレクトへの対策
オープンリダイレクトへの対策としては、
$targets = array(
'next' => '/next.html',
'login' => '/login.html'
);
$nexturl = $_GET['url'];
if (isset($targets[$nexturl])) {
header('Locatoin: ' . $targets[$nexturl]);
}else{
header('Locatoin: /');
}
このPHPのコードでは、
- http://
example. jp/ go?url=nextというURLにアクセスされたときは、 http:// example. jp/ next. htmlへ - http://
example. jp/ go?url=loginというURLにアクセスされたときは、 http:// example. jp/ login. htmlへ - それ以外の場合は、
http:// example. jp/へ
とリダイレクトされることになり、
クリックジャッキング
クリックジャッキングはどのように引き起こされるのか
クリックジャッキングとは、
罠サイトでは、

クリックジャッキングへの対策
Webアプリケーションとしてクリックジャッキングへの対策を行うには、
X-Frame-Optionsでは、
- X-Frame-Options: DENY
- →該当ページのframeやiframeへの埋め込みを一切禁止する
- X-Frame-Options: SAMEORIGIN
- →該当ページのframeやiframeへの埋め込みは、
同一オリジンからの場合のみ許可される - X-Frame-Options: ALLOW-FROM http://
example. com - →該当ページのframeやiframeへの埋め込みは、
指定されたオリジンからの場合のみ許可される
DENYを指定した場合には、
Webセキュリティのおさらい まとめ
本連載の第1回から第3回までで、
CSRFやクリックジャッキングなどは、
このような問題についてもWebアプリケーション側で対策が迫られるのは、