15

我最近了解到可以将数组注入 PHP GET 变量以执行代码?

.php?a[]=asd&a[]=asdasd&b[]=$a

那是给我的例子。我不知道它是如何工作的,并且想知道这是否可能?

4

9 回答 9

9

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在其上使用,或任何类似的坏主意),就没有风险代码注入。

于 2009-12-11T05:34:13.920 回答
7

如果您不确定如何确保安全,您至少可以过滤 $_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 数组中的可疑字符,例如 [ ]。

谢谢

于 2009-12-11T06:56:10.743 回答
2

长话短说:没有代码执行。否则,你不认为已经有人入侵了 Facebook 吗?:)

我认为告诉您的人对使用深度数组嵌套来触发缓冲区溢出/双重释放/其他一些黑客向量的其他一些错误感到困惑,理论上可以用来执行一些代码。这些是您在许多流行软件中每天都能看到的软件错误。他们通常会很快得到修补。

您可以在http://www.suspekt.org/找到更多信息

于 2009-12-11T05:52:27.557 回答
2

以上并不严格允许代码执行,但如果不考虑数据可能是数组的事实,它可能会改变现有代码的控制流。

上述工作的原因是因为 PHP 将以 [] 结尾的变量解释为数组。因此,如果您提供多个以 [] 结尾的同名 GET 变量,PHP 会创建一个包含所有值的数组。

于 2009-12-11T05:35:51.740 回答
2
echo $_GET['a'][0]; //prints "asd"
echo $_GET['a'][1]; //prints "asdasd"
echo $_GET['b'][0]; //prints "$a"
于 2009-12-11T05:34:21.267 回答
2

我认为他在谈论通过数组时评估不同的东西

strcasecmp( $_GET['password'], $password ) == 0 ) { echo($secret); } ` 如果您将一个空数组传递给 strcasecmp,无论出于何种原因,它都会评估为 true。

即:index.php?password=[]

于 2013-09-18T23:57:43.647 回答
1

好像你误会了什么。

上面的例子简单地创建了一个数组,如

Array (
  [a] => Array (
    [0] => asd
    [1] => asdasd
  )
  [b] => Array ( [0] => $a )
)

这已记录在案并且完全按预期工作。

于 2009-12-11T05:35:16.070 回答
0

你的网址想要那样

www.mysite.com/page.php?姓名=约翰

但你想防止插入这样的东西

www.mysite.com/page.php?姓名[]=约翰

解决方案:

<?php
 $myname = is_array($_GET['name'])? "invalid" : $_GET['name'] ;
 echo $myname;
?>
于 2014-08-10T01:29:04.370 回答
0

有人对你撒谎,你不会用它执行任何东西,你只会发送一个数组而不是一个普通的变量。

试试这个代码

<?php
    $x = $_GET['x'];
    var_dump($x);
?>

并使用 ?x=1 然后 ?x[a]=1&x[b]=2 访问它,这是预期的行为,而不是注入,你不能用它运行任何代码。

于 2009-12-11T05:34:00.567 回答