パラメーター化されたクエリへの依存は、SQLインジェクションから保護する唯一の方法ですか?


13

SQLインジェクション攻撃で私が見たすべては、パラメータ化されたクエリ、特にストアドプロシージャのクエリが、このような攻撃から保護する唯一の方法であることを示唆しているようです。私が(暗黒時代に)働いていたとき、主に保守性が低いと見られていたため、ストアドプロシージャは貧弱なプラクティスと見なされていました。テスト可能性が低い。高度な結合; システムを1つのベンダーにロックしました。(この質問は他のいくつかの理由をカバーしています)。

私が働いていたとき、プロジェクトはそのような攻撃の可能性にほとんど気づいていませんでした。さまざまな種類の破損からデータベースを保護するために、さまざまなルールが採用されました。これらのルールは次のように要約できます。

  1. クライアント/アプリケーションは、データベーステーブルに直接アクセスできませんでした。
  2. すべてのテーブルへのすべてのアクセスはビューを介して行われました(ベーステーブルへのすべての更新はトリガーを介して行われました)。
  3. すべてのデータ項目にドメインが指定されていました。
  4. データ項目をNULL可能にすることは許可されませんでした-これは、DBAが時々歯を磨くという意味がありました。しかし、強制されました。
  5. ロールと権限が適切に設定されました-たとえば、ビューのみにデータを変更する権限を与える制限されたロール。

SQLインジェクション攻撃を防ぐために、このような(強制的な)ルールのセット(必ずしもこの特定のセットである必要はありませんが)は、パラメーター化されたクエリの適切な代替手段ですか?そうでない場合は、なぜですか?データベースは、データベース(のみ)固有の手段によって、このような攻撃から保護できますか?

編集

質問の強調は、受け取った最初の回答に照らして、わずかに変わりました。基本質問は変更されていません。

EDIT2

パラメータ化されたクエリに依存するアプローチは、システムに対する攻撃に対する防御の周辺ステップにすぎないようです。より根本的な防御が望ましいと思われ、特にインジェクション攻撃から防御する場合でも、そのようなクエリへの依存は不要であるか、それほど重要ではないようです。

私の質問に暗示されているアプローチは、データベースの「装甲」に基づいており、それが実行可能なオプションであるかどうかはわかりませんでした。さらなる研究は、そのようなアプローチがあることを示唆しています。このタイプのアプローチへのポインタを提供する以下のソースを見つけました。

http://database-programmer.blogspot.com

http://thehelsinkideclaration.blogspot.com

これらのソースから取得した主な機能は次のとおりです。

  1. 広範なセキュリティデータディクショナリと組み合わせた広範なデータディクショナリ
  2. データディクショナリからのトリガー、クエリ、および制約の生成
  3. コードを最小化し、データを最大化する

これまでの回答は非常に有用であり、パラメータ化されたクエリを無視することから生じる困難を指摘していますが、最終的には元の質問に回答しません(太字で強調されています)。


ストアドプロシージャに対する引数を購入しません。それらは単に真実ではありません。
コンラッドルドルフ

ヌルなしの要件はどうなっていますか?
マーク・カンラス

2
@Konrad Rudolph-アプリケーションをMySQLで作成してからDB2に移行することにした場合、ストアドプロシージャには互換性があると本当に思いますか?同様に、SQLLiteに移行する場合は?また、OSをアップグレードするとします。ストアドプロシージャがC(DB2にあります)でコンパイルされている場合、おそらくすべて再コンパイルが必要になります。これらは妥当な引数です。絶対的なものではなく、合理的なものです。
マシューフリン

@マシュー・ドゥー。それを読んでそれについてコメントするとき、私は実際に「パラメータ化されたクエリ」を考えていました。ストアドプロシージャ=全体の「別のストーリー」。
コンラッドルドルフ

回答:


25

ストアドプロシージャは、インジェクションを自動的に保護しません。これはどうですか

CREATE PROC proc
  @id VARCHAR(5)
AS
BEGIN
  EXEC("SELECT * FROM Client WHERE ClientId = " + @id);
END

パラメータ化されたクエリを使用すると、プロシージャ内にあるかどうかにかかわらず、インジェクションから保護されます。


プロシージャではなく、パラメータ化されたクエリに焦点を当てていただきありがとうございます。ただし、このようなクエリ以外の方法、特にデータベース層のみに限定されている方法で、データベースを保護できるかどうかを尋ねています。
クリスウォルトン

1
+1それに加えて、データを取得する方法を維持しながらユーザーがテーブルに直接アクセスできないようにする唯一の方法であるため、ストアドプロシージャはほとんど安全であると考えたいと思います。ユーザーが間に何も介在せずにクライアントと直接データベースにアクセスする必要がある場合に、行ベースおよび列ベースの権限を確保する唯一の方法です。
ファルコン

2
@クリス-クレイグがここで言っていることは、Procが実際にあなたを保護していると仮定することはできないと思います。それはおそらく完全な答えではなく、タイトルの仮定の修正です。
ジョンホプキンス

