【问题标题】:Can you see any vulnerabilities in the following SQL Injection defense scheme?你能看到以下 SQL 注入防御方案中的任何漏洞吗?
【发布时间】:2015-11-16 23:05:55
【问题描述】:
  1. 不要将撇号 (') 存储在数据库的字符字段中,而是始终将撇号转换为一些独特的替代符号,这些符号不被识别为 SQL 语法,并且在您的数据中不太常见或有意义.
  2. 当接收来自 GET、POST 等的直接用户输入时,始终通过将值中的撇号转换为您选择的替代符号来过滤掉它们。
  3. 对于包含用户输入的所有 SQL 语句,始终将撇号包裹在文字值周围。例如,像这样:SELECT Name FROM Client WHERE TYPE = '1';。这应该强制将所有非撇号字符视为文字值本身的一部分,无论它们是反引号、花括号、分号、反斜杠、正斜杠等。所以像 SELECT Name FROM Client WHERE TYPE = ' -- /* comment the rest ';不会有不同的解释。
  4. 每当将用户输入合并到 SQL 语句的非文字部分(例如 ORDER BY 子句中的列名)时,从值中完全过滤掉标点符号,或根据预定义的安全集对其进行验证。
  5. 无论何时从您的数据库输出数据(到 HTML、XML 等),始终通过将您选择的替代符号替换为撇号来反转此过滤过程,以便客户可以很好地阅读内容。

(注意:我们使用的是 SQL Server,它不会将反引号符号识别为有效的 SQL 标点符号,但如果使用 MySQL,我们还需要翻译反引号。)

我已经用每个可以想象到的可能阻塞 SQL 的符号对此进行了测试,到目前为止它已经经受住了一切。我有没有忽略什么?在我在生产系统上尝试之前,我想获得一些社区反馈。


我们的环境:

【问题讨论】:

标签: mysql sql-server security sql-injection


【解决方案1】:

我不了解 MySQL 方面的情况,但由于这主要是关于 SQL Server,我可以说这种方法对您没有任何好处,而参数化查询和/或使用存储过程并没有让您受益。但是,它确实有以下缺点:

  1. 实施需要时间
  2. 它使系统更容易出错(即忘记翻译的地方)
  3. 它降低了数据的可移植性/可导出性/可报告性,因为所有客户都需要知道这种不明显的翻译
  4. 关于SELECT Name FROM Cient WHERE TYPE = '1';,如果TYPE 字段是数字类型,那么您充其量只会影响性能,最坏的情况是会出现转换错误
  5. 您现在拥有一个不必要的过于复杂的系统,这将增加培训和支持时间(让新程序员快速上手,发现/解决问题所需的时间等)。

只需使用参数,无论是作为存储过程的输入,还是参数化的即席 SQL 语句。如果使用 .NET,则在这两种情况下都将使用 SqlParameters。

ADOdb 确实支持参数化查询和存储过程(本质上是参数化的)。请看:

他们甚至提到了 PDO(转到此处及其下一小节:http://phplens.com/lens/adodb/docs-adodb.htm#connect_ex),但我不确定这是否有用。这里也提到了 PDO:http://adodb.sourceforge.net/docs-adodb.htm#php5

【讨论】:

  • 使用参数化 SQL 会很好。 :) 但在这种情况下,我们使用的是带有 PHP 的旧版 ADODB 驱动程序。它不像新的 PDO 驱动程序那样支持参数化 SQL。
  • @JohnDoe 我更新了 ADOdb 链接,显示您应该能够同时执行参数化查询和存储过程 :-)。
猜你喜欢
  • 1970-01-01
  • 2019-05-05
  • 1970-01-01
  • 1970-01-01
  • 2022-12-05
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
  • 2020-08-21
相关资源
最近更新 更多