SQL注入单引号漏洞

时间:2015-08-21 14:06:25

标签: c# sql sql-server sql-injection code-injection

你好,我正在测试我正在研究的网站。一些开发人员试图通过用双引号替换每个引号来避免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上运行。

3 个答案:

答案 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之前。至少,这个验证码   要么验证输入不包含引号,要么进行清理   它可以使任何现有报价加倍。例如,验证码可以   使用string.Contains()string.Replace(),正则表达式,   此网页也可能是经过精心调整的   Web应用程序防火墙,用于验证所有输入并验证否   报价包括在内。恶意用户或攻击者可以提交恶意攻击   包含修饰符字母撇号(U+02BC,编码为的URL的代码   %CA%BC)。这将轻松传递适用的验证码和WAF   过滤器,因为它们搜索实际的引用(U+0027)   此时输入中不存在。显然,IDS / IPS系统会   也没有发现任何错误。验证机制甚至可能   搜索引用的各种编码,例如URL编码,UTF-8   编码,十六进制编码,双重编码等 - 但是,U+02BC是   这些都不是,实际上是一个完全不同的字符值。   

<小时/>   这就是有趣(或可怕)部分的开始 - Unicode   同性恋翻译不仅限于基本字母字符......   具体来说,Unicode字符U + 02BC(修饰符字母   撇号可以由数据库服务器翻译成简单的引用    - '(U + 0027)。当然,还有许多其他类似的例子。

来源:http://web.archive.org/web/20130401091931/http://www.comsecglobal.com/FrameWork/Upload/SQL_Smuggling.pdf

答案 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。