Новый PHP input_filter не читает массивы $ _GET или $ _POST - PullRequest
11 голосов
/ 18 ноября 2008

В PHP 5.2 была добавлена ​​хорошая функция безопасности под названием "input_filter", поэтому вместо того, чтобы говорить:

$name = $_GET['name'];

Теперь вы можете сказать:

$name = filter_input (INPUT_GET, 'name', FILTER_SANITIZE_STRING);

и он автоматически дезинфицирует вашу строку, также есть:

  • FILTER_SANITIZE_ENCODED
  • FILTER_SANITIZE_NUMBER_INT
  • FILTER_SANITIZE_EMAIL
  • FILTER_SANITIZE_URL

и т.д.. так что это очень удобная функция безопасности, и я хочу полностью переключиться на нее.

Проблема в том, что ... Я часто манипулирую массивами $ _GET и $ _POST перед их обработкой, например:

$ _ GET ['name'] = '(имя по умолчанию)';

но похоже, что filter_input не имеет доступа к изменениям в $ _GET, так как он читает «INPUT_GET», который имеет тип int (?). Было бы хорошо, если бы я мог заставить filter_input читать $ _GET вместо этого, но:

$name = filter_input ( $_GET, 'name', FILTER_SANITIZE_STRING );

выдает ошибку:

Warning: filter_input() expects parameter 1 to be long, array given.

Может кто-нибудь придумать, как я мог бы:

  • манипулирует источником INPUT_GET (где бы он ни был), чтобы я мог изменить его значения, прежде чем filter_input сможет их прочитать
  • получить filter_input для чтения $_GET

ADDENDUM:

<Ч />

Рич спросил: «В любом случае, почему вы изменяете массивы, конечно, вы хотите, чтобы они были входными данными, а не чем-то, что вы программно вставили».

Это просто очень удобное место для предварительной обработки входящих переменных, например, для того, чтобы:

  • установить значения по умолчанию (если $ _GET ['state'] = '', то $ _GET ['state'] = 'AL')
  • выполнить ручную обработку (удалить все пробелы и т. Д.)
  • безопасность (некоторые из них будут выполнены filter_input сейчас)

Тогда я знаю, что когда я получу входящую переменную, она будет безопасной и действительной. Конечно, я мог бы скопировать массив $ _GET в другой массив и обработать массив THAT, но это просто ненужный шаг, поскольку I $ _GET уже является работающим массивом, поэтому имеет смысл делать это с этими уже существующими системными массивами.

Ответы [ 6 ]

19 голосов
/ 18 ноября 2008

Вы можете вручную заставить его снова считывать массивы, используя filter_var и filter_var_array

$name = filter_var ( $_GET['name'], FILTER_SANITIZE_STRING );
6 голосов
/ 24 августа 2010

Удобный способ сделать это без изменения глобального массива:

if (!($name = filter_input(INPUT_GET, 'name'))) {
    $name = 'default_value';
}

Или используя троичный оператор:

$name = ($name = filter_input(INPUT_GET, 'name')) ? $name : 'default_value';
2 голосов
/ 08 декабря 2013

Как было предложено Jrngs:

Пропустить программную модификацию суперглобальной переменной запроса и определить и использовать новые обычные переменные.

Мало того, что создание новой переменной быстрее, чем доступ и изменение значения в ассоциативном массиве (массив со строковыми индексами), это также лучший способ.

Смысл функции filter_input в том, чтобы в конечном итоге УДАЛИТЬ использование суперглобальных переменных, поскольку они являются наиболее опасной точкой из всех PHP-скриптов и наиболее частой причиной уязвимостей безопасности (как для XSS, так и для SQL). уколы), а также ошибки и путаница, особенно в крупных проектах.

Например, переменные $ _GET и $ _REQUEST должны возвращать одно и то же значение для одного и того же ключа:

.../?var=1
var_dump($_GET['var']); ---> string '1' (length=1)
var_dump($_REQUEST['var']); ---> string '1' (length=1)
$_GET['var'] = 2;
var_dump($_GET['var']); ---> int 2
var_dump($_REQUEST['var']; ---> string '1' (length=1)

Не говоря уже о том, что суперглобальные переменные едва ли имеют какой-либо смысл в объектно-ориентированном коде.

Следовательно, если функция filter_input получит доступ к суперглобальным переменным $ _GET / $ _ POST / $ _ REQUEST, это полностью лишит смысла эту функцию. И вы определенно НЕ ДОЛЖНЫ использовать для этого предлагаемую filter_var функцию:

filter_var($_GET['var'],FILTER_SANITIZE_STRING); ---> JUST NO!

Функция filter_var была создана для того, чтобы обеспечить функциональность фильтрации / очистки для переменных, не являющихся запросами, а не для такого рода "взлома". Что вы делаете, так это то, что вы, по сути, берете фильтры из функции filter_input , которая изначально была создана для обеспечения лучшего и более безопасного доступа к данным запроса, полностью обходя саму функцию, обращаясь к данным запроса точно так же filter_input был создан для замены и применения фильтров, предоставленных filter_input , к данным запроса. И это просто неправильно. :)

2 голосов
/ 18 ноября 2008

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

Возможно, было бы полезно больше кода / контекста.

1 голос
/ 18 ноября 2008

Бит INPUT_GET - это просто идентификатор (число), сообщающий PHP, что ему нужно получить значение из $ _GET.

Если вы хотите использовать filter_input для всего массива, вам нужно пройти через него, отправить каждый ключ массива в filter_input и вернуть результат обратно в $ _GET.

Вероятно, будет так же просто написать функцию, которая выполняет очистку самостоятельно, и это также должно позволить вам иметь дело с массивами в массивах (не похоже, что filter_input сделает это). В комментариях к документации PHP.net есть несколько таких примеров функций, например, удаление «магических кавычек». См. здесь для примера.

0 голосов
/ 28 ноября 2011

Новый входной_фильтр PHP не читает массивы $_GET или $_POST. Если вы перезаписываете глобальные (например, $_GET, $_POST), тогда не переходите на filter_input. Вместо этого используйте filter_var ( $_GET['name'], FILTER_SANITIZE_STRING ), передавая переменную вручную.

...