SQL 注入单引号漏洞

SQL injection single quote Vulnerability

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

您应该改用参数化命令。使用 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

This SP may be called from a Web page, which executes validation code before passing the input to the SP. At a minimum, this validation code either verifies that the input does not contain a quote, or sanitizes it to double any existing quote. For instance, the validation code may be using string.Contains(), string.Replace(), Regular expressions, etc. It is also possible that this Web page is behind a finely-tuned Web Application Firewall that validates all input and verifies that no quotes are included. A malicious user or attacker can submit malicious code containing a modifier letter apostrophe (U+02BC, URL encoded to %CA%BC). This will easily pass applicative validation code and WAF filters, since these search for an actual quote (U+0027) which does not exist in the input at this time. Obviously, IDS/IPS systems would also not detect anything amiss. The validation mechanisms may even search for various encodings of a quote, such as URL Encoding, UTF-8 encoding, Hex encoding, double encoding, and more – however, U+02BC is none of these, and is in fact a completely different character value.


And this is where the interesting (or scary) part starts – the Unicode homoglyph translation is not limited to base alphabet characters... Specifically, the Unicode character U+02BC (modifier letter apostrophe) can be translated by the database server to a simple quote – ' (U+0027). There are, of course, many other similar examples.

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

该部分查询的代码在 SQL 注入中是安全的,但 仅在 与某些数据库一起使用时。每个系统都有自己的一组需要转义的字符,因此如果您将其与 MySQL 一起使用,那么它 是安全的。其他查询可能是安全的。

代码已损坏,但仍应更换。由于您需要修复代码,因此您还应该将其更改为使用参数化查询,这是一种更健壮和可移植的解决方案。

所以,让我们看看有什么问题。由于代码一次替换一个参数,它们可能会相互干扰。例如,如果我输入用户名 has$$$pwnd 和密码 1234(是的,弱密码),您最终会得到如下查询:

SELECT *
  FROM users
WHERE us_username = 'has$34nd'
  AND us_password = '1234'

如果某些值包含用于在其后替换的参数的代码,则这些值将被破坏。

这甚至可以用于在代码中的其他查询中进行 SQL 注入,如果有不同类型的参数并且值没有被正确验证的话。由于一个参数的值可以在另一个参数中结束,一个字符串值可以在一个没有撇号的数字参数中结束,因此不需要潜入一个撇号来打破字符串文字来放置查询中的有害代码。

对抗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 注入。