我最近了解到可以将数组注入到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 = filter_url($_GET);
echo $_GET['a'][0]; //prints "asd"
echo $_GET['a'][1]; //prints "asdasd"
echo $_GET['b'][0]; //prints "$a"
以上并不严格允许代码执行,但如果现有代码没有考虑到数据可能是数组,则可能会改变其控制流程。
上述方法之所以可行,是因为PHP将以[]结尾的变量解释为数组。因此,如果您提供多个相同名称以[]结尾的GET变量,PHP将创建包含所有值的数组。
我认为他在谈论当传入一个数组时,某些内容会被不同地评估。
strcasecmp( $_GET['password'], $password ) == 0 )
{
echo($secret);
}
如果你将一个空数组传入strcasecmp函数中,由于某种原因,它将被评估为true。
例如:index.php?password=[]
看起来你误解了一些东西。
上面的例子只是简单地创建了一个数组,如下所示:
Array (
[a] => Array (
[0] => asd
[1] => asdasd
)
[b] => Array ( [0] => $a )
)
这是有文档记录的,而且完全按照预期工作。
有人骗了你,你不会用那个执行任何东西,你只会发送一个数组而不是一个普通变量。
试试这段代码
<?php
$x = $_GET['x'];
var_dump($x);
?>
通过使用 ?x=1 并且 ?x[a]=1&x[b]=2 访问它,这是预期的行为,而不是注入,您无法使用它运行任何代码。
你的网址应该是这样的
www.mysite.com/page.php?name=john
但是你想要防止插入类似这样的内容
www.mysite.com/page.php?name[]=john
解决方案:<?php
$myname = is_array($_GET['name'])? "invalid" : $_GET['name'] ;
echo $myname;
?>