如何判断用户是否尝试了SQL注入攻击


How To Determine Whether A User Attempted A SQL Injection Attack

我熟悉使用mysql_real_escape_string()和PHP FILTER_SANITIZE函数来防止sql注入。

然而,我很好奇,我将如何在PHP脚本中确定用户输入是否可能是sql注入尝试?这将有助于跟踪潜在的恶意ip。

如果mysql_real_escape_string的输出与输入不一致,则表示输入中包含不安全字符。您可以推断用户可能一直在尝试攻击,特别是如果有问题的字段是您通常期望的低数量的不安全字符(例如邮政编码)的字段。

但也可能是因为他们的名字恰好是Robert'); DROP TABLE Students; --

所以一般来说,没有办法做到这一点甚至是可靠的

简单的答案是你不能。只需编写代码,假设服务器将接收一个重击,那么您就不会出错。

这是一个很难解决的问题,自动检测哪些SQL查询是攻击(或简单的错误)。

有一些公司的产品试图做到这一点,如GreenSQL和DB Networks ADF-4200,通过应用启发式测试来查看查询是否看起来"可疑"。

但是他们更依赖于白名单的查询,你的应用程序运行。众所周知,启发式既有假阳性也有假阴性。还有一些查询类别是白名单和启发式方法都无法捕获的,比如对存储过程的调用。

有人也提到了mod_security,但这需要大量的配置,然后你又回到手工编码规则,将应用程序的合法查询列入白名单。

只要遵循良好的实践,如参数化和白名单,这样用户输入(或任何不可信的内容)永远不会作为代码计算。

其实没有一定的办法!
但是可以猜测攻击!
只需检查最常见的有用的SQL注入结构例如,在输入中扫描以下单词(不区分大小写):

union
select
drop
--
; 

如果你知道如何停止SQL注入,你不应该担心,你可以安全地运行查询。但据我所知,你想检测注射,所以我更希望你只是记录可疑的输入,然后手动决定!在大多数情况下,记录的查询是真实的注入。

测试字符串"-"answers";"……也可以是OR, AND,(等等。但你永远无法百分百确定这是一次攻击。

我想说,当您编写代码并使程序足够安全以减轻攻击时,假设所有用户输入都是攻击更安全,而不是试图追溯修复可能是攻击或可能不是攻击的东西。

您可以尝试以下操作:

  1. 如果输入字符串中没有要转义的字符,则这不是攻击企图。
  2. 将用户输入放在查询中,不带引号。
  3. 尝试检查查询语法而不运行它(例如让mysql以某种方式为你做(?))。
  4. 如果没有语法错误,则是攻击企图。

但是这样你只能检测潜在的成功的攻击尝试,而不是那些给出解析错误的。

您可以搜索某些键(union, delete, drop, ...)等等。如果确定原始查询永远不会包含--'n(新行),则搜索它。创建一个查询,总是返回一些值-如果用户恶意输入,它没有,这可能表明攻击。

但是因为用户倾向于总是犯错误或攻击服务器(数字,我会写字母来检查它会造成多大的混乱…)所有用户输入在使用前都应该过滤。

(笑话删除)

EDIT:您可以尝试以下操作:

  1. 如果输入字符串中没有要转义的字符,则这不是攻击企图。
  2. 将用户输入放在查询中,不带引号。
  3. 尝试检查查询语法而不运行它(例如让mysql以某种方式为你做(?))。
  4. 如果没有语法错误,则是攻击企图。

但是这样你只能检测潜在的成功的攻击尝试,而不是那些给出解析错误的。