12

如果我从 SQL 查询中删除所有 ' 字符,还有其他方法可以对数据库进行 SQL 注入攻击吗?

如何做呢?谁能给我例子?

4

14 回答 14

23

就在这里。摘自维基百科

"SELECT * FROM data WHERE id = " + a_variable + ";"

从该声明中可以清楚地看出,作者希望 a_variable 是与“id”字段相关的数字。但是,如果它实际上是一个字符串,那么最终用户可以根据他们的选择来操作语句,从而绕过对转义字符的需要。例如,将 a_variable 设置为

1;DROP TABLE users

将从数据库中删除(删除)“用户”表,因为 SQL 将呈现如下:

SELECT * FROM DATA WHERE id=1;DROP TABLE users;

SQL注入不是简单的攻击。如果我是你,我会做非常仔细的研究。

于 2008-09-16T12:41:20.487 回答
15

是的,取决于您使用的语句。您最好通过使用存储过程或至少参数化查询来保护自己。

有关预防样本,请参见Wikipedia 。

于 2008-09-16T12:38:59.353 回答
6

是的,这绝对是可能的。

如果您有一个表单,其中您希望一个整数来创建您的下一个 SELECT 语句,那么您可以输入任何类似的内容:

SELECT * FROM thingyWHERE 属性 ID=

  • 5(好答案,没问题)
  • 5个;删除表users;(糟糕,糟糕,糟糕……)

以下网站详细介绍了经典的 SQL 注入技术:SQL Injection cheat sheet

使用参数化查询或存储过程也好不到哪里去。这些只是使用传递参数的预制查询,也可以是注入源。本页也对此进行了描述:攻击 SQL 中的存储过程

现在,如果你禁止简单的引用,你只能阻止一组给定的攻击。但不是全部。

一如既往,不要相信来自外部的数据。在这 3 个级别过滤它们:

  • 显而易见的东西的界面级别(下拉选择列表比自由文本字段更好)
  • 与数据性质(整数、字符串、长度)、权限(此用户是否可以在此页面上使用此类数据)相关的检查的逻辑级别...
  • 数据库访问级别(转义简单引号...)。

玩得开心,别忘了查看维基百科的答案。

于 2008-09-16T13:01:08.707 回答
6

我建议您将变量作为参数传递,而不是构建自己的 SQL。否则,总会有一种方法来进行 SQL 注入,以我们目前不知道的方式进行。

您创建的代码类似于:

' Not Tested
var sql = "SELECT * FROM data WHERE id = @id";
var cmd = new SqlCommand(sql, myConnection);
cmd.Parameters.AddWithValue("@id", request.getParameter("id"));

如果你有一个像我这样的名字,里面有一个'。所有 ' 字符都被删除或标记为无效是非常烦人的。

您可能还想查看有关 SQL 注入的 Stackoverflow 问题

于 2008-09-16T13:53:18.847 回答
3

参数化内联 SQL 或参数化存储过程是保护自己的最佳方式。正如其他人指出的那样,仅仅剥离/转义单引号字符是不够的。

您会注意到我专门讨论了“参数化”存储过程。如果您恢复将过程传递的参数连接在一起,那么仅使用存储过程是不够的。换句话说,将完全相同的易受攻击的 SQL 语句包装在存储过程中并不会使其更安全。您需要在存储过程中使用参数,就像使用内联 SQL 一样。

于 2008-09-16T13:48:19.187 回答
2

. . . 呃大约 50000000 其他方式

也许像5; drop table employees; --

生成的 sql 可能类似于: select * from somewhere where number = 5; drop table employees; -- and sadfsf

--开始评论)

于 2008-09-16T12:40:46.493 回答
2

此外 - 即使您只是寻找撇号,您也不想删除它。你想逃避它。您可以通过用两个撇号替换每个撇号来做到这一点。

但是参数化查询/存储过程要好得多。

于 2008-09-16T13:06:54.840 回答
2

由于这是一个相对较旧的问题,我不会费心写一个完整而全面的答案,因为该答案的大部分方面都已被一位或另一位海报提到过。
然而,我确实认为有必要提出另一个在这里没有人提到的问题——SQL Smuggling。在某些情况下,即使您尝试将引号字符 ' 删除,也有可能将其“走私”到您的查询中。事实上,即使您使用了正确的命令、参数、存储过程等,这也是可能的。

在http://www.comsecglobal.com/FrameWork/Upload/SQL_Smuggling.pdf上查看完整的研究论文(披露,我是这方面的主要研究人员)或者只是谷歌“SQL Smuggling”。

于 2008-10-09T19:39:24.717 回答
1

是的,绝对是:根据您的 SQL 方言等,有很多方法可以实现不使用撇号的注入。

针对 SQL 注入攻击的唯一可靠防御是使用数据库接口提供的参数化 SQL 语句支持。

于 2008-09-16T12:41:16.743 回答
1

而不是试图找出要过滤掉的字符,我会坚持使用参数化查询,并完全消除问题。

于 2008-09-16T12:57:01.963 回答
0

这取决于您如何组合查询,但本质上是的。

例如,在 Java 中,如果你要这样做(故意令人震惊的例子):

 String query = "SELECT name_ from Customer WHERE ID = " + request.getParameter("id");

那么你很有可能会面临注射攻击。

Java 有一些有用的工具来防止这些,例如 PreparedStatements(您在其中传递一个字符串,例如“SELECT name_ from Customer WHERE ID = ?”,并且 JDBC 层在替换 ? 标记时为您处理转义),但还有一些其他语言对此没有太大帮助。

于 2008-09-16T12:41:10.520 回答
0

事情是撇号可能是真正的输入,当您在代码中使用内联 SQL 时,您必须通过将它们加倍来逃避它们。您正在寻找的是一个正则表达式模式,如:

\;.*--\

一个分号用于过早结束正版语句,一些注入的 SQL 后跟双连字符以注释掉原始正版语句中的尾随 SQL。连字符可以在攻击中省略。

因此答案是:不,简单地删除撇号并不能保证您免受 SQL 注入的影响。

于 2008-09-16T12:47:51.173 回答
0

我只能重复别人说过的话。参数化的 SQL 是要走的路。当然,对它进行对接编码有点痛苦 - 但是一旦你完成了一次,那么剪切和粘贴该代码并进行所需的修改并不难。我们有很多 .Net 应用程序允许网站访问者指定整个范围的搜索条件,并且代码动态构建 SQL Select 语句 - 但用户可能输入的所有内容都进入了参数。

于 2008-09-16T13:52:15.963 回答
0

当您期望一个数字参数时,您应该始终验证输入以确保它是数字的。除了帮助防止注入之外,验证步骤将使应用程序更加用户友好。

如果您在期望 id = 1044 时收到 id = "hello",那么最好向用户返回一个有用的错误,而不是让数据库返回一个错误。

于 2008-09-16T17:39:35.590 回答