该手册似乎建议在数字周围使用引号足以防止 SQL 注入。
根据第5.3.1 节。MySQL 5.1 参考手册的一般安全指南:
如果应用程序生成查询,例如
SELECT * FROM table WHERE ID=234
当用户输入值234
时,用户可以输入值234 OR 1=1
以使应用程序生成查询SELECT * FROM table WHERE ID=234 OR 1=1
。结果,服务器检索表中的每一行。这会暴露每一行并导致过多的服务器负载。防止此类攻击的最简单方法是在数字常量周围使用单引号:SELECT * FROM table WHERE ID='234'
. 如果用户输入额外的信息,它们都将成为字符串的一部分。在数字上下文中,MySQL 自动将此字符串转换为数字并从中删除任何尾随的非数字字符。
这是否意味着如果用户输入值,用户就会受到保护234' OR 1=1 #
?(即生成查询SELECT * FROM table WHERE ID='234' OR 1=1 #'
)
简短的回答,不。引用技巧很容易通过包含您自己的结束引号和注释符号来消除最终的连接引号,就像在您的示例中一样。
为了保护自己免受 SQL 注入,您必须使用绑定变量。将您的示例更改为
SELECT * FROM table WHERE ID = :X
然后将用户的输入绑定到 X 可以立即彻底地解决问题。这种做法的重要性怎么强调都不为过!用户只需输入
234' OR 1=1 --
(带有尾随空格)即可打破这一点。上面提供的摘录不会阻止 SQL 注入。即使使用单引号,也可以修改输入以操纵引号。带引号的查询将是:
SELECT * FROM table WHERE ID='234',其中输入为
234
现在考虑注入的输入:
234'; select * from passwords;select * from table where id='234
. 这将创建一个查询块:SELECT * FROM table WHERE ID='234'; 从密码中选择 *;从 id='234' 的表中选择 *
根据使用的前端语言,在我的例子中是 PHP,有内置的函数
mysql_real_escape_string
可以用来减少 SQL 注入。我可以对文档说的唯一评论(除了@mrdenny 的幽默评论)是,如果没有引号,则可能有更多的注入。通常,如果您使用某种
magic_quotes
机制(仅当您GBK / Big5
在后端 DBMS 使用或熟悉的字符集时才可绕过),这并不是一个糟糕的“指南”。它应该正确过滤/预格式化所有出现的字符'
,这些字符可以轻松地将 SQL 注入输入到该语句中(例如,使用您声明的有效负载234' OR 1=1 #
)。但是,为了 100% 安全,您绝对应该只使用“参数化”的 SQL 语句!