http://seclab.stanford.edu/websec/csrf/csrf.pdf は、ほとんどのCSRF保護メカニズムがログインフォームを保護できないことを指摘しています。 https://stackoverflow.com/a/15350123/14731 の説明:
脆弱性は次のように発生します。
- 攻撃者は信頼されたドメインにホストアカウントを作成します
- 攻撃者は、被害者のブラウザでこのホストアカウントの認証情報を使用してログインリクエストを偽造します
- 攻撃者は被害者をだまして、信頼できるサイトを使用させます。ホストアカウントを介してログインしていることに気付かない可能性があります。
- 攻撃者は、ブラウザがホストアカウントでログインしている間、被害者が(意図的または非意図的に)「作成」したデータまたはメタデータにアクセスできるようになります。
この攻撃は Youtubeに対して成功した です。
この論文の執筆者たちは、「Origin」ヘッダーの追加を提案し続けましたが、W3Cメンバーから抵抗を受けました: http://lists.w3.org/Archives/Public/public-web-security/2009Dec /0035.html
現在まで、ChromeとSafariのみが「Origin」ヘッダーを実装しています。IEとFirefoxは実装しておらず、実装するかどうかは明確ではありません。
それを念頭に置いて:ログインフォームへのCSRF攻撃から保護するための最良の方法は何ですか?
[〜#〜] update [〜#〜]:RESTfulソリューションを探しているので、理想的にはサーバー側の状態を保存しないようにしますユーザー。これは、認証されていないユーザーに特に当てはまります。それが不可能な場合は、明らかにこの要件をあきらめます。
匿名ユーザーのCookieとして設定されている安全なトークンを生成しても問題ないが、サーバー側に格納しない場合は、単純に double submit cookies を使用できます。
例えば正当なユーザー:
これは攻撃者が悪用することはできません。次のことが起こるからです。
サイトがHTTPS経由でのみアクセス可能で、正しく Secure Flag を設定している場合でも、攻撃者が潜在的に MiTMなので、このアプローチには注意が必要ですany 被害者から any HTTP Webサイトへの接続(攻撃者がもちろん適切に配置されている場合)、HTTP経由でドメインにリダイレクトします。これもMiTMです。次に、必要なCookie値を設定します。これは Session Fixation 攻撃になります。これを防ぐには、すでに設定されているCookie値を再利用するのではなく、Cookie値をヘッダーと非表示のフォームフィールド every にこの(ログイン)ページが読み込まれるたびに(HTTPS経由で)出力します。 。これは、ブラウザがセキュアフラグを設定できても、HTTPS接続を介してセキュアフラグなしでCookieを送信し、サーバーがセキュアフラグが設定されたかどうかを通知できないためです。 (Secure FlagなどのCookie属性は、Cookieが設定されている場合にのみ表示され、読み取られた場合には表示されません。サーバーが確認できるのはCookieの名前と値だけです。)実装 [〜#〜] hsts [〜#〜] は、サポートされているブラウザーでの保護に適したオプションです。
X-Frame-Options を設定して、UIによるクリックジャッキング攻撃を防止することをお勧めします(そうしないと、攻撃者はサイトの機能を使用して、ユーザー名とパスワードを事前に入力し、ユーザーがクリックして送信するのを待つ可能性があります。 CSRF値で)。
匿名ユーザーにCookieを設定したくない場合(サーバー側で追跡されている可能性があるため)、代わりに次の方法を使用できます。マルチステージログインフォーム。
最初の段階は、通常のユーザー名とパスワードの組み合わせです。
フォームが送信されると、別のフォームにリダイレクトされます。このフォームは、特別な中間認証トークンCookieとCSRFトークンによって保護されています。ここでの認証では、第2段階の認証の送信のみが許可されますが、アカウントでの他のアクションは許可されません(完全なログアウトを除く)。これにより、CSRFトークンが関連付けられ、この中間セッションでのみこのユーザーアカウントによって使用されるようになります。
ユーザーがドメインで完全に認証されるのは、トークンCookieとCSRF非表示フォーム値を含むこのフォームが送信されたときだけです。 CSRF攻撃を試みる攻撃者は、CSRFトークンを取得できず、完全なログイン試行は失敗します。
唯一の欠点は、ユーザーがログインを完了するために手動でクリックする必要があることです。 X-Frame-Options を設定して、これがUIのリドレスクリックジャッキング攻撃と組み合わせて使用されないようにすることをお勧めします。 JavaScriptを使用した自動送信は攻撃者にとって有益であり、攻撃が成功する可能性があります。そのため、現時点では、ユーザーが手動でクリックしたことしか確認できません。
これは次のように再生されます。
したがって、少しニッチな要件ですが、有効なCSRFです。春に思い浮かぶこの問題に対処する方法はいくつかあります
次のように機能する 暗号化トークンパターン のバリアントを提案したいと思います。クライアントがCSRF保護を必要とするHTMLページをリクエストすると...
sessionId
cookieの存在を確認します。それが欠落している場合、サーバーは暗号的に強力な疑似乱数値を含む新しいHttpOnly
Cookieを設定します。この値はサーバーには保存されませんが、ログインCSRFから保護されます(攻撃者はログインフォームを通過しないと認証できません)。[sessionId + nonce]
を暗号化し、その値(csrfToken
と呼ぶ)をHTMLファイルに埋め込みます。 csrfToken
が埋め込まれている場所は、リクエストを作成するフォームまたはJavaScript関数がアクセスできる限り、重要ではありません。 nonce
は、秘密鍵へのブルートフォース攻撃を防ぐために使用される暗号的に強力な疑似ランダム値ですが、検証プロセスでは使用されません。csrfToken
を送信します。 JavaScript関数は、csrf-token
という名前のカスタムリクエストヘッダーを使用してcsrfToken
を送信します。csrfToken
を復号化し、その値をsessionId
と比較します。 2つが一致しない場合、サーバーは401 Unauthorized
を返し、認証をトリガーします。シンクロナイザートークンパターンやダブルサブミットCookieなど、標準のCSRF対策を適用できます。前者は、サブドメインによってCookieが上書きされる可能性があるため、通常はより安全です。
シンクロナイザトークンパターンは認証後にのみ機能すると主張しましたが、これは当てはまりません。ユーザーが認証されているかどうかに関係なく、攻撃者はユーザーのトークンにアクセスできません。
もちろん、攻撃者は自分でログインページにアクセスし、有効なCSRF防止トークンを取得できます。しかし、このトークンonlyは攻撃者に有効です。被害者がリクエストを行うと、トークンは被害者のセッションに存在しないため、受け入れられません。実際、セッションは最初のリクエストでは完全に空になります。