我总是担心我的PHP应用程序中的安全性,我只是(可能)想到了黑客可能会杀死我的脚本的方式。目前我的应用程序采用表单数据并通过AJAX将其作为数组提交给PHP脚本,然后遍历此数组。
foreach($_POST['form_data'] as $field => $value){
//Do something here.
}
但是,如果黑客伪造一个AJAX请求,并重复提交带有1000亿随机元素的'form_data'数组怎么办?循环必须遍历每个元素,可能导致DoS(或至少减慢服务),是否正确?
我在这里没有完全接受过教育,所以我可能会有一些不正确的假设。感谢您的任何意见!
答案 0 :(得分:13)
这不是问题:PHP使用max_input_vars
directive限制POST变量的最大数量,默认为1000个变量。
这个限制实际上是为了防止比你想到的更严重的DOS攻击类型(实际上,迭代几千个数组元素就像什么都没有),即基于哈希表冲突的攻击(通常称为HashDOS)。有关该问题的详细信息,请参阅我的文章Supercolliding a PHP array。
答案 1 :(得分:6)
循环必须遍历每个元素,可能导致DoS(或至少减慢服务),是否正确?
这是真的(尽管Web服务器的POST大小限制,并且脚本的内存限制可能会在100000000000项之前很久就停止了)。
同样@duskwulf指出,PHP> = 5.3.9有the max_input_vars
variable,默认设置为1000。
您仍然可以进行尺寸检查以确保安全。
答案 2 :(得分:3)
我通常使用array_key_exists()
来做这种事情。
如果您想维持当前循环,请尝试以下操作:
$allowed = array('name', 'address', 'phone', 'etc');
foreach($_POST['form_data'] as $field => $value)
{
if(array_key_exists($field, $allowed))
{
//do something here
}
}
或者看看这样的事情:
$vals = array_intersect($allowed, $_POST)
答案 3 :(得分:1)
是的,当然黑客可能会发送所有这些数据,并且肯定是不明智的,无法迭代它们。可以做许多意想不到的事情。
我建议你将你的申请减少到只接受的那些申请。你现在正在做的是从form_data
获取所有值。
而不是这个,你应该知道期望什么值。可能类似于name
,address
,phone
,只能迭代这些已知值。
因此,可能发生的问题将减少但不会完全阻止。通过额外的尺寸检查,如Pekka建议的那样,您将进一步降低风险。
答案 4 :(得分:0)
只有最后版本(5.3.10)才有使用责任,默认情况下支持max_input_vars
。但是有一个很好的扩展 - Suhosin,可以防止这种类型的攻击,就像许多早期版本的PHP一样。