我知道过滤bad关键字并不是防止SQL注入的好方法。然而,当我无法回答为什么这不是一个好方法时,下面是我的原则:
1)当我看到;时,我把它转到'' (这样就没有人可以再做一行SQL语句了)。
2)当我看到'时,我到了''。(我认为这应该能防止引号逃跑)。
3)当我看到*时,我会把它转到* (这样黑客就不会得到我的表信息)。
4)当我看到--时,我会把它转到-(这样就可以防止黑客试图对我的声明进行评论)。
^我提出这4条规则的原因是因为这里中有一本C8指南
假设在解析SQL语句时,我在服务器上执行以下操作:db.exc("INSERT INTO name VALUES ('{}', '{}');".format(firsname, lastname))
当我查看我设置的规则时,我认为从技术上来说,防止SQL注入这个语句是安全的。我说的对吗?如果没有,你能提供一个打破它的方法吗?(我知道最好的做法,但我就是搞不懂为什么不行。)有人能帮我举个例子吗?
发布于 2018-04-14 23:22:49
一种明显的突破方法是:使用非字符串(例如,数字)的东西进行攻击,其中用户应该输入类似于45的内容(在代码中以字符串的形式操作,因为它是从某些HTML中提取出来的,但在SQL中不是撇号--因为它是数字类型字段),而是可以输入整个SQL子查询(或者一个过程调用,或者至少还有一些附加的子句.)。
你也没有任何地方接近全面的元字符来捕捉。例如,使用--启动注释并不是唯一的方法(我不确定它是否在一般的SQL标准中);启动单行注释( MySQL也支持)的另一种方法是#,而且您没有对这些进行任何处理。请参阅https://dev.mysql.com/doc/refman/5.7/en/comments.html
其他问题:让我们假设你已经“完全”地做到了这一点。然后,在将来的某个时候,切换数据库引擎(或者只是升级到新版本),新的数据库服务器支持一些新的元字符(作为注释的开始,作为行尾,作为字符串的结尾,作为子查询分隔符,作为其他的.),突然您的“解决方案”再次受到攻击。
别再想重新发明轮子了。所有数据库驱动程序都存在已准备好的语句/参数化查询。一些数据库引擎支持用户定义的存储过程,这些存储过程不仅是参数化的,而且比普通的SQL字符串执行得更快。
如果您出于某种原因绝对必须将用户输入与原始SQL结合起来(这是很少见的,通常可以通过更聪明地使用代码来避免,但在某些地方您不能简单地使用参数化查询),那么使用一个经过良好测试的库函数。您基本上是在尝试重新实现mysql_escape_string和第一次尝试也失败了。。
发布于 2018-05-11 13:02:44
您的过滤方法不是很有用,您应该使用内置的安全方法,而不是自己替换字符。
您可以同时执行这两项操作,但请记住,mysqli_query()不会自动接受多个SQL语句,因此解决了第一个问题。
mysql_escape_string()修复了您的第二个问题,并且还应该修复一系列其他问题,其中的值被解释为比它们更重要。
您目前拥有的是一个黑名单,除非与其他SQL注入缓解方法结合使用,否则它并不完全有效。如果可能的话,我建议使用白名单。因此,例如,您将只接受整数作为输入。
黑名单是这样的:
我接受一切除了..。
白名单是这样的:
我不允许一切除了..。
因此,如果使用得当,白名单比黑名单有效得多。请记住,SQL注入非常、非常先进,并且已经存在了很长时间。您所拥有的只是一个包含4条规则的黑名单,如果用仅包含4条规则的黑名单防止所有SQL注入攻击非常简单,那么SQLi就不是问题了。
https://security.stackexchange.com/questions/183746
复制相似问题