2

可能重复:
我可以通过转义单引号并用单引号包围用户输入来防止 SQL 注入吗?

我只是想知道,如果我在用户输入中替换 every'并验证数字(确保它们是数字,并且不包含任何其他字符),SQL 注入仍然可能吗?如何?''string.Replace("'","''")

我正在使用动态 SQL 查询,使用SqlCommand. 像这样的东西:

cmd.CommandText = "SELECT * FROM myTable WHERE ID = " + theID.ToString();

或者

cmd.CommandText = "UPDATE myTable SET title='" + title.Replace("'","''") + "' WHERE ID = " + theID.ToString();

输入整数在 ASP.NET MVC 中自动验证(检查它们是否为实数)。

4

1 回答 1

10

如果这是一个以这种方式编码的遗留项目,那么虽然不是最佳的,但我目前不知道它有任何可能受到 SQL 注入的影响,只要每个字符串都以这种方式处理并且查询很简单正如你所展示的。

然而,我不能说比这更确定了。如果不使用参数化查询,总是有可能存在一些您尚未考虑的漏洞。

自己手动转义引号很容易出错,并且有时会以难以提前预料的方式失败。例如下表

CREATE TABLE myTable(title VARCHAR(100))
INSERT INTO myTable VALUES('Foo')

以及使用通过字符串连接构建的动态 SQL 的存储过程

CREATE PROC UpdateMyTable
@newtitle NVARCHAR(100)
AS
/*
Double up any single quotes
*/
SET @newtitle = REPLACE(@newtitle, '''','''''')

DECLARE @UpdateStatement VARCHAR(MAX)

SET @UpdateStatement = 'UPDATE myTable SET title='''  + @newtitle + ''''

EXEC(@UpdateStatement)

您可以尝试以下方法

正常更新

EXEC UpdateMyTable N'Foo'
SELECT * FROM myTable /*Returns "Foo"*/

SQL 注入尝试失败

EXEC UpdateMyTable N''';DROP TABLE myTable--'
SELECT * FROM myTable  /*Returns "';DROP TABLE myTable--"*/

SQL 注入尝试成功并删除表

EXEC UpdateMyTable N'ʼ;DROP TABLE myTable--'
SELECT * FROM myTable  /*Returns "Invalid object name 'myTable'."*/

这里的问题是第三个查询通过U+02BC而不是标准的撇号,然后在varchar(max)卫生发生后将字符串分配给 a ,这会默默地将其转换为常规撇号。

在我在这里阅读答案之前,我永远不会想到这个问题。

于 2012-09-02T11:57:56.977 回答