2017-04-27 4 views
0

私は、文字列連結がSQLインジェクションを受けやすいことを知りました。悲しいことに、私は既に自分のコードのほとんどに既に適用しています。私はパラメータ化されたクエリを組み込もうとしていますが、何とかオンラインの例が私の問題に答えることはありません。私が見たほとんどの例がこれです:asp.netでクエリをパラメータ化する方法は?

string query = "SELECT * FROM Products WHERE ProductID = @Id"; 
SqlCommand cmd = new SqlCommand(query, conn); 
cmd.Parameters.AddWithValue("@Id", Request.QueryString["Id"]); 

しかし、私はこのようなSQL文があるとします。また、

public static void CreateLingerieBrandsDatabase(string brand) 
{ 
    SqlConnection createBrandData = new SqlConnection(@"Data Source=Y560\SQLEXPRESS;Initial Catalog=LingerieItemsDB;Integrated Security=True"); 
    createBrandData.Open(); 
    SqlCommand cmdBrandData = new SqlCommand("CREATE TABLE lingerieItem" + brand + "(id int,type char(50),model char(50),price float,image1 char(255),image2 char(255),description text, [neck type], [color] char(50)); ", createBrandData); 
    cmdBrandData.ExecuteNonQuery(); 
    createBrandData.Close(); 
} 

を、私は意志、テキストボックス内の文字列ブランドの値を取得していますCreateLingerieBrandsDatabaseメソッドに渡されます。それは文字列連結に渡されます。ちなみに、なぜ私はlingerieItemGlamory、lingerieItemEvgenia、lingerieItemVictoriaのように各ブランドごとに3つのテーブルを作成しているので、テーブル名に文字列連結を使用する理由があります。管理者がテキストボックスにGlamoryを入力してからsubmitをクリックすると、アクセスするデータベーステーブルがわかります。

EDITED:上記の例では、私が言及した3つの以前のブランド(連結部分を除く)と同じテーブル名を持つ新しいデータベースを作成します。だから、アクセスするときは、アクセスするブランドを知ることになります。

私のコードは面倒で、私はまだ初心者です。皆さんが私にとってより良いソリューションを提案し、コードを改善できることを願っています。実際の例を示すことも高く評価されています。うわー!

+1

あなたは識別子をパラメータ化することはできません。つまり、ddlステートメントではパラメーターを使用できません。ただし、表の作成は、設計時の操作であり、実行時の操作ではありません。ユーザーがデータベース構造を扱えるようにすることは、決して良い考えではありません。また、異なるブランドの同じ構造で複数のテーブルを保持するのではなく、単一のテーブルを作成し、ブランドを示す列を追加する必要があります。 –

+0

@ZoharPeled - そうだね。さて、私は間違いなくその変化についてブレーンストームするつもりです。 –

+0

通常、データモデルが壊れていることを認識してこれを修正します。 *データ*(ブランド名)をデータとしてモデル化するのではなく、*メタデータ*(テーブル名)に埋め込みます。 'brand'カラムを含む* single *' lingerieItems'テーブルがあれば、この(そして非常に多くの)クエリは、素早く*簡単に*書くことができ、基本的なパラメータ化にオープンします。 –

答えて

0

パラメータで表名を置き換えることはできません。連結によって名前を構成する必要があります。そして、ブランド名ので、例えば、単にSQLインジェクションを防ぐために、そのリストに対してbrand変数の値をチェックし、特定の定義済みリストに限定されているように見える。:

public static void CreateLingerieBrandsDatabase(string brand) 
{ 
    SqlConnection createBrandData = new SqlConnection(@"Data Source=Y560\SQLEXPRESS;Initial Catalog=LingerieItemsDB;Integrated Security=True"); 
    createBrandData.Open(); 
    if (!Regex.Match(brand, @"^(?:Glamory|Evgenia|Victoria)$", RegexOptions.IgnoreCase).Success) 
     throw new ArgumentException("Invalid brand"); 
    SqlCommand cmdBrandData = new SqlCommand("CREATE TABLE lingerieItem" + brand + "(id int,type char(50),model char(50),price float,image1 char(255),image2 char(255),description text, [neck type], [color] char(50)); ", createBrandData); 
    cmdBrandData.ExecuteNonQuery(); 
    createBrandData.Close(); 
} 
+0

ああそうです。これをチェックすることにより、不要な入力を防止します。印象的な! –

+0

あなたのソリューションをもう一度見直しましたが、Glamory、Evgenia、Victoria以外の新しいブランドを作成することができないことに気付きました。面白い解決策に近いので、私はこれを微調整する必要があるかもしれません。 –

+0

はい、 '^(?:Glamory | Evgenia | Victoria)$'は単なる例でした。実際のリストがもっと長い場合は、拡張する必要があります。リストが本当に長い場合は、正規表現文字列を次のように記述することができます: 'var brandsRegexStr =" ^(?: "string.Join(" | "、brands)+")$ ";' 'brand'は、ブランド名を持つ文字列の配列またはリストであると仮定しています。 –

関連する問題