10

CSRF から保護するには、フォームの非表示フィールド、Cookie、またはセッション変数にノンスを配置する必要があります。しかし、ユーザーが異なるタブで複数のページを開いた場合はどうなるでしょうか? この場合、各タブには一意の nonce を持つフォームがありますが、セッション変数または Cookie に保存される nonce は 1 つだけです。または、すべての nonce を cookie/session 変数に格納しようとすると、どれがどのフォームに属しているかをどのように識別しますか?

4

4 に答える 4

7

各フォームに同じ nonce を格納できます。これを行う最も簡単な方法は、ノンスをセッション ID に関連付けて、これらのフォームがそのセッションでのみ機能するようにすることです。

攻撃者がセッション ID を盗んで独自の nonce を作成するのを困難にする必要があります。そのため、HMAC-SHA256 (など) を使用してセッション ID をハッシュし、公開しないキーを使用する方法があります。

(明らかに、攻撃者が実際のセッション ID 自体を取得できる場合、彼らはすでにセッション ハイジャックを実行できます。つまり、それは私が話していることではなく、攻撃者が (被害者のコンピューターで実行される) スクリプトを作成する能力です。何らかの方法でセッション ID を取得し、それを使用してノンスが事前に入力された URL を動的に生成できます)。


ETA: 上記のアプローチだけで十分かどうかは、通常のセッションがどれくらい続くと予想されるかによって異なります。ユーザーが通常、数時間以上にわたる長時間のセッションを使用する場合は、より洗練されたものを使用する必要があります。

1 つの方法は、フォームごとに新しい nonce を作成することです。これには、タイムスタンプと、hash(timestamp . sessionid)(hash偽造を防ぐための上記の HMAC の変形であり、.文字列の連結があります) が含まれます。次に、次の方法で nonce を確認します。

  1. タイムスタンプをチェックして、ナンスが十分に新しいことを確認します (これはポリシー次第ですが、通常は数時間かかります)
  2. 次に、タイムスタンプとセッション ID に基づいてハッシュを計算し、ナンスと比較して、ナンスが本物であることを確認します。

nonce チェックが失敗した場合は、ユーザーの送信内容が事前に入力された新しいフォームを表示する必要があります (投稿を書くのに丸一日かかったとしても、彼らの努力が無駄にならないようにするためです)。新鮮なナンスとして。その後、ユーザーはすぐに正常に再送信できます。

于 2010-02-12T07:43:48.133 に答える
3

フォームごとにトークンを生成する人もいますが、これは非常に安全なアプローチです。ただし、これによりアプリが破損し、ユーザーを怒らせる可能性があります。サイトに対するすべての XSRF を防ぐには、セッションごとに一意の 1 つのトークン変数が必要です。攻撃者は、この 1 つのトークンを見つけられない限り、リクエストを偽造することはできません。このアプローチの小さな問題は、被害者が攻撃者が制御する Web サイトにアクセスしている限り、攻撃者がこのトークンをブルート フォースできることです。ただし、トークンが 32 バイト程度のようにかなり大きい場合、ブルート フォースには何年もかかり、http セッションはそれよりずっと前に期限切れになるはずです。

于 2010-02-12T20:04:03.870 に答える
0

この投稿はかなり前に書かれました。ほぼ確実に保護できるcsrfブロッカーを実装しました。複数の開いているウィンドウで機能しますが、提供される保護の種類をまだ評価しています. DB アプローチを使用します。つまり、セッションの代わりにテーブルに保存します。注: この場合、簡単なアンチ SQL メカニズムとして MD5 を使用します。

疑似コード:

形:

token = randomstring #to be used in form hidden input
db->insert into csrf (token, user_id) values (md5(token),md5(cookie(user_id))

-- トークンは、以下のアクション スクリプトからアクセスされるまでデータベースに保持されます。

アクション スクリプト:

if md5(post(token)) belongs to md5(cookie(user_id)) 
    #discard the token
    db -> delete from csrf where token=md5(post(token)) and user_id=md5(cookie(user_id)) 
    do the rest of the stuff
于 2013-09-10T22:42:50.253 に答える