0

ADO.net でパラメーターを使用する方法と、C# を始めるきっかけとなったすばらしい Web サイトhttp://csharp-station.com/Tutorial/AdoDotNet/Lesson06で多くのことを目にします。

        // don't ever do this
        // SqlCommand cmd = new SqlCommand(
        // "select * from Customers where city = '" + inputCity + "'");

しかし、なぜこれを行うべきでないのかについての答えが得られないようです。正当な理由があることは間違いありませんが、私はそれを見つけることができないようです. 誰かが私に記入してください。将来、新規参入者にこれに答えることができます (職場の人がコードを学ぶのを手伝うのが好きです)。C# を学んでいる新しい人にとっては、ほとんどの人がコードの行数が少ないことに気付くと思います。これは勝利のように思えます。文字列を一緒に追加することは、パラメーターを使用するよりも負担が大きいためですか?

4

1 に答える 1

1

誰かがアプリの都市のテキスト ボックスに次のように入力した場合に何が起こるかをよく考えてください。

';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 または他のクエリ ツールに貼り付けることができ、完了したら、混乱全体をクライアントにすばやく戻すことができることです。コード。ワンライナーにとってはそれほど大したことではなく、非常に巨大で複雑なクエリはストアドプロシージャまたはビューとして終了することがよくありますが、これが本当に役立つスイートスポットがあります..そして、より多くのものがそのスイートスポットで終わることがわかります.あなたが思うかもしれないより。

于 2013-04-11T03:32:38.047 に答える