如果从SQL查询中删除所有'字符,还有其他方法对数据库进行SQL注入攻击吗?
怎么做?谁能举个例子?
答案 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 =
users
; (坏,坏,坏......)以下网站详细介绍了经典的SQL注入技术:SQL Injection cheat sheet。
使用参数化查询或存储过程并不是更好。这些只是使用传递参数的预制查询,也可以是注入源。此页面还对其进行了描述:Attacking Stored Procedures in SQL。
现在,如果你压制简单的引用,你只能防止一组特定的攻击。但不是全部。
与往常一样,不要相信来自外部的数据。在以下3个级别过滤它们:
玩得开心,不要忘记查看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"));
如果你有一个像我这样的名字,其中包含'。所有' - 字符都被删除或标记为无效是非常烦人的。
答案 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”,那么最好将有用的错误返回给用户,而不是让数据库返回错误。