クロスサイトリクエストフォージェリ(CSRF)は通常、次のいずれかの方法で防止されます。
- リファラーを確認してください-RESTfulですが信頼性がありません
- フォームにトークンを挿入し、サーバーセッションにトークンを保存します-実際にはRESTfulではありません
- 不可解なワンタイムURI-トークンと同じ理由でRESTfulではありません
- このリクエストのパスワードを手動で送信します(HTTP認証で使用されるキャッシュされたパスワードではありません)-RESTfulですが便利ではありません
私の考えは、ユーザーシークレット、不可解であるが静的なフォームID、およびJavaScriptを使用してトークンを生成することです。
<form method="POST" action="/someresource" id="7099879082361234103">
<input type="hidden" name="token" value="generateToken(...)">
...
</form>
GET /usersecret/john_doe認証されたユーザーからJavaScriptによってフェッチされます。- 応答:
OK 89070135420357234586534346この秘密は概念的には静的ですが、セキュリティを向上させるために毎日/時間ごとに変更できます。これが唯一の機密事項です。 - JavaScriptを使用して不可解な(ただしすべてのユーザーにとって静的です!)フォームIDを読み取り、ユーザーシークレットと一緒に処理します。
generateToken(7099879082361234103, 89070135420357234586534346) - 生成されたトークンと一緒にフォームをサーバーに送信します。
- サーバーはユーザーシークレットとフォームIDを認識しているため、両方の結果を送信して比較する前に、クライアントが実行したのと同じgenerateToken関数を実行できます。両方の値が等しい場合にのみ、アクションが許可されます。
JavaScriptなしでは機能しないという事実にもかかわらず、このアプローチに何か問題がありますか?
補遺: