ストアドプロシージャを使用する場合、SQLインジェクションの影響を受けませんか?
-
04-07-2019 - |
質問
(重要な場合)MySQLデータベースで発言します。
解決
いいえ、あなたは完全に安全ではありません。他の人が述べたように、パラメータ化されたクエリは、あなたがデータベースにアクセスする方法に関係なく、常に行く方法です。
Procを使用すると安全であるというのは、ちょっとした都市伝説です。人々がこの妄想に陥っている理由は、ほとんどの人が、コードからパラメーター化されたクエリを使用してプロシージャを呼び出すと想定しているためだと思います。しかし、もしあなたがそうしなければ、例えば以下のようなことをするなら、あなたは広く開いています:
SqlCommand cmd = new SqlCommand("exec @myProc " + paramValue, con);
cmd.ExecuteNonQuery();
エンドユーザーからのフィルタリングされていないコンテンツを使用しているため。繰り返しになりますが、彼らがしなければならないのは、ラインを終了し("")、彼らの危険なコマンドを追加し、ブームです-あなたはうんざりしています。
(余談ですが、Webを使用している場合は、ブラウザーのクエリ文字列からフィルター処理されていない迷惑メールを取得しないでください。これにより、データに対して非常に悪いことを行うのが非常に簡単になります。)
クエリをパラメータ化すると、より良い状態になります。ただし、ここで他の人が述べたように、プロシージャがまだ動的SQLを生成して実行している場合は、まだ問題がある可能性があります。
私はアンチプロセスではないことに注意してください。 Procsは、データアクセスに関する特定の問題を解決するのに非常に役立ちます。ただし、procは、SQLインジェクションに対する「銀の弾丸」ソリューションではありません 。
他のヒント
パラメータ化されたクエリを一貫して使用する場合のみ、SQLインジェクションの影響を受けません。すべての場所で適切なエスケープを使用すると、SQLインジェクションにほとんど影響を受けません(ただし、エスケープルーチンにはバグがある可能性があり、バグがあります。したがって、パラメータほど確実ではありません)。
ストアドプロシージャを呼び出して、連結によって引数を追加する場合、入力フィールドの1つの最後にランダムクエリを追加できます-たとえば、CALL CheckLogin @username = '$ username'、@ password = '$ password'で、直接連結された変数を表す$ -thingsを使用して、$ password変数を変更して" 'を読み取ることを妨げるものは何もありません。 DROP DATABASE; -"。
明らかに、事前に入力をクリーンアップすると、これはSQLインジェクションの防止にも貢献しますが、これはクリーンアップされるべきではないデータを除外する可能性があります。
ストアドプロシージャが何をするかによって異なります。パラメーターに基づいて動的にSQLを生成し、そのSQLを実行する場合、依然として脆弱です。そうでなければ、あなたは大丈夫である可能性がはるかに高いです-しかし、私は100%自信を持って聞こえることをためらいます!
いいえ。ストアドプロシージャを呼び出すSQLを構築している場合、あなたはまだターゲットです。
クライアント側でパラメータ化されたクエリを作成する必要があります。
いいえ、まだストアドプロシージャでD-SQLを使用できます。入力を検証および制限することは、どのような場合でも良い考えです。
実際に脆弱なのは動的コードであり、ストアドプロシージャ内のコードとストアドプロシージャの動的に生成された呼び出しを含むため、ストアドプロシージャは保証ではありません。
パラメーター化されたクエリとパラメーターで呼び出されたストアドプロシージャは、コードを生成するために任意の入力を使用しない限り、どちらもインジェクションの影響を受けません。インジェクションに対して脆弱ではない動的コードがたくさんあることに注意してください(たとえば、動的コードの整数パラメーター)。
大部分(100%が本当に可能かどうかはわかりません)ストアドプロシージャベースのアーキテクチャの利点は、インジェクションがクライアント側の動的コードに対して(完全ではありませんが)ある程度防御できることです。 :
EXE権限のみが、アプリが接続しているユーザーコンテキストに付与されるため、SELECT、INSERT、UPDATE、DELETEクエリはすべて失敗します。もちろん、DROPなどは許可されません。したがって、インジェクションはEXECの形式である必要があるため、最終的には、SPレイヤーで定義した操作のみ(任意のSQLではなく)をインジェクトに使用できます。
データベースサービスを一連のストアドプロシージャ(ソフトウェアの抽象化レイヤーなど)として定義する他の多くの利点の中で、アプリに影響を与えずにデータベースをリファクタリングできること、使用パターンをよりよく理解して監視できることプロファイラーを備えたデータベース、および新しいクライアントを展開することなくデータベース内で選択的に最適化する機能。
さらに、きめの細かいデータベースアクセス(一般にロールベースのアクセス制御とも呼ばれます)を使用することを検討してください。データベースのメインユーザーは、ジョブを実行するために必要な権限を持っている必要があります。インストール後に新しいテーブルを作成する必要はありませんか?その許可を取り消す。 sysdbaとして実行する正当な必要はありませんか?しないでください!ユーザーに「DROP DATABASE」を指示する巧妙なインジェクション。ユーザーがその許可を付与されていない場合は妨害されます。その後、心配する必要があるのは、データ漏洩のSELECTステートメントだけです。