@Jon-クレイグの訂正を踏まえて、質問のタイトルを変更し、質問を編集しました。私は、返信を受け取り始めるまで、質問で行っていた仮定を知りませんでした。
クリスウォルトン

2
上記のCraigの
記述

11

これは、SQLインジェクション攻撃を防ぐためのストアドプロシージャの適切な代替手段である(強制された)ルールのセットですか?そうでない場合は、なぜですか?

いいえ、開発者にかなり重いペナルティを課しているためです。アイテムごとの内訳:

1.クライアント/アプリケーションは、データベーステーブルに直接アクセスできませんでした。

ロールを使用します。クライアントは、アクセスが必要なテーブル(および可能な場合は行)へのSELECT、INSERT、UPDATE、およびDELETEアクセスのみを持つ制限されたロールを介してのみDBにアクセスできる必要があります。クライアントがすべてのエントリをスパムまたは削除できないようにする場合は、データ変更にAPIを使用します。

2.すべてのテーブルへのすべてのアクセスは、ビューを介して行われました。

ビューの効率に応じて、ごくわずかなパフォーマンスコストから膨大なパフォーマンスコストまで、あらゆるものが考えられます。開発が遅くなるのは、不必要な複雑さです。ロールを使用します。

3.すべてのデータ項目にドメインが指定されていました。

維持するのに多くの作業が必要になる可能性があり、おそらく別のテーブルに正規化する必要があります。

4.データ項目をNULL可能にすることは許可されませんでした-これは、DBAが時々歯を磨くという意味がありました。しかし、強制されました。

それは単純に間違っています。開発者がを処理できない場合、NULL大きな問題が発生します。

データベースは、データベース(のみ)固有の手段によって、このような攻撃から保護できますか

ストアドプロシージャ必要ありませ。引数をエスケープする関数(pg_query_paramsなど)でパラメーター化されたクエリを使用するだけです。もちろん、データベースが誰でも書き込み可能な場合、またはクライアントロールがすべてに完全にアクセスできる場合は、とにかく台無しになります。誰かがやって来て、クライアントが何をしているのかを理解し、5分以内にクライアントをクックアップして、DBを破壊(またはさらに悪いことには毒)する必要があります。



役割の+1。彼らはこれに大きく貢献しています-私は質問に役割を含めませんでしたが、それらはセットアップの一部でした-特に、ビューには、クライアントに提案するような制限された役割が割り当てられました。ビューのパフォーマンスヒットに関するポイント。ドメインには検証テストが含まれていました-主に範囲と長さ。データnullableルールに関するあなたのコメントは、このルールについて聞いた人よりもはるかに丁寧です。これは私の仮定でしたが、許可が適切に設定されることを明示的に述べませんでした。
クリスウォルトン

6

あなたのルールがあなたを完全に保護しているかどうかはわかりません。

最初の問題は、それらが施行されていると述べていることですが、かなりのオーバーヘッドが発生するだけでなく、完璧な施行を見たこともありません。

第二に、それらの私の読書は、これらのようなルールが物事を悪用することを難しくするかもしれないが、彼らはそれを妨げないということです。たとえば、ビューで同じデータにアクセスできる場合、テーブルに直接アクセスできないことは実際にはあまり変わりません。クライアントが何かを行う必要がある場合、ビューがそれを容易にする必要があり、ビューがそれを容易にする場合、攻撃者は同じ機能/データを利用できます。

データの更新や削除だけではないことも忘れないでください。SQLインジェクションの脆弱性の一部は情報の収集です。そのため、データがビューvCustomersまたは基礎となるCustomersテーブルを介して渡されたかどうかは気にしません。あなた、すべてではないが、いくつかの弱点からあなた自身を守ったかもしれません。同様に、クライアントが更新を行うことができる場合、トリガーを介しても、トリガーを起動して更新を行うSQLを作成できます。

(すべての更新がトリガーを介して行われるという点では、2つのことを言います。(1)これを読んだとき、口の中で少し気分が悪くなりました。(b)ストアドプロシージャは嫌いです。 「メンテナンス性が低く、テスト性が低く、高度に結合され、システムを1つのベンダーにロックします」が、基本的に同じことが言えるトリガーを使用します。

必要なのは、SQLステートメントの実行を許可する1つの穴(およびそれを妨げるこれらのルールは表示されません)と攻撃者がいます。彼らは背後で非常に直感的でないデータベースを見つけている可能性があります。停止するのではなく、遅くするだけです)。

ここでのもう1つのことは、複雑さを追加していること(および作成されるオーバーヘッドも)、複雑さは悪用される可能性のある穴につながる傾向があるということです。

このような一連のルールを作成できなかったと言っているわけではありません。この種の攻撃を防ぐために広く受け入れられている方法を使用するよりも、面倒で信頼性が低いようです。


暗黙的で無意識の仮定に照らして実際のクエリを理解し、それに適切に対応したことに対して+1。気になる理由については-アーキテクチャの関連する説明からコードの多くが生成されるプロジェクトに取り組んでいます-このアーキテクチャの一部では、データベースアクセスルーチンを生成する方法を説明しています。これらの生成されたルーチンがどのような形をとるかについてはまだ未解決です。
クリスウォルトン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.