关于数据库:即使删除了’字符,是否有某种方法可以注入SQL?

关于数据库:即使删除了’字符,是否有某种方法可以注入SQL?

Is there some way to inject SQL even if the ' character is deleted?

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

如何完成?谁能给我例子吗?


是的,有。摘自Wikipedia

"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注入不是简单的攻击方法。如果我是你,我会做非常仔细的研究。


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

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


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

您创建的代码如下:

1
2
3
4
' 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问题。


是的,绝对有可能。

如果您希望使用下一个SELECT语句作为整数,则可以输入类似的内容:

选择*从thingy其中attributeID =

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

以下网站详细介绍了经典的SQL注入技术:SQL注入速查表。

使用参数化查询或存储过程并不是更好。这些只是使用传递的参数的预制查询,这些参数也可以作为注入源。此页上也有描述:在SQL中攻击存储过程。

现在,如果您禁止使用简单的引号,则只能阻止一组给定的攻击。但并非全部。

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

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

玩得开心,别忘了查看WikiPedia的答案。

/ Vey


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

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


由于这是一个相对较老的问题,因此我不会费心编写一个完整而全面的答案,因为一个或多个发布者在此提到了该答案的大多数方面。
但是,我确实有必要提出另一个此处未曾提及的问题-SQL走私。在某些情况下,即使您尝试删除引号字符',也可以将其"走私"到查询中。实际上,即使您使用了正确的命令,参数,存储过程等,这也是可能的。

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


而且-即使您只是查找单引号,也不想将其删除。您想逃脱它。您可以通过用两个撇号替换每个撇号来实现。

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


。 。 。大约有50000000其他方式

也许有点像5; drop table employees; --

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

(--发表评论)


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


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

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


当期望数字参数时,应始终验证输入以确保其为数字。除了帮助防止注入外,验证步骤还将使应用程序更加用户友好。

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


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


这是撇号的真实输入,当您在代码中使用内联SQL时,必须通过将它们加倍来对其进行转义。您正在寻找的是正则表达式模式,例如:

1
\\;.*--\\

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

因此答案是:不,仅删除撇号并不能保证您免受SQL Injection的安全。


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

例如,在Java中,如果要这样做(故意过高的示例):

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

那么您很有可能会遭受注射攻击。

Java有一些有用的工具来防止这些攻击,例如PreparedStatements(在其中传递" SELECT NAME_ from Customer WHERE ID =?"之类的字符串,而JDBC层则在为您替换?令牌时处理转义),但是其他一些语言对此没有帮助。


推荐阅读