7

当我开始在我的程序中编写第一个 SQL 语句时,我对使用同事向我展示的一种非常简单的方法保护自己免受 SQL 注入感到很自在。它用两个单引号替换了所有单引号。

例如,有一个搜索字段,您可以在其中输入客户名称以在客户表中搜索。如果你要输入

彼得的理发店

SELECT 语句看起来像

SELECT *
FROM Customers
WHERE Customername = 'Peter''s Barbershop'

如果现在攻击者会插入这个:

';DROP TABLE FOO; --

该声明将如下所示:

SELECT *
FROM Customers
WHERE Customername = ''';DROP TABLE FOO;--'

它不会删除任何表,而是在 customertable 中搜索 customername ';DROP TABLE FOO;-- 我想不会找到 ;-)

现在在用这种方法编写语句并保护自己免受 SQL 注入之后,我读到许多开发人员使用参数化语句,但我从未读过使用“我们的”方法的文章。所以肯定有一个很好的理由。

参数化语句将涵盖哪些场景但我们的方法没有?与我们的方法相比,参数化语句的优势是什么?

谢谢
菲利普

4

5 回答 5

4

参数化查询比对 sql 注入的防御具有更多的过程。

  1. 它解决了日期和时间格式化和解析的问题。
  2. 您可以为参数化查询准备执行计划。
  3. sql注入保护。

我现在不记得其他专业人士了:)。

然而,“双引号”的方式对于字符长度有限的字段存在问题。

例如:

  • 该页面有“昵称”框,可以是 10 个字符长。
  • 用户插入“不关心”——确切的 10 个字符。

现在,如果将引号加倍,则该值有 11 个字符,并且数据库将“剪切”它,并且您在 db 中得到另一个值而不是用户键入的值。

所以我推荐参数。

于 2010-04-28T15:36:20.120 回答
2

一个很大的缺点是您的解决方案依赖于记住添加字符的开发人员,显然编译器不会抱怨。那很危险。

其次,应该使用参数化的 SQL 语句来提高性能,正如 Jeff 指出的那样2005 年!!!)。

于 2010-04-28T15:34:18.260 回答
1

一个优点是司机自己将决定他必须逃脱什么和不需要逃脱什么。您的方法可能会被这样的输入破坏:

  \'; DROP TABLE foo;--

这会导致

  SELECT *
  FROM Customers
  WHERE Customername = '\'';DROP TABLE FOO;--'

第一个引号被转义,第二个没有并关闭字符串。

于 2010-04-28T15:36:07.080 回答
1

简短的回答:
您应该使用参数化查询,因为数据库服务器比您更清楚哪些字符需要转义。

长答案:
'不一定是唯一需要转义的特殊字符。这些特殊字符因数据库服务器而异。例如,MySQL\也用作转义字符(除非sql_mode=NO_BACKSLASH_ESCAPES已设置)。因此,''\'意思是一样的。

例如,甲骨文并非如此。

于 2010-04-28T15:52:17.940 回答
0

与我们的方法相比,参数化语句的优势是什么?

优点是更难出错;你不能做参数化的方法,忘记替换引号。此外,如果您这样做两次,替换引号很容易受到攻击。

参数化查询的缺点(以及我从不使用它们的原因)是复杂性。在获得 RSI 之前,您可以编写 10 倍的临时查询。

于 2010-04-28T15:34:03.530 回答