1

我的问题基本上是这样的:如果我使用参数化语句/准备语句将用户输入字符串插入表中,然后稍后获取该值并将其用于动态构造表的列值,这是否让我对 SQLInjection 持开放态度?

具体例子:

如果我使用参数化语句将用户的输入字符串存储到表中,然后从该表中选择该 TEXT 并将其存储在我的程序中的局部变量(字符串 localVariable)中,并创建一个具有以下内容的表:

"CREATE TABLE InjectFree (" + localVariable + " TEXT)"

我的 localVariable 会没有可注入的 sql 代码吗?我知道有替代方案(并且可能会使用替代方案只是为了安全起见),但我想我只是想知道参数化值实际上做了什么以及它对存储在表中的数据有什么影响。

4

2 回答 2

3

你会有危险。

参数化的插入将防止对该原始插入语句进行注入,但不会防止下一次使用。

于 2012-07-11T12:54:38.357 回答
1

如果您使用参数化查询,则查询和数据将分别提供给数据库。这有几个影响...

  • 它允许 RDBMS 看到该查询与该查询的先前实例相同。 (如果您将数据作为静态值嵌入到查询字符串中,RDBMS 将不会看到查询是相同的,只有数据发生了变化。) 这允许执行计划重用和 RDBMS 的其他有益特性。

  • 它简化了数据验证。这与注入攻击有关。无论将什么值代入参数,数据始终只是数据。它永远不会被视为查询的一部分。

然而,后一点也意味着你不能这样做......

INSERT INTO @tableName(@fieldName) VALUES (@dataValue)

每个参数都被视为一个数据项。它不是一个松散绑定的脚本,其中的值@tableName不会被替换到脚本中。查询必须使用表名和字段名进行硬编码。只有真正的数据项才能作为参数传递。

这通常感觉像是对 java 脚本等用户的限制。然而,它是保护您免受 SQL 注入攻击的机制。那是一件好事 :)


这意味着要允许用户定义的数据定义语言(例如 CREATE TABLE),您需要自己将字符串的不同部分连接在一起。实际上,无论您如何保护自己免受 SQL 注入攻击,总会有人找到解决办法。

As soon as you allow a user to specify table names, field names, etc, you become immediately open to attack. The only safe way is to have a white-list of allowable strings.

于 2012-07-11T13:14:02.697 回答