我已经看到了一些答案,但我的查询有点不同:
这是一个原始查询:
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
参数放入查询中是否有任何区别?
答案 0 :(得分:1)
我一直在研究.net Mvc很长一段时间,我可以确保你自己在第二种情况下正确修复了参数,你不必担心。顺便说一句,你仍然可以调试和测试你是否可以自己注射。简而言之,您的代码看起来很棒且无懈可击。
这就是我这样做的方式,它和你的一样安全:
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;
}
答案 1 :(得分:1)
在初始查询中,双引号属于查询的实际文本,而不是参数。将字符串附加到sql查询时要添加的单引号。我不知道为什么你会在名为Number的东西周围加上单引号。如果实际上这是一个数字类型变量,它可以在没有单引号的情况下进入查询。但如果它有单引号,那么唯一发生的事情就是Sql将其视为字符串,然后将其转换为数字,如果它将其用作一个数字。例如,如果Table1.Number是数字。
但是,正如您所注意到的那样,通过将您的参数附加到查询字符串中来构建查询字符串是一种可怕的做法,因为它为sql注入攻击打开了大门。因此,您可以使用参数化查询。
在参数化查询中,您不必担心引号。对于作为字符串值的参数,环境会担心将它们包含在引号中,因为它构建了传递给sql db的命令。对于数字参数,不需要引号,并且再次为您处理。
答案 2 :(得分:0)
我认为你的第二个版本的查询要好得多,从它的外观来看,它应该可以正常工作。
添加参数而不是连接值对于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;