web-dev-qa-db-ja.com

セッションレス認証システムは安全ですか?

そこで、認証システムを作成しました。あらゆる種類のセキュリティ欠陥のためにそれに注ぎ、それからがらくたをテストしました。私はそれはかなり安全だと思いますが、Web認証システムでは通常ではない、設計上の「異なる」1つの側面があります。

基本的には、各ユーザーのセッションを追跡せずに認証を行えるようにしたかったのです。これは、データベースへの負荷が少なく、スケーリングとキャッシュが簡単であることを意味します。サーバーが保持する「秘密」は次のとおりです。

  • 秘密鍵がアプリケーションのソースコードに保持されている
  • ランダムに生成されたソルトはユーザーごとに保持されます

セッションレスにするが、Cookieを簡単に偽造することは、これが私のCookieの形式です。

_expires=expiretimestamp
secret=hash(privatekey + otherinfo + username + hashedpassword + expires)
username=username
_

otherinfoはIPアドレス、ブラウザ情報などであり、hashedpassword=hash(username + salt + password + privatekey)

私の理解では、ログインCookieを偽造する(パスワードをクラックしない)には以下が必要です。

  1. アプリケーションへのソースコードアクセス、またはアプリケーションをだまして秘密鍵を吐き出す方法
  2. Saltとhashedpasswordを取得するためのデータベースへの読み取り専用アクセス

一方、従来のセッションメソッドには次のものが必要です。

  1. データベースへの書き込みおよび読み取りアクセス(セッションを挿入する、またはWebアプリをだまして実行させる)
  2. 機能によってはソースコードにアクセスできる可能性があります

とにかく、これは誰にとっても過度に安全ではないように見えますか? (ステートレス/セッションレスモデルを維持しながら)それを改善してより安全にする方法はありますか?このステートレスモデルを使用する既存の認証システムはありますか?

また、ハッシュ方法は、SHA256からBlowfishまで、基本的に何でもかまいません。

10
Earlz

基本的な概念は新しいものではありません。ユーザーにいくつかの状態を関連付けたいが、その状態を自分で保存したくない場合です。代わりに、をクライアントに(Cookieに)保存します。そのような状態の変更(たとえば、クライアントが最初からCookieを作成するクライアント)から保護したいので、 メッセージ認証コード などの整合性チェックが必要です。ハッシュ関数を使用した構成は、大まかなMACです。 長さ拡張攻撃 のため、通常のハッシュ関数を備えた弱いMACであることが偶然に起こります。

MACが必要な場合は、強力なMACを使用してください。つまり、 [〜#〜] hmac [〜#〜] です。これは標準的で普及しています。

もちろん、(MAC計算用の)秘密鍵の保管は注意が必要です。アプリケーションの「ソースコード」に埋め込まれた何かがファイルとして存在し、(本来)アプリケーションが読み取ることができるため、任意のファイルへの不正な読み取りアクセスを取得するエクスプロイトに対して脆弱になります。ローカル通信プロトコルを介してアプリケーションが動的にMACキーを取得できるように調整することをお勧めします(ただし困難です)(アプリケーションはローカルサーバーに接続し、アプリケーションにのみキーを提供します)。そうすれば、キーはアプリケーションのRAMにのみ存在し、アプリケーションのアクセス権で読み取り可能なファイルとしては存在しません。サーバーが完全にハッキングされた場合、それは絶対的な保護にはなりません。 、まあ、それだけです)しかし、それは実際にはより強いでしょう。

MACedされたデータにハッシュされたパスワードが含まれているようです。これは少し変です。認証としてすでにMACを持っている:MACはCookieデータが本物であることを証明するため、それ以上の認証は必要ありません。

Blowfishはハッシュ関数ではありません。 ブロック暗号 (または 魚の種類 )なので、大幅に変更しない限りハッシュに使用できません。つまり、自家製の暗号化を意味します。良い考えではありません。


クライアントの状態をオフロードしている場合、クライアント自身が知らないはずの状態をオフロードしたい場合があります。つまり、暗号化も必要になる場合があります。暗号化とMACを安全に組み合わせるのは、思ったほど簡単ではありません。 そのためのモード があります。 [〜#〜] eax [〜#〜] をお勧めします。


状態を維持しないと、本質的に リプレイ攻撃 に対して弱くなることに注意してください。それは避けられない。短い有効範囲を使用することで、ダメージを最小限に抑えることができます(たとえば、Cookieは15分以内に期限切れになります)。

14
Thomas Pornin

この提案されたシステムは、認証された状態を維持するために使用されるセッションハンドラーであり、セッショントークンを構築する方法は安全ではありません。

たとえば、SQLインジェクションを使用すると、ほとんどの秘密データをデータベースから読み取ることができます。 MySQLを使用している場合、SQLインジェクションを使用して、設定ファイルからシークレットを読み取るために使用できるload_file()関数を使用してファイルを読み取ることができます。

一般に、システムを構築するときは、ホイールを再発明しないでください。ほぼすべてのWebアプリケーションで必要なため、プラットフォームには安全なセッションハンドラーが付属していると思います。

セッションIDは純粋にランダムな値である必要があり、/ dev/urandomのようなエントロピープールは優れた選択肢です。プラットフォームのセッションハンドラーを使用しているからといって、正しく構成されているとは限りません。 OWASP Session Management Cheat Sheet を読むことをお勧めします。

2
rook

セッションレスにするが、Cookieを簡単に偽造することは、これが私のCookieの形式です。

あなたが説明するのはセッションレスではありません-それは認証状態がサーバーではなくブラウザで保持されるということだけです。

SSLのみのサイトの場合でも、セッションの乗っ取りと修正を検出することをお勧めします(おそらく、認証はセッション管理に直接結び付けられているため、修正のために利用できるエクスプロイトのタイプはより制限されています)。これは、データサーバー側の格納を意味します。

認証は承認なしではあまり役に立ちません(承認がコードに直接組み込まれていることを教えないでください)。これもサーバー側に保持されている情報に依存します。

ハッシュを再生成してすべてのリクエストを確認するか、ハッシュをルックアップテーブルに保存する必要があります。つまり、サーバーでデータを取得します。

次に、何らかのデータ処理がある場合は、トランザクションデータに加えて、CSRF防止が必要です。これは、通常、サーバー側にデータを格納することで実装されます。

従来のWebセッションを使用する場合と比較して、ワークロードをどのように削減したかはわかりません。ユーザー名を単純に含めた場合、有効期限とユーザー名のハッシュ、および有効期限は、はい、従来のWebセッションと同等のIDの証拠を提供するためにCookieの値に依存する可能性がありますが、これは- very制限付きの認証/アクセスモデル。

2
symcbean