0

セキュリティ上の目的で、セキュリティ トークンをコメント フォームの非表示の入力フィールドとして使用したいと考えています。自分の Web ページにフォームが 1 つしかない場合は、そのようなことを行うことができます。

$token = sha1(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;

このトークンをフォームで使用できます

<form action="comment.php" method="post">
<input type="hidden" name="token" value="<?php echo $token; ?>" />
<input type="text" name="comment_body" value="" />
</form>

受信側では、私はそれを行うことができます

if ($_POST['token'] == $_SESSION['token']){ 

   /* Valid Token */

}

しかし、1ページに約10個のフォームがあるので、複数のトークンを生成する方法と、受信側でそれらを処理する方法. ユーザーが複数のページを開いた場合はどうなりますか?

4

2 に答える 2

0

CSRF を防ぐには、単一のセッション依存トークンで十分です

ただし、フォームごとに異なるトークンを使用する場合は、トークンをフォームの特性 (アクション URL やメソッドなど) に関連付けることができます。次に例を示します。

// issue token
$form = array('method'=>'POST', 'uri'=>'/comment.php');
if (!isset($_SESSION['CSRF_TOKENS']["{$form['method']}:{$form['uri']}"])) {
    $_SESSION['CSRF_TOKENS']["{$form['method']}:{$form['uri']}"] = generate_csrf_token();
}
echo '<form method="'.$form['method'].'" action="'.$form['uri'].'">';
echo '<input type="hidden" name="CSRF_TOKEN" value="'.$_SESSION['CSRF_TOKENS']["{$form['method']}:{$form['uri']}"].'">';


// check token
$form = array('method'=>$_SERVER['REQUEST_METHOD'], 'uri'=>$_SERVER['REQUEST_URI']);
if (isset(${'_'.$form['method']}['CSRF_TOKEN'], $_SESSION['CSRF_TOKENS']["{$form['method']}:{$form['uri']}"]) && ${'_'.$form['method']}['CSRF_TOKEN'] === $_SESSION['CSRF_TOKENS']["{$form['method']}:{$form['uri']}"]) {
    // token valid
} else {
    // token missing or invalid
}

もう 1 つの考えられる解決策は、署名済みの CSRF トークンを使用することです。トークンの有効性をさらに制限したい場合は、指定された例にユーザー ID 以外の追加情報を追加できます。

于 2013-04-28T10:31:21.250 に答える
0

このようなシナリオを扱うときに基本的に使用するmicrotimeとmt_randの組み合わせを使用できます

$tokenLen = 64;

$randomData = mt_rand() . mt_rand() . mt_rand() . mt_rand() . microtime(true) . uniqid(mt_rand(), true);

$token =  substr(hash('sha512', $randomData), 0, $tokenLen);
于 2013-04-28T09:07:37.873 に答える