CSRF攻撃に対して無数の防御策があることを知っています。ただし、CSRFは厳密にはブラウザの脆弱性であり、ブラウザ以外からのリクエストはすべて「自動的」に(そして正しく)通過を許可されます。
しかし...ブラウザからのリクエストかどうかはどうやってわかりますか?私の知る限り、唯一の方法は ser-agent header を調べることです。
これはすべて順調ですが、OriginヘッダーやRefererヘッダーとは異なり、user-agentヘッダーは プログラムで変更 にすることができます。
注:User-Agentヘッダーは仕様に従って禁止されなくなりました。禁止されたヘッダー名のリストを参照してください(これはFirefox 43で実装されました)。XHRsetRequestHeader()などを介してFetch Headersオブジェクトに設定できるようになりました。
おっと。
リクエストがブラウザからのものかどうかを判断する他の方法はありますか?または、CSRF攻撃を防御するために、ブラウザ以外のすべてのリクエストもブロックする運命にあるのでしょうか?
ブラウザ以外のリクエストをブロックする必要はありません。
理由? Csrfは、ブラウザを使用するユーザーへの攻撃です。悪意のあるサイトと同時にサイトにアクセスする必要があります。
ブラウザがない場合、攻撃はありません。したがって、ブラウザ以外を通過させます。
更新:変更後 Andersのコメント ユーザーに基づく状態変更要求をすでに許可しているWebサイトに関する質問であることがわかりましたエージェント。 彼の答え を参照してください。これに関して状況をうまくまとめています。
私の新しい答え:
最高のアプローチは、機密機能にブラウザベースの認証メカニズムを使用することではありません。ブラウザーの外部でアクセスするものについては、リクエスト内のヘッダーとして送信されるAPIキーを使用してアクセスを強制します。 APIを使用する自動システムでは、ユーザー名とパスワードを使用してセッショントークンを取得するのではなく、すべてのリクエストに添付できる強力なキーが必要です。
このように、ユーザーエージェントが何であるかは問題ではありません。ユーザーがヘッダーで送信されたAPIキーを使用して自分自身を認証しているという事実によって、非ブラウザーを識別します。
私があなたを正しく読んだ場合、サイトhttp://completely.not.evil.com
に次のようなスクリプトが埋め込まれているシナリオを検討しています:
var req = new XMLHttpRequest();
req.setRequestHeader("User-Agent", "Totally not a browser");
req.open("POST", "http://example.com/delete_account");
req.send();
この攻撃は失敗します。他のすべての回答はCSRFについて有効なことを述べていますが、攻撃者が被害者のブラウザをだまして、変更されたユーザーエージェントでリクエストを送信できない理由を説明するパズルの欠けている部分については言及していません。そして、そのピースは [〜#〜] cors [〜#〜] です。
User-Agent
ヘッダーを設定すると、ブラウザーはプリフライトOPTIONS
リクエストをサーバーに送信して、これが許可されているかどうかを確認します。これを許可するようにサーバーを特別に構成しない限り-これは足元で自分を撃ちます-積極的に応答しません。その後、ブラウザは、実際に悪意のあるアクションを実行するPOSTリクエストを送信しません。
したがって、結論として、攻撃者が許可しない限り、攻撃者はUser-Agent
ヘッダーを正常に変更できません。
CSRF攻撃の例は、なぜそれがブラウザーベースの攻撃であり、クライアントがブラウザーを使用しているかどうかを検出する必要がない理由を理解するのに役立つと思います。
あなたがwww.example.comのWebサイトのユーザーで、www.example.com/delete_accountにつながるリンクをクリックすると、アカウントを削除できるとしましょう。そのリンクをクリックするとどうなりますか?ブラウザはそのリソース(/ delete_account)へのHTTPリクエストを生成し、そのサイトのすべてのCookieをそのリクエストに含めます。したがって、サーバーは、含まれているCookieに基づいて、それがあなたであり、あなたがあなたのアカウントを削除したいことを認識します。
問題は、誰かが悪意のあるページを作成し、src属性がwww.example.com/delete_accountを指すiframeを含める可能性があることです。その悪質なサイトにアクセスし、www.example.comにログインしている場合、ブラウザーはwww.example.com/delete_accountにリクエストを送信してiframeをレンダリングしようとし、そのリクエストにCookieも含めます。そのため、CSRF保護がない場合、example.comで実際にアカウントが削除されます。
これは、たとえば、ユーザーが送信するCookieのみに基づいてユーザーのアクションを信頼する場合にCSRFが発生することを意味します。問題は、ブラウザーがCookieを自動的に送信することです。そのため、CSRF保護が重要です。
ブラウザ以外を使用してwww.example.com/delete_accountに同じリクエストを実行してもらえますか?それは実際には意味がありません。リクエストをBurpにコピーアンドペーストするように説得することもできます。さらに、Cookieを手動でリクエストにコピーアンドペーストする必要があります...実際には意味がありません:)理解するための最良の方法は、保護は機能しますが、攻撃がどのように機能するかを考えます。
簡単に言えば、CSRFと非ブラウザーについて心配する必要はありません。
CSRF攻撃を成功させるには、WebサイトがクライアントからすべてのヘッダーとCookieを含むリクエストを受信し、サイトまたはサードパーティがリクエストを行ったかどうかを認識できないようにする必要があります。
ブラウザ以外のユーザーがユーザーを攻撃するには、サイトが使用するすべてのCookieとヘッダーを推測(または所有)し、ユーザーが接続しているかのようにすべてのセッション情報を渡す必要があります。
ユーザーエージェントがめちゃくちゃになることを心配する必要はありません。
CSRF攻撃に関与する偽造された要求は、攻撃者によって発行されません。それらは正当なユーザーのブラウザによって発行されます。それが肝心なのです。ハッカーが正当なユーザーの正当なセッションをハイジャックしています(そのため、攻撃は セッションライディング と呼ばれることもあります)。攻撃者は、どういうわけか(たとえば、リンクをクリックするか、注意深く作成された電子メールを開くことによって)要求を送信するようにユーザーを説得しました。彼は実際にはトラフィックやネットワーク接続にまったく関与していません。
攻撃者がユーザーエージェントヘッダーを偽造してリクエストを送信するという考えは、このシナリオにはまったく当てはまりません。確かに、ハッカーが選択したハッキングツールを使用して、ハッカーが直接発行できる他の攻撃もありますが、これらの攻撃はいずれもCSRFではありません 定義により 。