暗号化されたデータを使用するWebアプリケーションがあるとします。例えば患者が医師にメモを残すウェブサイト。
患者はログインし、メモを残します。メモは対称暗号化を使用して暗号化され、データベースに挿入されます。ユーザーは、戻ってきた場合でもメモを表示できます。メモは復号化されて表示できます。医師がログインし、患者のメモに行くと、解読されて印刷されます。
しかし、このアプリはSQLインジェクションに対して脆弱です。ハッカーはそれを見つけ、Webアプリケーションでアカウントを開き、ダミーのメモを作成します。次に、SQLインジェクションを使用して、誰か他の人の暗号化されたメモをコピーし、その内容をメモ(表の彼の行)に貼り付けます。彼がそれを表示するためにアプリケーションに戻ると、それは復号化されます。
ハッカーが他の暗号化されたメモを閲覧できないようにするにはどうすればよいですか?
私があなたの質問を正しく理解した場合、システムは同じキーを使用して、患者と医師の両方のメッセージを暗号化および復号化します。
その場合、別のユーザーのメッセージを読み取って自分のメッセージとしてDBに挿入できると想定して、攻撃は理論的に可能です。
これに対する暗号化の緩和策は、ユーザーごとに一意のキーを使用するか、公開キーと秘密キーのペアを使用してデータを暗号化し、違反が発生した場合のセキュリティと損傷を制限するために各ユーザーが一意のキーを使用することです。
他のメカニズムには、入力をサニタイズすることによるSQLインジェクションに対する適切な防御と、登録ユーザーが正当な患者であることを確認するユーザー検証システムが含まれます。これにより、攻撃者のプールが減少しますが、これだけに頼るべきではありません。
ここでの問題は、すべてのノートが同じ暗号化キーで暗号化されることです。これにより、アプリは必要以上に脆弱になります。
代わりにこの設定を検討してください:
これを完璧なシステムの青写真と見なさないでください。これには多くの方法があり、おそらくこれよりも優れた方法があります。しかし、これはデータベースへの読み取りおよび書き込みアクセスのみ(SQLiの場合など)が攻撃者にすべての平文データへのアクセスを即座に許可しないシステムの例です。
編集:すべての医師がすべてのメモを読めるようにしたい場合、状況は少し不安定になります。データベース全体への書き込みアクセス権を持つ人なら誰でも、自分を医者に変えることができます。したがって、doctorsテーブルへの書き込みアクセスをできるだけ制限する必要があります。
Webアプリがそのテーブルへの書き込みアクセスを使用しているDBユーザーに、他のより制限されたシステム(たとえば、一部のイントラネットでのみ利用可能)を使用して新しい医師を作成しないでください。または、doctorテーブルのすべての行が暗号で署名されているか、またはそのようなものである必要があります。またはさらにお読みください Lie Ryans great answer 。
結論:ここでの重要な教訓は、暗号化には、アルゴリズム、メッセージ、およびキーだけではないということです。それは、物事が複雑になるキーの処理方法について考え始めるときであり、コンテキストに大きく依存するソリューションが必要です。
あなたは特定の攻撃に夢中になりすぎていると思います。つまり、ノートテーブルへの完全なCRUDアクセス権を持つSQLログイン(およびそれ以上)が他の医師のノートを読もうとするのではないかと心配しています。
ええ、([AppWideKey] + [DoctorID]のように単純であっても)さまざまなキーを使用して医師のメモを暗号化するとよいでしょうが、「SQLインジェクション攻撃が成功した場合、ハッカーはおそらくAppUserXとしてSQLにログインします。AppUserXによる被害を最小限に抑えるにはどうすればよいですか?」答えは通常、ストアドプロシージャを使用してデータにアクセスし、ストアドプロシージャはアプリのニーズを満たすために最小限の量だけを実行し、ユーザーにテーブルへの直接アクセスを許可しないことです。
各ノートを独自の秘密鍵で暗号化する必要があります。ノートごとに新しい対称鍵を使用する必要があります。この対称鍵はセッション鍵と呼ばれます。
ここで問題は、セッションキーを受信者に、そして受信者にのみ配布する方法になります。これには、公開鍵暗号化が必要です。
システムの各参加者(患者と医師)に自分の個人鍵ペアを発行する必要があります。公開鍵は暗号化せずにサーバーに保存できますが、秘密鍵は暗号化せずにサーバーに保存しないでください。ユーザーのパスワードを使用してサーバー上の秘密鍵を暗号化するか、ユーザーが秘密鍵を安全に保管するようユーザーに要求する必要があります。
患者は、新しいセッションキーを生成し、それを使用してメッセージを暗号化してから、医師の公開キーでセッションキーを暗号化することにより、特定の医師にプライベートメッセージを送信できます。複数の公開鍵に対してセッション鍵を暗号化することにより、複数の受信者にメッセージを送信することもできます。
必要に応じて、参加者の身元を確認し(たとえば、写真IDを要求することにより)、参加者の公開鍵に署名して身元確認が行われたことを表明し、参加者の役割を表明する署名付き属性を添付する認証局が必要になる場合があります。 )。
この時点で、ポイントツーポイント暗号化のメカニズムができました。これらは基本的に、S/MIMEおよびPGPスキームが機能する方法です。
この上にグループメッセージングを構築して、患者や医師がメッセージを大きなグループに送信できるようにすることができます(たとえば、患者は暗号化されたメッセージを歯科医グループに送信できますが、歯科グループはメッセージを読むことができません)。誰もが個々のメンバーのアイデンティティを知る必要はありません。これはマルチキャスト暗号化と呼ばれます。
グループメッセージングを構築する方法は、グループキーペアを作成する必要があることです。グループキーペアは、グループのすべてのメンバーに配布される秘密キーと、グループにメッセージを送信する必要があるすべての人に配布される公開キーで構成されます。これにより、メンバーと非メンバーは、そのグループの全員にのみメッセージを送信できます。グループメッセージを送信するには、そのメッセージのセッションキーをグループの公開キーで暗号化します。
ほとんどの場合、グループのメンバーシップが変更されるたびに新しいグループキーを作成する必要があることに注意してください(たとえば、誰かがグループを退会したり、新しい人がグループに参加したりします)。
あなたが説明する暗号化は、多くのシナリオからあなたを守っていません。 MySQLデータベースが盗まれても暗号化キーは盗まれないように保護します。しかし、データベースはアプリケーションの背後にあるため、通常は最初に壊れ、次にデータベースが壊れるので、実際のシナリオでは、アプリケーションとデータベースの両方のキーが盗まれます。
これからアプリケーションを保護するには、SQLインジェクションを解決する必要があります。これは簡単で簡単です。すべてのアプリケーションがSQLインジェクションに対して回復力があることを確認するのは簡単です。必要なのは、データベースへのすべてのクエリを変更することだけです。準備されたステートメントを使用する方法。
アプリケーションがどれほど大きくて複雑であるか、またはそれが使用している言語とフレームワークの数に関係なく、これは単純な仕事で非常に効果的です。 SQLインジェクションをソートすることは、実行する非常に基本的なことです。
ハッカーがあなたが説明したことをしないように保護する方法は他にもたくさんあります。たとえば、アプリケーションに渡される変数の監査。これは通常WAFと呼ばれるものによって行われます。SQLインジェクション攻撃の検出を処理チェーンの最上位のコードに埋め込むこともできます。
強力なアクセス制御を実施している場合は、患者自身のみがプロファイルに対して新しいメモを作成できるはずです。医師はメモを読んだり、メモにコメントを追加したりできますが、メモを削除または更新することはできません。これにより、元のノートは不変になるはずです。アプリケーションに、ノートテーブルに対する挿入特権を与えますが、更新特権は与えません。これにより、インジェクション攻撃も軽減されます。
医師が有効なセッションに関連付けられたユーザーからのメモのみを見ることができ、SQLiを介して実行された挿入は表示されないように、メモをユーザーセッションに関連付けることもできます。データベースの正規化ジョブはこれらを削除できます。
Webインターフェースを介して追加の権限を持っている可能性のあるユーザー向け。スーパーユーザーの場合、httpd.confなどを使用して、スーパーユーザーリソースへのアクセスを特定のIPアドレス(つまり、本社システム)に制限できます。
パラメーター化されたクエリを使用していますか?これにより、洗練されていないSQLインジェクションが防止されます。
ユーザーごとに1つの一意のキーが必要です。ユーザーはメールアドレスとパスワードでサインアップしますか?パスワードを使用できます。
ユーザーがサインアップするときに各ユーザーのキーを生成し、それをデータベースに保存するのは愚かなことです。元の攻撃を実行するために必要なステップが1つ増えるだけです。実際には、ユーザーのパスワードをデータベースに保存するべきではありません。あなたは? HTTPSを使用していますか?