web-dev-qa-db-ja.com

パスワードリセットトークンに対するDjangoのアプローチは安全ですか?

私はpassword reset機能をWebアプリケーションに実装しており、 Django に類似した実装の採用を検討しています。

簡単に言えば、Djangoは、タイムスタンプとタイムスタンプのハッシュ、およびユーザーIDで構成されるトークンを作成します。このハッシュはHMACであり、タイムスタンプもユーザーIDが改ざんされています。

タイムスタンプに加えて、パスワードソルトなどのユーザーに関する情報がハッシュされます。このようにして、ユーザーがパスワードを変更すると、トークンが無効になり、攻撃者の機会が減ります。

トークンジェネレーターのソースコードは表示できます here とここに擬似コードがあります:

function make_token(user)
  timestamp = current timestamp (now)
  value =  timestamp + user.id + user.password
  hash = create_hmac("some secret", value)
  return timestamp + ":" + hash

function check_token(user, token)
  timestamp = token.split(":")[0]
  hash = token.split(":")[1]

  if timestamp is after expiration date
    return false

  value =  timestamp + user.id + user.password
  comparate = create_hmac("some secret", value)

  // if the hash has changed, the token has been tampered with or the user has 
  // changed their password. 
  if hash != comparate
    return false

  return true

これは私にとって良い解決策のようです。 Django=を実行しているWebサイトは、2008年以降これを行っており、脆弱性の報告を見つけることができません。

私はいくつかの調査を行い、 Hacker News の誰かがこのアプローチを好きではありませんでした。この件については、懸念を表明する チケット もいくつかあります。しかし、これが安全でない可能性がある理由について、私はまだ特定の理由を見つけていません。

これはパスワードリセットトークンを生成する安全な方法ですか?そうでない場合、なぜですか?

6
Angular noob

「Xは安全である」という質問と同様に、答えはある程度、「セキュリティの観点からの正確な要件、直面する脅威、アプリケーションの種類、および展開する環境に依存します」

ただし、注意点はありますが、上記で概説したスキームは、セキュリティの観点からは比較的妥当に聞こえ、以前に見た多くのパスワードリセット機能よりも明らかに優れています。

あなたがリンクしたバグレポートは非​​常に特定のシナリオを示しています(攻撃者はサーバー側のコードと構成の特定のセクションへの読み取りアクセス権を持っていますが、他のアクセス権は持っていません)リスクを表すのは本当に(私にとって)わずかなものですユーザーがそのアクセス権を持っているかのように、ユーザーに偽のパスワードリセットリンクの生成を開始する前に攻撃する可能性のある他のものがあります。

HNスレッドからのコメントはより一般的なものであり、コメントで説明する標準的なアプローチを回避するスキームに対するトーマスの一般的な不信を超えて、このスキームに対する特定の脅威を説明しているようには見えません。彼の論点は妥当ですが、Djangoスキームが破られていると言っているのではなく、トレードオフが関係しているということです。

3
Rory McCune