web-dev-qa-db-ja.com

AJAX呼び出しによってフォームが送信されるときのCSRFからの保護

CSRF攻撃を防ぐために、すべてのフォームで反CSRFトークンを使用しています。また、トークンは$ _COOKIE変数に保存され、フォームから取得した値に対して検証されます。フォームが読み込まれるたびにトークンをリセットしています。

しかし、$。post、つまりAJAX=を使用して送信し、JSON応答を取得するために使用しているフォームがいくつかあります。

AJAXが使用されているため)$ _COOKIE変数は設定されていません。

回避策はありますか、それとも何か問題がありますか?

編集:クライアント側とサーバー側のコードサンプルの追加

クライアント側:

<?php
$tokenVal = md5(uniqid(mt_Rand(), true));
setcookie ("token", $tokenVal);
?>
<form action="target.php" method="post" name="abc">
<input type="text" name="city" id="city" value="abc" size="25" maxlength="10">
<input type="hidden" name="csrf" value="<?php echo $tokenVal; ?>">
<a class="cssButton buttonColor right" id="billToSubmit">Save</a>
</form>

サーバ側:

if($_POST['csrf'] == $_COOKIE['token']) {
//process further
} else {
die("Invalid form source")
}

フォームは$ .postを使用して送信されています。私が直面している問題は、$ _ POST ['csrf']が$ _COOKIE ['token']と等しくないことです。

6
Gaurav Sharma

JavaScriptがCSRFトークンを使用できると仮定すると、 setRequestHeader を使用してリクエストトークンを手動で添付し、サーバーを変更してCookieヘッダーでリクエストトークンを探すか、または指定したヘッダーのXHRを介してアクセスできる必要があります。

2
Mike Samuel

ほとんどのJavaScriptフレームワークは、X-Requested-With: AJAXなどのPOSTingリクエスト時に特定のヘッダーを追加します。理論的には、バックエンドでこのヘッダーの存在を確認して、フォームがAJAX=を介して送信されたことを確認することができますAJAX=リクエストは同じドメインからのみ送信できるため、CSRF攻撃から安全である必要があります。

しかし発見されました ブラウザプラグインのいくつかの組み合わせが存在する場合、攻撃者が実際にリクエストを作成することが可能であることカスタムヘッダー付き。これにより、上記のアプローチはそれほど健全ではなくなります。 AJAX送信の場合でも、CSRFトークンをクライアントに渡すことを推奨します。たとえば、非表示フィールドに追加して、JavaScriptで読み取ることができます。

[〜#〜] edit [〜#〜]$_COOKIE$変数がAJAXリクエスト、あなたのポイントは理解できません。実際にCookieをAJAXリクエストで設定できます。通常のCookieでも、http専用でない場合は保持されます。

1
Andrea

これは、攻撃者がCookieの値を知らないため、CSRF保護の有効な形式です。これは、攻撃者がトークンポスト変数に有効な値を持たないためです。この方法では、ユーザーごとの状態は必要ありません。これは利点です。

CSRF防止に関するチートシート は優れたリソースです。

0
rook