トークンを使用してリクエストが有効かどうかを確認する
データを送信するときに、いつでも何らかのセキュリティ トークンを追加できます。
トークンは、さまざまな用途に簡単に拡張でき、リクエストが有効かどうかを確認する際に広い範囲をカバーできます。たとえば、重要でないフォームを公開して、ユーザーにいくつかのページから秘密鍵を取得するように依頼することができます (それらを強制します)。そのページを開くには)、データを送信するときにこれらのキーを使用してそれらを識別します。
もちろん、これはすべてユーザーに対して完全に透過的です。Cookie (またはセッション Cookie) を介してフロント ページからキーを提供できるためです。ここでは問題ではありません。サーバー キーは使用後に変更され、指定された時間内に無効になる必要があるため、多かれ少なかれセキュリティはありません。ユーザーの ID が変更されたとき)。
この使用例では、フロントページを開いたユーザーのみがサーバーにデータを送信できます。
もう 1 つのケースは、サーバーにデータを送信するためのフォームを含む同じページで Cookie が配布される場合です。ページを開くすべてのユーザーは、すぐにデータを送信するためのキーを持っていますが、誰かが外部からリクエストを行おうとすると失敗します。OWASP クロス サイト リクエスト フォージェリ
と、codinghorror.com のブログ CSRF とあなた
を参照してください。
AJAXだけ?
別の質問に対する私の回答は次のとおりです。この回答では、追加のデータを ajax リクエストに挿入するためのさまざまな方法について説明しています: Liftweb: 従来の方法と AJAX の両方で送信できるフォームを作成します(
$.ajax({
...
data: /* here */
...
現在、私はこのようにトークンを使用しています:
送信に使用するフォーム
この非表示の入力はフォームに追加できますが、前述の別の回答で説明されている方法を使用できるため、必須ではありません。
<input type="hidden" name="formid" value="<?php echo generateFormId(); ?>" />
関数 generateFormId()
ランダムな文字列を生成してセッション ストレージに保存するだけです
function generateFormId() {
// Insert some random string: base64_encode is not really needed here
$_SESSION['FORM_ID'] = 'FormID'.base64_encode( uniqid() );
// If you want longer random string mixed with some other method just add them:
//$_SESSION['FORM_ID'] = 'FormID'.base64_encode( crypt(uniqid()).uniqid('',true) );
return $_SESSION['FORM_ID'];
}
送信されたフォーム データの処理
if (!isset($_SESSION['FORM_ID']) || $_SESSION['FORM_ID'] != $_POST['formid']) {
// You can use these if you want to redirect user back to form, preserving values:
//$_SESSION['RELOAD_POST'] = $_POST;
//$_SESSION['RELOAD_ID'] = uniqid('re');
echo 'Form expired, cannot submit values.';
//echo '<a href="form.php?reload='.$_SESSION['RELOAD_ID'].'">Go back and try again</a>';
exit(1); // <== Stop processing in case of error.
}
データを送信しているフォームを確認する必要がある場合
次に、ID を生成するときにプレフィックスを追加し、フォーム データを処理するときにそのプレフィックスを確認することができます。
これは、1 つの php スクリプトが多くの異なるフォームを処理する場合です。
悪意のあるユーザーを防ぐための唯一の最終的な解決策は、サーバーからすべてのワイヤを引き抜くことであることを忘れないでください...