我知道这个话题已经被讨论到死了,但是我想从社区中得到一些关于我们web应用程序安全性的反馈。
我们有标准的LAMP堆栈web应用程序,其中包含使用mysqli_query
执行的大量数据库查询。这些查询目前没有参数化,但是使用addslashes
对输入进行了一些简单的转义。
我的任务是使这个系统更安全,因为我们将很快进行渗透测试。上述高层知道参数化查询是使系统更安全的方法,但他们不想花费时间和精力重写应用程序中的所有查询,也不想改变我们必须使它们正常工作的框架。
基本上我在问我有什么选择?
我在输入端运行了mysqli_real_escape_string
。我设置了一个过滤器,它不允许像SELECT, WHERE, UNION这样的词被传递,我想这让它更安全。我知道mysqli_query
只允许一次运行一个查询,所以那里有一些安全性(从连接更新到选择的结束)。
我这里还有其他选择吗?
编辑:我可能应该补充说,如果有人能够提供一个攻击的例子,这是完全不可避免的没有参数化查询,这也将是有帮助的。我们有一个像这样的查询:
SELECT
pl.created
p.LoginName,
pl.username_entered,
pl.ip_address
FROM loginattempts pl
LEFT JOIN people p ON p.PersonnelId = pl.personnel_id
WHERE p.personnelid = $id
AND pl.created > $date1
AND pl.created < $date2
我已经将UNION查询替换为$id UNION SELECT * FROM p WHERE 1 = 1
之类的东西,我可以通过不允许SELECT/UNION来防止这种情况,但我确信还有无数其他类型的攻击我无法想到。谁能再提几个建议?
我已经说服了我的上级,我们需要将查询重写为参数化语句。他们估计可能需要几个月的时间,但这是必须要做的。赢了。我的想法吗?
更新2
不幸的是,我还没能说服当权者,我们需要将所有的查询重写为参数化的查询。我们提出的策略是测试每个输入,如下所示:
如果用户提供的输入为is_int,则将其强制转换为is_int。实数也是一样。在字符数据上运行mysqli_real_escape_string。将查询中的所有参数更改为引号字符串,即
WHERE staffName = ' . $blah . '
根据这个答案,我们是100%安全的,因为我们没有在任何时候改变字符集,我们一直使用带有latin1字符集的PHP5.5
更新3
这个问题被标记为重复,但在我看来,这个问题仍然没有得到回答。根据更新编号。我们发现一些强烈的意见,mysqli_real_escape string函数可以防止攻击,显然是"100%安全"。从那以后,就没有一个好的反驳论据(例如,一个攻击的演示,如果使用得当,可以击败它)。
- 检查每个用户输入的数据类型和适用的正则表达式(黄金法则是:永远不要相信用户输入)
- 使用预编译语句
- serious: prepared statements:)
这需要大量的工作,特别是当你的应用程序处于糟糕的状态时(就像你的情况一样),但这是拥有一个体面的安全级别的最好方法
另一种方式(我建议反对)可能是使用mod_security或WAF来过滤注入尝试的虚拟补丁,但首先要做的是:尝试编写健壮的应用程序(虚拟补丁似乎是一种懒惰的修复方法,但实际上也需要大量的工作和测试,应该只在已经很强大的应用程序代码上使用)
我这里还有其他选择吗?
。没有任何外部措施,比如你试图实施的措施,被证明有任何帮助。您的网站仍有漏洞。
我在输入上运行了mysqli_real_escape_string
恭喜你,你刚刚重新发明了臭名昭著的magic_quotes
特性,这个特性被证明是无用的,现在已经从语言中被驱逐了。
jffyi, mysqli_real_escape_string与SQL注入无关。
此外,将它与现有的addslashes()
调用相结合,您正在破坏数据,其中的斜杠数量加倍。
我已经设置了一个过滤器,我想这会使它更安全。
它不是。SQL注入不是添加一些单词。
同样,这种方法被称为"黑名单"。事实证明它本质上是不可靠的。黑名单本质上是不完整的,不管有多少"建议"。
我知道mysqli_query只允许一次运行一个查询,所以这里有一些安全性
没有。SQL注入不是添加另一个查询。
为什么我把这个问题关闭为"如何在PHP中防止sql注入?"的副本?
因为这些问题是互斥的,不能在同一站点上共存。
如果我们同意唯一正确的答案是使用预处理语句,那么问题就来了:"我怎样才能避免使用无预处理语句";这没什么意义。
同时,如果OP设法迫使我们给出他们迫切想要的肯定答案,它将使其他问题过时。如果没有准备好的语句,为什么要使用准备好的语句呢?
另外,这个问题也太局部化了。它寻求的不是洞察力,而是借口。除了执政官,谁也不能找借口。一个借口,让他们使用一种被证明是不安全的方法。虽然这取决于他们,但这使得这个问题对社区来说基本上毫无用处。