我最近了解到可以将数组注入 PHP GET 变量以执行代码?
.php?a[]=asd&a[]=asdasd&b[]=$a
那是给我的例子。我不知道它是如何工作的,并且想知道这是否可能?
PHP 将解析查询字符串,并将这些值注入到$_GET
超级全局数组中($_POST
如果这是在使用 POST 的表单中完成的,顺便说一句)。
在您的情况下,该$_GET
数组将包含以下内容:
array
'a' =>
array
0 => string 'asd' (length=3)
1 => string 'asdasd' (length=6)
'b' =>
array
0 => string '$a' (length=2)
在查询字符串中传递的每个值都将由 PHP 放入数组中,如果需要,在查询字符串$_GET
中使用时创建子数组。[]
但这不会导致任何类型的“代码执行”:只要您正确处理输入(即不信任输入并eval
在其上使用,或任何类似的坏主意),就没有风险代码注入。
如果您不确定如何确保安全,您至少可以过滤 $_GET 数组。这是功能:
function filter_url($url)
{
if (is_array($url))
{
foreach ($url as $key => $value)
{
// recurssion
$url[$key] = filter_url($value);
}
return $url;
}
else
{
// remove everything except for a-zA-Z0-9_.-&=
$url = preg_replace('/[^a-zA-Z0-9_\.\-&=]/', '', $url);
return $url;
}
}
现在您可以像这样过滤 $_GET :
$_GET = filter_url($_GET);
这将从本质上清除 $_GET 数组中的可疑字符,例如 [ ]。
谢谢
长话短说:没有代码执行。否则,你不认为已经有人入侵了 Facebook 吗?:)
我认为告诉您的人对使用深度数组嵌套来触发缓冲区溢出/双重释放/其他一些黑客向量的其他一些错误感到困惑,理论上可以用来执行一些代码。这些是您在许多流行软件中每天都能看到的软件错误。他们通常会很快得到修补。
以上并不严格允许代码执行,但如果不考虑数据可能是数组的事实,它可能会改变现有代码的控制流。
上述工作的原因是因为 PHP 将以 [] 结尾的变量解释为数组。因此,如果您提供多个以 [] 结尾的同名 GET 变量,PHP 会创建一个包含所有值的数组。
echo $_GET['a'][0]; //prints "asd"
echo $_GET['a'][1]; //prints "asdasd"
echo $_GET['b'][0]; //prints "$a"
我认为他在谈论通过数组时评估不同的东西
strcasecmp( $_GET['password'], $password ) == 0 )
{
echo($secret);
}
` 如果您将一个空数组传递给 strcasecmp,无论出于何种原因,它都会评估为 true。
即:index.php?password=[]
好像你误会了什么。
上面的例子简单地创建了一个数组,如
Array (
[a] => Array (
[0] => asd
[1] => asdasd
)
[b] => Array ( [0] => $a )
)
这已记录在案并且完全按预期工作。
你的网址想要那样
www.mysite.com/page.php?姓名=约翰
但你想防止插入这样的东西
www.mysite.com/page.php?姓名[]=约翰
解决方案:
<?php
$myname = is_array($_GET['name'])? "invalid" : $_GET['name'] ;
echo $myname;
?>
有人对你撒谎,你不会用它执行任何东西,你只会发送一个数组而不是一个普通的变量。
试试这个代码
<?php
$x = $_GET['x'];
var_dump($x);
?>
并使用 ?x=1 然后 ?x[a]=1&x[b]=2 访问它,这是预期的行为,而不是注入,你不能用它运行任何代码。