誰かがアプリの都市のテキスト ボックスに次のように入力した場合に何が起こるかをよく考えてください。
';DELETE FROM Customers;--
次のような sql 文字列を作成することになります。
select * from Customers where city = '';DELETE FROM Customers;--'
たまたま 2 つのステートメントと 1 つのコメントでうまくいき、SQL プロバイダーはそれらの両方を完全に喜んで実行します。現在、データベース接続がそのテーブルから削除するために必要な権限のないユーザーとして実行されている可能性もあります...しかし、社会保障番号やクレジットカードなどを取得するために他のテーブルからデータを読み取るなど、他の権限を持っている可能性があります。おそらく、管理者権限を持つ新しいアカウント レコードを挿入します。熟練した攻撃者は、これを使用してほとんどすべてのことを行うことができます.
代わりに、単純なエスケープまたはサニタイズ関数を書きたくなるかもしれません。これをしないでください。まず、問題が完全に解決するわけではありません。クエリ パラメータは、SQL コードからユーザー データを完全に分離するため、データベースでさえ、常にユーザー入力を変数値のように扱い、クエリ文字列に直接入力することはありません。脱出機能を使うと、クラッカーとの軍拡競争に巻き込まれます。
もう 1 つの理由は、パフォーマンスです。データベースは、データを取得するためのクエリを実行計画に変換するために多くの問題を抱えています。そのため、クエリ テキストのハッシュをキーとしてプランをキャッシュすることがよくあります。パラメータ化されたクエリを使用しないと、毎回キャッシュ ミスが発生します。
最後に、パラメータ化されたクエリの操作が簡単だと思います。複雑なクエリの場合、次のように、クエリの上にコメントを付けることができます。
/*DECLARE @someVariable varchar(12);
DECLARE @OtherVariable varchar(50);
DECLARE @thirdVariable int;
...*/
var sql =
"SELECT <columns>
FROM table t"
INNER JOIN othertable o ON t.ID = o.tableID"
WHERE someColumn = @someVariable AND ...";
using (var cn = new SqlConnection(" ... "))
using (var cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add()
//...
これが行うことは、このクエリを維持するときが来たら、クエリをすばやくコピーして変数宣言を Management Studio または他のクエリ ツールに貼り付けることができ、完了したら、混乱全体をクライアントにすばやく戻すことができることです。コード。ワンライナーにとってはそれほど大したことではなく、非常に巨大で複雑なクエリはストアドプロシージャまたはビューとして終了することがよくありますが、これが本当に役立つスイートスポットがあります..そして、より多くのものがそのスイートスポットで終わることがわかります.あなたが思うかもしれないより。