你好,我正在测试我正在研究的网站。一些开发人员试图通过用双引号替换每个引号来避免SQL注入。这是C#代码:
string sql =
@"SELECT *
FROM users
WHERE us_username = '$us'
AND us_password = '$pw'";
sql.Replace("$pw", txtPassword.Text.Replace("'","''"));
有什么方法可以执行SQL注入攻击吗?我尝试了Unicode技巧,但它没有用。该数据库在SQL Server 2008R2上运行。
答案 0 :(得分:7)
您应该使用参数化命令。使用string.Replace
只是一个坏主意。
var command = conn.CreateCommand();
command.CommandText = @"SELECT *
FROM users
WHERE us_username = @user
AND us_password = @password";
cmd.Parameters.Add("@user", txtUser.Text);
cmd.Parameters.Add("@password", txtPassword.Text);
这可能是您的设置的潜在候选人:
As an example, note the following trivial Stored Procedure: create procedure GetData ( @param varchar(20) ) as begin declare @s varchar(200) select @s = 'select * from dataTable where name = ''' + @param + '''' exec (@s) end
可以从执行验证代码的网页调用此SP 在将输入传递给SP之前。至少,这个验证码 要么验证输入不包含引号,要么进行清理 它可以使任何现有报价加倍。例如,验证码可以 使用
<小时/> 这就是有趣(或可怕)部分的开始 - Unicode 同性恋翻译不仅限于基本字母字符...... 具体来说,Unicode字符U + 02BC(修饰符字母 撇号可以由数据库服务器翻译成简单的引用 - '(U + 0027)。当然,还有许多其他类似的例子。string.Contains()
,string.Replace()
,正则表达式, 此网页也可能是经过精心调整的 Web应用程序防火墙,用于验证所有输入并验证否 报价包括在内。恶意用户或攻击者可以提交恶意攻击 包含修饰符字母撇号(U+02BC
,编码为的URL的代码%CA%BC
)。这将轻松传递适用的验证码和WAF 过滤器,因为它们搜索实际的引用(U+0027
) 此时输入中不存在。显然,IDS / IPS系统会 也没有发现任何错误。验证机制甚至可能 搜索引用的各种编码,例如URL编码,UTF-8 编码,十六进制编码,双重编码等 - 但是,U+02BC
是 这些都不是,实际上是一个完全不同的字符值。
答案 1 :(得分:3)
该部分查询的代码在SQL注入时是安全的,但在与某些数据库一起使用时仅 。每个系统都有自己的一组需要转义的字符,所以如果你使用它,例如MySQL,那么不安全。其他查询可能不是安全的。
代码应该被替换,因为它已被破坏。当您需要修复代码时,您还应该将其更改为使用参数化查询,这是一种更强大且可移植的解决方案。
所以,让我们看看它是什么坏了。由于代码一次替换一个参数,它们可能会相互干扰。例如,如果我输入用户名number
和密码has$$$pwnd
(是的,弱密码),您最终会得到如下查询:
1234
如果某些值包含用于替换后的参数的代码,则值将被破坏。
如果存在不同类型的参数且值未正确验证,则甚至可以用于在代码中的其他查询中进行SQL注入。由于一个参数的值可以在另一个参数中结束,因此字符串值最终可能会出现在一个数字参数中,而该数字参数周围没有撇号,因此无需潜入撇号来突破字符串字面值将有害代码放入查询中。
答案 2 :(得分:-1)
计算SQL注入的最佳方法是添加参数。
SqlCommand sql = new SqlCommand (@"SELECT *
FROM users
WHERE us_username = @user
AND us_password = @password")
sql.Parameters.Add("@users", SqlDbType.Varchar2, 5).Value = "users";
sql.Parameters.Add("@user", SqlDbType.Varchar2, 6).Value = "your_value";
sql.Parameters.Add("@password", SqlDbType.Varchar2, 8).Value = "your_value";
正如您所看到的,您可以做很多事情来确保正在执行的是您只想执行的值。
开发人员编写的代码只会在事后改变sql语句,如果他们记录这个sql语句就很好。但是你现在拥有的东西不能防止Sql Injection。