Webセッション識別子の保護について少し

hapi.jsの作成者であるEran Hammerのブログの記事の翻訳に注目してください。 今回は、セッション識別子の保護に焦点を当てます。







Express Node.jsフレームワークのセッション識別Cookieにハッシュサフィックスが追加される理由について、Githubで質問されました。 いい質問ですね。



しかし、最初に、小さな免責事項:特定のシステムの詳細に精通していない人からの他の安全アドバイスのように、以下に書かれているすべては教育の観点からのみ考慮されるべきです。 セキュリティは複雑で非常に特殊な知識の領域であるため、特定の企業にとって適切なレベルの保護を確保することが重要である場合、専任の情報セキュリティスペシャリストを雇うか、情報保護の専門家のサービスを求めます。



ブルートフォース



ブルートフォース攻撃中、攻撃者は、さまざまな資格情報オプションを使用して繰り返し要求を送信することにより、システムへのアクセスを試みます(徹底的な検索で検索が見つかるまで)。 最も一般的なシナリオは、サービスのユーザーパスワードを選択することです。 これが、語彙を使用せずにパスワードを長く複雑にする必要がある理由です。パスワードを取得するのはより困難です。 正しく設計されたシステムは、誤ったデータ入力のケースを常に追跡し、失敗した試行の数が多すぎる場合、攻撃信号が生成されます。



Web認証に使用される資格情報はパスワードだけではありません。 最も一般的な実装では、セッションCookieがクライアントに割り当てられるデータエントリが成功した後、ログインページが使用されます。 これは「ベアラートークン」として機能します。このトークンを「提示する」ユーザーは、システムによって認証済みユーザーと見なされます。 Cookie識別子を使用すると、各ページでユーザー名とパスワードを入力する必要がなくなります。 ただし、現在、このセッションIDが唯一の認証キーであり、このセッションIDにアクセスできるユーザーは誰でもシステムにアクセスできます。 結局のところ、Cookieは文字列にすぎません。



攻撃セッションIDのコレクションは、ブルートフォース攻撃の一種です。 パスワードを推測する代わりに、攻撃者はセッション識別子を取得します。 攻撃者は、オプションの1つがアクティブセッションの実際の識別子と一致することを期待して、セッション識別子を生成し、それらを使用して要求を送信します。 たとえば、Webアプリケーションで識別子が順番に生成される場合、サイバー犯罪者は自分のセッションの識別子を使用し、それを使用して有効なIDを選択できます(システムの「近傍」値を提供します)。



このような攻撃を防ぐために、セッション推測を非実用的にします。 これは重要なポイントです-非現実的ではなく、不可能ではありません。



不便



まず、セッション識別子が十分に長く、連続して発行されないことを確認する必要があります。 ここでは、パスワードと同様に、識別子が長いほど、ブルートフォースを使用して「有効な」ものを選択することが難しくなります。 そのようなロジックが存在する場合、攻撃者は識別子を推測する必要さえないため、予測可能なアルゴリズムを使用しないで(たとえば、カウンターを使用して)そのようなIDを生成することも重要です-アルゴリズムによってそれらを生成するだけです。 暗号的に安全な乱数ジェネレータを使用して、十分に長いID番号を作成するのが最善の選択肢です。 「十分な長さ」とはどういう意味ですか? 特定のシステムの性質に依存します。 サイズは、セッション識別子を選択するための不適切な努力につながるはずです。



セッションIDの推測を防ぐもう1つの方法は、セッションCookieにハッシュまたは署名を追加してトークンの整合性を構築することです。 Expressでは、セッションの操作を担当するミドルウェアは、セッションIDと何らかの種類のアドオン(「シークレット」)の組み合わせのハッシュを計算することでこれを行います。 この場合、ハッシュを計算するにはシークレットを知る必要があるため、攻撃者はシークレットを推測することなく「有効な」セッション識別子を生成できません(そうでなければ、ハッシュを整理するだけです)。 強力なランダムIDセッションの場合のように、ハッシュサイズは特定のアプリケーションのセキュリティ要件を満たす必要があります。 セッションCookieは、ユーザーが取得できる単なる文字列であることを忘れないでください。



