49

これは CSRF トークンの生成に関する質問です。

通常、ユーザーのセッションに関連付けられた一意のデータに基づいてトークンを生成し、秘密鍵でハッシュおよびソルト化したいと考えています。

私の質問は、使用する一意のユーザー データがない場合のトークンの生成に関するものです。セッションは利用できません。Cookie はオプションではありません。IP アドレスとその性質のものは信頼できません。

ハッシュする文字列をリクエストの一部として含めることができない理由はありますか? トークンを生成して埋め込む疑似コードの例:

var $stringToHash = random()
var $csrfToken = hash($stringToHash + $mySecretKey)
<a href="http://foo.com?csrfToken={$csrfToken}&key={$stringToHash}">click me</a>

CSRF トークンのサーバー側検証の例

var $stringToHash = request.get('key')
var $isValidToken = hash($stringToHash + $mySecrtKey) == request.get('csrfToken')

ハッシュで使用される文字列は、リクエストごとに異なります。それが各リクエストに含まれている限り、CSRF トークンの検証は続行できます。リクエストごとに新しく、ページにのみ埋め込まれているため、トークンへの外部アクセスは利用できません。トークンのセキュリティは、私だけが知っている $mySecretKey に委ねられます。

これは素朴なアプローチですか?これが機能しない理由がありませんか?

ありがとう

4

9 に答える 9

29

ハッシュする文字列をリクエストの一部として含めることができない理由はありますか?

CSRF トークンには 2 つの部分があります。フォームに埋め込まれたトークン、および対応するトークンは、セッションまたは他の場所に保存された Cookie に含まれます。このように他の場所を使用すると、ページが自己完結することがなくなります。

リクエストにハッシュする文字列を含める場合、リクエストは自己完結型であるため、攻撃者はトークンの両方の部分を持っているため、フォームをコピーするだけで十分であり、したがって保護はありません。

フォームの URL に入れても自己完結型であることを意味し、攻撃者はフォームと送信 URL をコピーするだけです。

于 2009-12-04T09:14:55.307 に答える
8

試してみてくださいbase64_encode(openssl_random_pseudo_bytes(16))https://github.com/codeguy/php-the-right-way/issues/272#issuecomment-18688498 https://gist.github.com/mikaelz/5668195フォームの例に使用しました

于 2013-05-31T10:12:52.720 に答える
2

HMACに基づいてハッシュを作成する、つまり、ユーザー名+ユーザーID+タイムスタンプの順序でパスワードを暗号化してハッシュを作成するのが最善の方法だと思います。ハッシュを要求するたびに異なる必要があります。攻撃時にハッシュを単純に再生したくない場合は、タイムスタンプを指定する必要があります。

于 2012-03-27T12:30:19.243 に答える
2

CSRF トークンは、通常 POST 要求で適用される (意図しない) データ変更を防止することを目的としています。

したがって、データを変更するリクエスト (GET または POST リクエスト) ごとに CSRF トークンを含める必要があります。

私の質問は、使用する一意のユーザー データがない場合のトークンの生成に関するものです。セッションは利用できません。Cookie はオプションではありません。IP アドレスとその性質のものは信頼できません。

次に、訪問者ごとに一意のユーザー ID を作成します。その ID を Cookie または URL に含めます (Cookie が無効になっている場合)。

編集:

次のイベントを検討してください。

Facebook アカウントにログインしてから、任意の Web サイトにアクセスしました。

その Web サイトには、送信するフォームがあり、ブラウザに Facebook アカウントに POST リクエストを送信するよう指示します。

その POST リクエストによって、パスワードが変更されたり、コメントなどが追加されたりする可能性があります。これは、Facebook アプリケーションがあなたを登録済みでログインしているユーザーとして認識したためです。(CAPTCHA のような別のブロック メカニズムがない限り)

于 2009-11-26T22:06:42.987 に答える
1

URL/フォームと Cookie で同じ「トークン」が必要なだけです。これは、ページで JavaScript によってトークン Cookie を任意の値 (できればランダムな値) に設定し、サーバーに送信されるすべての要求でまったく同じ値を渡すことができることを意味します (URI ?param または form-分野)。サーバーで Cookie を生成する必要はありません。

これは、あるドメインのページが他のドメインの Cookie を編集/読み取りすることをブラウザが許可しないと信頼できる限り安全であり、今日では非常に安全であると考えられています。

サーバーにトークンを生成させることは、このトークンが CSRF の試みによって取得されることなくブラウザに安全に送信できることを前提としています (なぜ危険を冒す必要があるのでしょうか?)。サーバーで生成されたトークンにさらにロジックを入れることはできますが、CSRF を防ぐために必要はありません。

(ここで間違っていたら教えてください)

于 2010-03-04T23:00:59.897 に答える
0

CSRF はユーザーのセッションを利用するため、セッションがない場合は CSRF はありません。

于 2009-12-04T09:10:56.190 に答える