4

現在、次のようなことを行ってSQLクエリを作成しています

string SQLQuery = "SELECT * FROM table WHERE ";
foreach(word in allTheseWords)
{
     SQLQuery = SQLQuery + " column1 = '" + word + "' AND";
}

これが SQL インジェクション攻撃につながる可能性があることを理解しています。配列をパラメータとして渡す方法がわかりません

where report in @allTheseWords

===========

SQL Server 2012 を使用しています

4

6 に答える 6

3

残念ながら、テーブル値パラメーターのユーザー定義型を追加しないと、配列をパラメーターとして渡すことはできません。この制限を回避する最も簡単な方法は、ループ内の配列の各要素に対して個別に名前を付けたパラメーターを作成し、これらの各要素に値をバインドすることです。

string SQLQuery = "SELECT * FROM table WHERE column1 in (";
for(int i = 0 ; i != words.Count ; i++) {
    if (i != 0) SQLQuery += ",";
    SQLQuery += "@word"+i;
}
...
for(int i = 0 ; i != words.Count ; i++) {
    command.Parameters.Add("@word"+i, DbType.String).Value = words[i];
}

一時テーブルを作成し、そこに個々の単語を挿入してから、単語の一時テーブルと内部結合するクエリを実行することもできます。

于 2013-01-28T15:35:12.710 に答える
2

ADOを使用すると、paramsの助けを借りてそれを行うことができます

SqlConnection Con = new SqlConnection(conString);
SqlCommand Com = new SqlCommand();
string SQLQuery = "SELECT * FROM table WHERE ";
int i=1;
foreach(word in words)
{
      Com.Parameters.Add("@word"+i.ToString(),SqlDbType.Text).Value = word;
      SQLQuery = SQLQuery + " column1 = '@word"+i.ToString()+"' AND ";
      i++;
}
Com.CommandText =SQLQuery;
于 2013-01-28T15:43:12.633 に答える
2

マイクロソフトからの推奨事項は次のとおりです

  1. コード分​​析を使用して、SQL インジェクションが発生しやすい Visual Studio プロジェクト内の領域を検出します。
  2. 攻撃のリスクを軽減する方法については、次の記事を参照してください。

要するに、彼らは次のように話します。

  • ストアド プロシージャを使用します。
  • パラメータ化されたコマンド文字列を使用します。
  • コマンド文字列を作成する前に、タイプとコンテンツの両方についてユーザー入力を検証します。

ところで、ビルド プロセスの一部として静的分析を有効にして、セキュリティ ルールが破られたときにビルドも壊れるように構成することができます。チームが確実に安全なコードを作成できるようにする優れた方法です。

于 2013-01-28T17:26:04.887 に答える
1

SQL Server の場合は、テーブル値パラメーターを使用します。SQL には、同じ型の複数の項目のコレクションを表す 1 つの構造があります。テーブルといいます。配列はありません。


もちろん、更新されたはずのクエリは次のとおりです。

where report in @allTheseWords

元のクエリと同等ではありませんが、意図に近い可能性があります。を使用して構築されたクエリでは、同じ行の同じが複数の異なる単語に等しくなけれANDばならないことを言っています。すべての単語が等しい場合を除き、行は返されません。更新されたクエリは、すべてではなく、いずれかの単語が一致するかどうかを回答します。

于 2013-01-28T15:36:18.597 に答える
1

準備済みステートメントを使用する必要があります。それらが処理される方法は、クエリを記述し、使用する値のプレースホルダーを配置することです。次に例を示します。

SELECT * FROM table WHERE column1 = @word

次に、パラメーターをクエリにバインドする必要があることを SQL エンジンが認識している準備フェーズを実行する必要があります。その後、クエリを実行できます。SQL エンジンは、クエリにバインドするパラメーターをいつ、どのように解釈するかを認識している必要があります。

これを行うコードは次のとおりです。

SqlCommand command = new SqlCommand(null, rConn);

// Create and prepare an SQL statement.
command.CommandText = "SELECT * FROM table WHERE column1 = @word";
command.Parameters.Add ("@word", word);
command.Prepare();
command.ExecuteNonQuery();
于 2013-01-28T15:36:27.407 に答える
0
I combine the use of params with HtmlEncoding(to get rid of special characters where not needed). Give that a shot.

using (SqlConnection conn = new SqlConnection(conString))
{     
    string sql = "SELECT * FROM table WHERE id = @id";
    using (SqlCommand cmd = new SqlCommand(sql, conn))
    {
        cmd.paramaters.AddWithValue("@id", System.Net.WebUtility.HtmlEncode(id));
        conn.Open();
        using (SqlDataReader rdr = cmd.ExecuteReader())
        {

        }
    }
}
于 2013-01-28T18:26:30.813 に答える