3

我正在更新一些不能正确处理用户输入的遗留代码。该代码确实进行了最少量的清理,但并未涵盖所有已知威胁。

我们较新的代码使用参数化查询。据我了解,查询是预编译的,输入被简单地视为无法执行的数据。在这种情况下,不需要消毒。那正确吗?

换句话说,如果我在这个遗留代码中参数化查询,是否可以消除它当前所做的清理工作?还是我错过了参数化之上的一些额外的清理好处?

4

6 回答 6

6

SQL 查询参数确实可以很好地防御 SQL 注入。嵌入的引号或其他特殊字符不会造成恶作剧。

但是 SQL 查询的某些组件不能参数化。例如表名、列名、SQL 关键字。

$sql = "SELECT * FROM MyTable ORDER BY {$columnname} {$ASC_or_DESC}";

因此,在插入 SQL 查询之前,您可能需要验证一些动态内容示例。将值列入白名单也是一种很好的技术。

此外,您可能拥有列的数据类型允许但没有意义的值。对于这些情况,使用应用程序代码进行验证通常比尝试在 SQL 约束中进行验证更容易。

  • 假设您存储了一个信用卡号。信用卡号有有效的模式,图书馆可以识别有效的和无效的。

  • 或者当用户定义她的密码时怎么样?您可能希望确保足够的密码强度,或验证用户在两个密码输入字段中输入了相同的字符串。

  • 或者,如果他们订购了一定数量的商品,您可能需要将数量存储为整数,但您需要确保它大于零,如果大于 1000,您可能需要与用户再次核对他们输入正确。

于 2010-06-25T18:14:11.957 回答
5

参数化查询将有助于防止 SQL 注入,但它们不会对跨站点脚本做任何事。您需要其他措施(例如 HTML 编码或 HTML 检测/验证)来防止这种情况发生。如果您只关心 SQL 注入,那么参数化查询可能就足够了。

于 2010-06-25T18:09:23.557 回答
2

清理和验证有许多不同的原因,包括防止跨站点脚本,以及只需要字段的正确内容(电话号码中没有姓名)。参数化查询消除了手动清理或逃避 SQL 注入的需要。

请参阅我以前的答案之一。

于 2010-06-25T18:05:38.047 回答
1

简而言之,没有。输入清理和参数化查询的使用不是相互排斥的,它们是独立的:您既可以不使用,也可以单独使用,也可以同时使用。它们可以防止不同类型的攻击。两者都使用是最好的课程。

于 2010-06-25T18:47:17.450 回答
1

重要的是要注意,作为一个小点,有时编写包含动态 SQL 的存储过程很有用。在这种情况下,输入参数化的事实并不能自动防御 SQL 注入。这似乎是一个相当明显的观点,但我经常遇到一些人认为因为他们的输入是参数化的,所以他们可以不再担心 SQL 注入。

于 2010-06-25T18:47:24.500 回答
1

您是对的,SQL 参数不是可执行代码,因此您无需担心。

但是,您仍然应该进行一些验证。例如,如果您期望 varchar(10) 并且用户输入的内容比这更长,那么您最终会遇到异常。

于 2010-06-25T18:06:55.923 回答