Внедрение переменной массива PHP GET

Недавно я узнал, что можно реализовать массивы в PHP GET-переменные для выполнения кода?

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

Это был пример, который мне дали. Я не знаю, как это работает, и задавался вопросом, возможно ли это?

Ответы

Ответ 1

PHP проанализирует строку запроса и введет эти значения в супер-глобальный массив $_GET (тот же для $_POST, если это было сделано в форме с использованием POST, btw).

В вашем случае массив $_GET будет содержать следующее:

array
  'a' => 
    array
      0 => string 'asd' (length=3)
      1 => string 'asdasd' (length=6)
  'b' => 
    array
      0 => string '$a' (length=2)

Каждое значение, переданное в строке запроса, будет помещено PHP в массив $_GET, при необходимости создавая подмассивы, когда в строке запроса есть [].

Но это не вызывает никакого "выполнения кода": до тех пор, пока вы правильно обрабатываете вход (т.е. не доверяете вводам и не используете eval на нем или какую-либо плохую идею вроде этого), нет риска инъекции кода.

Ответ 2

Если вы не знаете, как получить защиту, то самое меньшее, что вы можете сделать, это отфильтровать массив $_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 от подозрительных символов, таких как [].

Спасибо

Ответ 3

echo $_GET['a'][0]; //prints "asd"
echo $_GET['a'][1]; //prints "asdasd"
echo $_GET['b'][0]; //prints "$a"

Ответ 4

Вышеописанное не позволяет строго выполнять код, но может изменить поток управления существующего кода, если он не учитывает факт, что данные могут быть массивом.

Причина, по которой это работает, заключается в том, что PHP интерпретирует переменные, заканчивающиеся на [] как массивы. Поэтому, если вы предоставляете несколько переменных GET с тем же именем, что и в [], PHP создает массив, содержащий все значения.

Ответ 5

Короче говоря: никакого исполнения кода. В противном случае, разве вы не думаете, что кто-то уже взломал Facebook?:)

Я думаю, что человек, который сказал вам, был смущен некоторыми другими ошибками, которые использовали глубокую вложенность массива, чтобы вызвать переполнение буфера/двойной свободный/какой-либо другой вектор взлома, который теоретически может использоваться для выполнения некоторого кода. Это программные ошибки, которые вы можете видеть каждый день во многих популярных программах. Они обычно быстро исправляются.

Вы можете найти дополнительную информацию на http://www.suspekt.org/

Ответ 6

Я думаю, что он говорит о чем-то, оценивающем иначе, когда передал массив

strcasecmp( $_GET['password'], $password ) == 0 ) { echo($secret); } ` Если вы передадите пустой массив в strcasecmp, он будет оценивать значение true по любой причине.

IE: index.php? password = []

Ответ 7

Похоже, вы что-то неправильно поняли.

В приведенном выше примере просто создается массив вроде

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

Это документировано и работает точно так, как предполагалось.

Ответ 8

Кто-то лгал вам, вы ничего не с этим поделаете, вы просто отправите массив вместо простой переменной.

попробуйте этот код

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

и получить доступ к нему, используя? x = 1, а затем? x [a] = 1 & x [b] = 2 ожидаемое поведение, а не инъекция, и вы не можете запускать с ним какой-либо код.

Ответ 9

ваш url хочет быть таким

www.mysite.com/page.php? имя = джон

но вы хотите, чтобы вставить что-то вроде этого

www.mysite.com/page.php? name [] = john

решение:

<?php
 $myname = is_array($_GET['name'])? "invalid" : $_GET['name'] ;
 echo $myname;
?>