セッション識別子は十分に長く、選択を単に非営利で非実用的にする必要があります。 これはいくつかの方法で実現できます-上記のハッシュをランダムに生成して使用することに加えて、他の方法があります。



保護レベル



システムで強力なランダムセッションIDが生成された場合でも、ハッシュが必要ですか? もちろん!



重要な安全原則は階層化です。 また、「すべての卵を1つのバスケットに入れない」という原則とも呼ばれます。 セキュリティのソースが1つだけに依存している場合、それがクラックされる可能性がある場合、セキュリティはまったくありません。 たとえば、使用されている乱数ジェネレーターでエラーが見つかった場合はどうなりますか? システムのこの部分をクラックして変更した場合はどうなりますか? 歴史は成功した攻撃の多くの例を知っており、その組織者はまさにそれを行いました-乱数を生成しましたが、実際にはそれほどランダムではありませんでした( このような脆弱性については1回または2回書きました )。



ハッシュを使用して整合性を確保する強力なランダムセッション識別子の組み合わせにより、乱数ジェネレーターの動作の問題から保護されます。 また、この方法は、ソフトウェアの開発中に発生したエラーから保護します(たとえば、間違ったジェネレーター機能を使用する-ほとんどすべてのシステムに、多少なりとも保護されたメソッドがあります)。 デバッグプロセスや開発者の経験に関係なく、何らかの方法で不良コードを記述します。 これは職業の一部です。 これが、異なるレベルのセキュリティを構築することが重要である理由です。 堀は十分ではなく、背後に壁も必要です。おそらく警備員を置く価値があります。



OpenSSLパッケージで間違った乱数ジェネレーター関数またはバグを使用することを考慮する必要があると思う場合は、 monkey patchの概念を考慮してください。 アプリケーションの展開手順のいずれかで誰かがグローバルランダムエンティティ(テスト、ログ記録など)で何かを行い、それらを(偶然または意図的に)破壊した場合、ランダム性のみに基づく保護、ただ存在しなくなります



問題アラート



パスワードとセッションIDの選択における重要な違いは、パスワードがアカウント(ユーザー名など)に関連付けられていることです。 ユーザー名とパスワードの組み合わせにより、ブルートフォース攻撃の追跡が容易になります。特定のアカウントのパスワードを何度も間違って入力したことが簡単にわかります。 ただし、セッション識別子に関しては、物事はそれほど単純ではありません。セッションには有効期限があり、ユーザー名などの追加のコンテキストはありません。 これは、有効期限が切れた場合や攻撃中に識別子が「無効」になる可能性があることを意味します。 ただし、追加のデータ(IPアドレスなど)がなければ、実際に何が起こっているのかを理解するのはかなり困難です。



整合性コンポーネントをセッションID(署名またはハッシュ)に追加することにより、サーバーは、期限切れのセッション、無効な識別子、および生成されていない識別子をすぐに区別できます。 誤った認証試行の単純なロギングが実行された場合でも(これを実行する必要があります)、この場合でも、期限切れのセッションと無効なセッションを分離する必要があります。 これは、セキュリティの観点だけでなく、ユーザーの行動の分析の観点でも重要です。



安全衛生



認証データには有効期間が必要であるため、セッションIDの有効期間は有限でなければなりません(その特定の長さはシステムの機能によって異なります)。 Cookieには有効期限がありますが、コンプライアンスを検証する方法はありません。 攻撃者はCookieの有効期限パラメーターに任意の値を設定できますが、サーバーはそれを知ることができません。 認証データにはタイムスタンプを使用することをお勧めします。ランダムに生成されたセッションIDにタイムスタンプサフィックスを追加するだけです。 ただし、このようなラベルを完全に信頼するには、誰もラベルを変更していないことを確認する必要があります。 このためには、署名またはハッシュが必要です。



セッションIDにタイムスタンプを追加すると、サーバーは追加の高価なデータベースアクセスを必要とせずに、期限切れのセッションをすばやく処理できます。 一見、セキュリティとは無関係のように思えますが、実際には、安全なアプリケーションを作成するには、そのようなことを考える必要があります。



