即使'字符被删除,有没有办法注入SQL?

时间:2008-09-16 12:36:17

标签: sql database sql-injection

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

怎么做?谁能举个例子?

14 个答案:

答案 0 :(得分:23)

是的,有。摘自Wikipedia

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

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

1;DROP TABLE users

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

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

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

答案 1 :(得分:15)

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

有关预防样本,请参阅WikiPedia

答案 2 :(得分:6)

是的,这绝对是可能的。

如果你有一个表格,你期望一个整数来做你的下一个SELECT语句,那么你可以输入类似的东西:

SELECT * FROM thingy WHERE attributeID =

  • 5(答案很好,没问题)
  • 5; DROP表users; (坏,坏,坏......)

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

使用参数化查询或存储过程并不是更好。这些只是使用传递参数的预制查询,也可以是注入源。此页面还对其进行了描述:Attacking Stored Procedures in SQL

现在,如果你压制简单的引用,你只能防止一组特定的攻击。但不是全部。

与往常一样,不要相信来自外部的数据。在以下3个级别过滤它们:

  • 显而易见的东西的接口级别(下拉选择列表优于自由文本字段)
  • 与数据性质(int,字符串,长度),权限相关的检查的逻辑级别(此用户可以在此页面使用此类数据)...
  • 数据库访问级别(转义简单引用...)。

玩得开心,不要忘记查看WikiPedia的答案。

/维伊

答案 3 :(得分: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"));

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

您也可以查看此Stackoverflow question about SQL Injections

答案 4 :(得分:3)

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

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

答案 5 :(得分:2)

。 。 。呃大约5000万其他方式

可能类似于5; drop table employees; --

结果sql可能是这样的: select * from somewhere where number = 5; drop table employees; -- and sadfsf

--开始发表评论)

答案 6 :(得分:2)

此外 - 即使你只是寻找撇号,你也不想删除它。你想逃避它。你可以用两个撇号替换每个撇号。

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

答案 7 :(得分:2)

由于这是一个相对较老的问题,我不打算写一个完整而全面的答案,因为这个答案的大多数方面都在这里被一张海报或另一张提到过。
但是,我确实认为有必要提出另一个问题,这里没有任何人接触过这个问题 - SQL走私。在某些情况下,即使您尝试删除,也可以将引号字符“走私”到查询中。实际上,即使您使用了正确的命令,参数,存储过程等,这也是可能的。

http://www.comsecglobal.com/FrameWork/Upload/SQL_Smuggling.pdf查看完整的研究论文(披露,我是这方面的主要研究员)或只是google“SQL走私”。

答案 8 :(得分:1)

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

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

答案 9 :(得分:1)

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

答案 10 :(得分:0)

这取决于你如何组合查询,但实质上是。

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

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

那么你很有可能打开注射攻击。

Java提供了一些有用的工具来防范这些,例如PreparedStatements(你在其中传递一个字符串,如“SELECT name_ from Customer WHERE ID =?”,JDBC层处理转义,同时替换你的?令牌),但是其他一些语言对此没那么有用。

答案 11 :(得分:0)

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

\;.*--\

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

因此答案是:不,简单地删除撇号并不能保证SQL注入安全。

答案 12 :(得分:0)

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

答案 13 :(得分:0)

当您需要数字参数时,应始终验证输入以确保其为数字。除了有助于防止注射,验证步骤将使应用程序更加用户友好。

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