私は毎日何千もの訪問があり、かなり大規模なサイトを運営しています。MVC 3 に移行し始めてから、保護されたデータなどを変更する多くのフォームに AntiForgeryToken を入れています。
ログインや登録のような他のフォームでもAntiForgeryTokenを使用していますが、いくつかの理由から、そもそもこのフォームが必要なのか怪しくなってきています。
ログインフォームでは、投稿者が正しい認証情報を知っている必要があります。特に、リクエストが同じホストから来たことをチェックする(Refererヘッダをチェックする)のであれば、CSRF攻撃がここで利益を得る方法は思いつきません。
AntiForgeryToken トークンは、ページがロードされるたびに異なる値を生成します。ログインページで2つのタブを開き、それらを投稿しようとすると、最初のものは正常にロードされます。2つ目はAntiForgERYTokenExceptionで失敗します(まず両方のページを読み込んでから投稿を試みます)。よりセキュアなページでは、これは明らかに必要悪である。
トークンをフォームに使うべき理由、使わないべき理由は他にもあるでしょう。もしそうだとしたら、どのようなフォームにトークンを使用するのが効果的で、どのようなフォームにはトークンを使用しない方がよいのでしょうか?
P.S.この質問はStackOverflowでも質問されていますが、私は完全には納得していません。より多くのセキュリティをカバーするために、ここで質問してみようと思いました。
はい、ログインページに偽造防止トークンを含めることは重要です。
なぜか? ログイン CSRF 攻撃の可能性があるからです。 ログイン CSRF 攻撃では、攻撃者は犠牲者を攻撃者のアカウントでターゲットサイトにログインさせます。 例えば、邪悪な攻撃者 Evelyn が Paypal のユーザである Alice を攻撃したとする。 もし Paypal が CSRF 攻撃からログインページを保護していなければ(例えば偽造防止トークン)、攻撃者はアリス のブラウザを黙って Paypal のイヴリンのアカウントにログインさせることができる。 アリスはPaypalのウェブサイトに移動し、アリスはログインしているが、エブリンとしてログインしている。 アリスは自分のクレジットカードをペイパルのアカウントにリンクするページをクリックし、クレジットカード番号を入力したとします。 アリスは自分のクレジットカードをペイパルのアカウントにリンクしているつもりだが、実際はエブリンのアカウントにリンクしている。 これでエブリンは物を買うことができ、アリスのクレジットカードに請求される。 おっと。 これは微妙で少しわかりにくいですが、ログインに使われるフォームアクションのターゲットに偽造防止トークンを含める必要があるほど深刻です。 このような脆弱性の詳細と実例については、この論文を参照してください。
どのような場合にアンチフォージェリトークンを省略してもよいのでしょうか? 一般的に、ターゲットが URL で、その URL にアクセスしても副作用がない場合は、その URL にアンチフォージェリトークンを含める必要はありません。
大まかな経験則としては、すべてのPOSTリクエストにアンチフォージェリトークンを含めるが、GETリクエストには不要である。 しかし、この大まかな経験則は非常に粗い近似値です。 GET リクエストはすべて副作用がないという前提です。 よく設計されたWebアプリケーションでは、うまくいけばそうなるはずですが、実際にはWebアプリケーションの設計者がそのガイドラインに従わず、副作用のあるGETハンドラを実装してしまうことがあります(これは悪い考えですが、珍しいことではありません)。 これが、GET対POSTに基づくのではなく、リクエストがウェブアプリケーションの状態に副作用を与えるかどうかに基づくガイドラインを提案する理由です。