1

私はすでにいくつかの回答を見てきましたが、私のクエリは少し異なります:

元のクエリは次のとおりです。

cmd.CommandText = "select count(Table1.UserID) from Table1 INNER JOIN 
Table2 ON Table1.ID = Table2.ID where Table1.Userid = " + UserID + " and
Table1.Number != '" + Number +"' and Table2.ID < 4";

SQL インジェクションの変更されたクエリを次に示します。

cmd.CommandText = "select count(Table1.UserID) from Table1 INNER JOIN 
Table2 ON Table1.ID = Table2.ID where Table1.Userid = @userId and
Table1.ID != @Number and Table2.ID < 4";

お気づきのように、最初のクエリはUserId二重引用符で囲まれています:..." + UserID +"...そして Number私たちは一重引用符と二重引用符で囲まれています:...'" + Number + "'...

パラメータを設定する方法は次のとおりです。

cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("@Number", Number); 
cmd.Parameters.AddWithValue("@userId",UserID);

UserID整数でNumber、文字列です。

それで、私の質問は、変更されたクエリが正しい方法でフォーマットされているかどうかです。@UserId元のクエリで指定されているさまざまな方法を考慮して、@Numberパラメータをクエリに入れる方法に違いはありますか?

4

3 に答える 3

1

最初のクエリでは、二重引用符はパラメーターではなく、クエリの実際のテキストに属していました。文字列を SQL クエリに追加するときに追加する一重引用符。Number と呼ばれるものを一重引用符で囲む理由がわかりません。実際にそれが数値型の変数である場合、一重引用符なしでクエリに入ることができます。しかし、単一引用符が含まれている場合、Sql はそれを文字列と見なし、それを数値として使用する場合は数値に変換するだけです。たとえば、Table1.Number が数値の場合。

しかし、お気づきのように、パラメーターをクエリ文字列に追加してクエリ文字列を作成することは、SQL インジェクション攻撃のドアを大きく開いてしまうため、ひどい習慣です。したがって、パラメータ化されたクエリを使用します。

パラメータ化されたクエリでは、引用符について心配する必要はありません。文字列値であるパラメーターの場合、SQL データベースに渡すコマンドを作成するときに、環境はそれらを引用符で囲むことを心配します。数値のパラメーターの場合、引用符は必要ありません。これも自動的に処理されます。

于 2015-08-12T16:25:59.117 に答える
1

私は長い間 .net Mvc に取り組んできました。2 番目のケースでは、パラメーターが自分で正しく修正されていることを確認できます。心配する必要はありません。ちなみに、自分自身を注入できるかどうかは、引き続きデバッグおよびテストできます。簡単に言えば、あなたのコードは見栄えがよく、無敵です。

これは私が行う方法であり、あなたのものと同様に安全です:

    string Query = @"select a1, a2, a3, a4 from table1 where a1 in 
                           (select b1 from table2 where b2 = @start or b2 = @end)";

            using (SqlCommand Comm = new SqlCommand(Query, Conn))
            {
                Comm.Parameters.Add("@start", SqlDbType.NVarChar).Value = start;
                Comm.Parameters.Add("@end", SqlDbType.Int).Value = end;
            }
于 2015-08-12T15:56:37.310 に答える
0

クエリの 2 番目のバージョンの方がはるかに優れていると思います。見た目からすると、問題なく動作するはずです。

値を連結する代わりにパラメーターを追加すると、SQL インジェクションに対してより安全になります。この例では、SQL インジェクションを行う方法が見当たりません。

編集

パラメータ化されたクエリを使用する場合、変数を宣言してクエリで使用する場合と同様に、引用符を追加する必要はありません。引用符を使用する必要はありません。

DECLARE @x CHAR(10) = 'abc'
SELECT  @x 

クエリ内で値の連結を使用する場合、クエリに追加しようとしている値が の場合は、CHAR単一引用符で囲む必要があります。の場合はINT、一重引用符で囲む必要はありません。

SELECT  'abc', 1

最初のクエリにある二重引用符は、SQL ステートメントとは関係ありません。C# コードで使用され、CommandText に割り当てようとしている SQL ステートメント文字列を作成します。

string abcVar = "abc";
int intVar = 1;
string sqlCommand = "SELECT '" + abcVar + "', " + intVar;
于 2015-08-12T15:57:01.403 に答える