ユーザーメタデータ/個人を特定できる情報の過剰なログ記録に対して、適切なセキュリティプラクティスのバランスをとろうとしています。
安全なメッセージングを可能にするWebアプリを構築しています。システム設計の一環として、ユーザーメタデータの漏洩を最小限に抑えるようにしています。
システム設計の一部に、サービス拒否やアカウントのクラッキングなどの悪用を防ぐためにIPアドレスを追跡するモジュールが含まれています。 IPアドレスのログは必要な間だけ保持します。簡単な方法は、IPアドレスとタイムスタンプをログファイルに記録し、一定期間後にエントリを削除することです。煩わしさをなくすために、意図的なのは永続的なものではなく、設定された時間(つまり線形オフセット)の間、不正なIPアドレスを禁止することです。
脅威モデルでは、ログを使用して、誰がいつシステムを使用していたかを特定できます。このシステムのユーザーには、サーバーが危険にさらされている場合でも、第三者がシステムを誰がいつ使用したかを推測できるような方法でログが設計されていないことを確信してほしい。
私の最初の考えは、後で検証できる形式で情報を保存するが、プレーンテキストでは保存されないことは、キー導出関数を使用してシステムパスワードを安全に保存する方法(つまり、パスフレーズにハッシュを適用し、多数の反復)。したがって、ユーザーのパスワードをKDFベースのハッシュに対して検証できるのと同じ方法で、ログファイル内のKDFベースのハッシュに対してIPをチェックして、同じIPアドレスが以前に記録されているかどうかを確認できます。
このアプローチの長所と短所は何ですか?ユーザーメタデータ/ PIIをプレーンテキストではなく、Webアプリが確認できる形式で保存するための優れた方法はありますか?
Webアプリの目的と脅威モデルを明確にするために更新されました。
悪用を決定するために、30分間のIPを表示する必要があるとしましょう。これは、IPを1時間以内に保つためのスキームです。
30分ごとに、メモリのみのランダムな文字列RSを生成します。
どの期間でも、現在および以前のRS:rs_c、rs_pを保持します。
すべてのIPについて、現在のランダム文字列を使用して現在のhmacを計算します。
IP_c = HMAC(rs_c, IP)
IPをテーブルに保存します。
IP_c, last-update
過去1時間のIPカウントを計算します。
func get_ip_count(ip):
IP_p = HMAC(rs_p, IP)
IP_c = HMAC(rs_c, IP)
count = [select count(*) from ipHistory where IP in (IP_p, IP_c) and last-update < [30-minutes-ago]]
RSを保護できる限り、スライディングウィンドウ以上のIPを回復することはできません。
最終更新/年齢に基づいてテーブルをクリーンアップします。
delete from ipHistory where last-update < [30-minutes-ago]
簡単な方法は、IPアドレスとタイムスタンプをログファイルに記録し、一定期間後にエントリを削除することです。
簡単ですが、驚くほど非効率的です。本当に違反者のデータは、ログデータとは無関係にindexedストレージに維持する必要があります(おそらく、ログファイルも保持する必要がありますが分離ディスカッション)。
私はあなたが違反者へのあなたのサイトを使用している他の人々に対するほど強い注意義務を感じていないと思いますので、これはパフォーマンスの問題とプライバシーの問題の両方を解決します。
(これは間違いかもしれません。同様の質問の漠然とした記憶がありますが、今はそれが見つからないため、記憶またはsearch-fuに欠陥があるか、削除されています。)
ソルトは、保護された値をパブリック値に関連付けることができる場合にのみ機能します(つまり、パスワードをハッシュするためのソルトは、対応するユーザーIDとともに保存されます)。 IPアドレスとの唯一の明白な一致は、少なくとも機密性が高く、常に1対1であるとは限らないDNS名です。 Pepper(修正済みですがシークレット)は、ログファイルデータを取得するがそれを書き込むアプリを取得しない攻撃者に対しては依然として役立ちます。ただし、固有の制限があります。重複したハッシュを認識できますが、ファイアウォールルールなどで必要な場合にIPアドレスを簡単に戻すことはできません。only自分で作成したアプリでハッシュベースのチェックを行います。
より柔軟な解決策として、確定的なパディングを使用して値を公開鍵encryptすることができます(標準のパディングは、正確には重複を認識しないようにするため)。復号化する必要がある管理アプリにのみ(および一時的に)秘密鍵を提供します-おそらく別の(より安全な)マシンで実行します。
ただし、重複を検出するスキームはすべて、ログファイルおよびを取得する攻撃者によってブルートフォース攻撃を受ける可能性があります。これは、pepperまたはpublickey(またはいずれかを含むアプリ)が原因です。 IPアドレス空間(v4の場合、パブリックネットの99.99%はまだv4です)は32ビットよりやや小さいです。
これは別のアプローチを提示します-機密データを侵害リスクから分離します。 Webサーバーにログファイルを書き込む必要があります。これは一般にアクセス可能であり、通常は脆弱性のリスクを伴うほど複雑である必要があります。ログファイルをファイアウォールで保護された別のマシンに送信して、非常に単純な書き込み専用のログプログラムだけを実行します-おそらく20行厳密にチェックできるコードの数。
編集:コメントの説明、2015/02/24。
ソルト自体はパブリックである必要はありませんが、パブリックデータによって決定される必要があります、および一意確実ではないにしても、少なくとも高い確率でアイテムごとに。正規の例はパスワードハッシュです。通常はランダムなソルトとパスワードのソルトハッシュの両方が、useridによってアクセスされるデータベースに格納されます。塩の全体のポイントは、値によって異なります。秘密であるハッシュに追加された値(あなたの場合はアプリサーバーに対して)ですが、すべてのハッシュ値に対して同じですpepper。私が言ったように、攻撃者がペッパーハッシュを含むがペッパー自体を含まないデータを取得できる場合、これは便利です。
結果をどのように使用できるかについて、公開鍵暗号化を「柔軟」と対比しました。たとえば、フィルタープログラムは、新しい接続などの特定のIPaddrを取得し、(pepperを使用して)ハッシュして、ログに記録されたエントリと一致するかどうかを確認できますが、ログに記録されたエントリまたはいくつかを取得できず、(安価に)決定できますIPaddr(s)。公開鍵暗号化を逆にして、only特定のプログラムまたは(場合によってはリモートの)システムが秘密鍵を与えてIPaddrを表示し、それに応じて保護および制限することができます。