当我开始在我的程序中编写第一个SQL语句时,我觉得用一个同事向我展示的非常简单的方法来保护自己免受SQL注入的影响非常舒服。它用两个单引号替换了所有单引号。
例如,有一个搜索字段,您可以在其中输入客户名以在custompaable中进行搜索。如果你要输入
彼得的理发店
SELECT语句看起来像
SELECT *
FROM Customers
WHERE Customername = 'Peter''s Barbershop'
如果攻击者现在插入此内容:
';DROP TABLE FOO; --
声明如下:
SELECT *
FROM Customers
WHERE Customername = ''';DROP TABLE FOO;--'
它不会删除任何表,但会搜索customcable中的customername'; DROP TABLE FOO; - 我想,这将找不到; - )
现在经过一段时间编写语句并使用此方法保护自己免受SQL注入后,我读到许多开发人员使用参数化语句,但我从未读过使用“我们的”方法的文章。所以绝对有充分的理由。
参数化语句会覆盖哪些场景,但我们的方法却没有?与我们的方法相比,参数化语句有哪些优点?
感谢
菲利普
答案 0 :(得分:4)
参数化查询比sql-injection的防御具有更多的过程。
我现在记不起另一个职业选手:)。
然而,“每个引号加倍”的方式对字符长度有限的字段有问题。
例如:
现在,如果你将引号加倍,则该值有11个字符,数据库将“剪切”它,并且db中的另一个值比用户键入的值要多。
所以我推荐参数。
答案 1 :(得分:2)
一个很大的缺点是你的解决方案依赖于开发人员记住添加角色,显然编译器不会抱怨。这很危险。
其次,应该使用参数化的SQL语句来增强性能,Jeff指出here(在 2005 !!!中)。
答案 2 :(得分:1)
一个优点是驱动程序本身将确定他必须逃脱的内容以及不需要转义的内容。你的方法可以用这样的输入打破:
\'; DROP TABLE foo;--
哪会导致
SELECT *
FROM Customers
WHERE Customername = '\'';DROP TABLE FOO;--'
第一个引号被转义,第二个引号没有并关闭字符串。
答案 3 :(得分:1)
简短回答:
您应该使用参数化查询,因为数据库服务器比您需要转义的字符更清楚。
答案很长:
'
不一定是唯一需要转义的特殊角色。这些特殊字符与DB服务器和DB服务器不同。例如,MySQL也使用\
作为转义字符(除非设置了sql_mode=NO_BACKSLASH_ESCAPES
)。因此,''
和\'
意味着同样的事情。
例如,甲骨文并非如此。
答案 4 :(得分:0)
有什么好处 参数化语句比较 我们的方法?
优点是犯错很难;你不能做参数化的方法,忘了替换引号。此外,如果你这样做两次,替换引号很容易受到攻击。
参数化查询的缺点(以及我从不使用它们的原因)是复杂性。在获得RSI之前,您可以写出十倍的即席查询。