サービス拒否(DoS)攻撃の場合、攻撃者はサーバーのリソースを最大限に消費するという唯一の目的で繰り返しリクエストを送信し、サーバーがまったくクラッシュするか、クライアントにサービスを提供できないようにします。 要求ごとにアプリケーションデータベース全体を表示する必要がある場合、異なるセッション識別子を送信するだけでDoS攻撃を実行できます。 Cookieに整合性コンポーネントがある場合、サーバーはその前に経過したセッションをすぐに判断できます。または、偽の識別子をスリップすることで「トリック」を試みます。これはすべて、バックエンドにアクセスするための費用を必要としません。



緊急ボタン



時々物事がうまくいかない。 そして、物事が計画通りに進まない場合、セッションのクラス全体を迅速に「無効」にすることができる必要があります。 ハッシュまたは署名の作成にはサーバー側でキーまたは「秘密」が必要なので、そのような秘密を置き換えるとすぐにすべての識別子の検証が失敗します。 さまざまなタイプのセッション識別子にさまざまな秘密コンポーネントを使用すると、セッションのクラス全体を簡単にブロックして、さらに処理を進めることができます。 このようなメカニズムがない場合、アプリケーションは各セッションの状態を個別に決定するか、大規模なデータベース更新を実行する必要があります。



さらに、さまざまな地理的ポイントへのデータベースレプリケーションを備えた大規模な分散システムでは、1つのポイントでセッションを無効化すると、数秒または数分間もレプリケートできます。 つまり、完全な同期が行われるまで、そのようなセッションはアクティブのままになります。 自己署名または自己検証セッションと比較して、利点は明らかです。



汎用



Expressフレームワークの中間セッションソフトウェアの重要な機能は、ユーザー生成セッション識別子のサポートです。 開発者は、既存のエンティティによってセッション識別子が生成される既存の環境にソフトウェアを展開できます。これは、完全に異なるプラットフォームに実装できます。 ユーザーが生成したセッション識別子にハッシュを追加しない場合、ユーザー(セキュリティへの新しいアプローチ)は安全なシステムを構築する責任を負いません。 ハッシュの使用は、内部セッション識別子ジェネレーターを使用するよりもはるかに正確なアプローチです。



ワニが必要ですか



強力なランダムセッションIDにハッシュを追加するだけでは必要ありません。 ワニも水で堀に打ち込む必要があるかどうかは、城によって異なります。 使用できるセッション保護には多くのレベルがあります。 たとえば、認証データの2つのコピーを使用できます。1つは「長命」(セッション自体が存続する限り)、「短命」は数分または数時間アクティブです。 後者を更新するには、存続期間の長いインスタンスを使用しますが、ネットワーク内でのその有病率は低下します(TLSを使用しない場合に便利です)。



別の一般的な方法は、セッションに加えて、ユーザーに関する一般情報(名前、最近表示したアイテムなど)を含むCookieを作成することです。このCookieの1つは後でハッシュに追加されます。これにより、ユーザーのアクティブ状態と認証の間に接続が作成されます。 「ユーザー名」が再びゲームに戻ります。



さらに進んで、ハッシュを電子署名に置き換え、含まれているCookieを暗号化できます(さらに、ハッシュまたは署名)。 セキュリティレベルの数は、考えられる脅威に対応する必要があります。



おわりに



まず、この記事ではセキュリティレベルの概念を取り上げる必要があります。 数学は保護を提供する上で重要ですが、これは使用できる唯一のツールではありません。 統合されたアプローチとさまざまな方法の適用により、真のセキュリティが実現されます。



さらに、安全なシステムの特性をめぐって「学問的討論」を行う誘惑に屈するべきではありません。 たとえば、「強力なランダムセッションIDのハッシュに統計的利点がある」という質問は、これが唯一の考慮事項であるという印象を与えます。 したがって、議論は抽象的な概念の分野で現実世界を離れます。 複雑なブルートフォース攻撃に加えて、ハッシュを使用する多くの理由があります。



All Articles