Очистка пользовательских данных в GET с помощью PHP

Как вы дезинфицируете данные в $_GET -переменных с помощью PHP?

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

Ответ 1

Как вы дезинфицируете данные в $_GET-переменных с помощью PHP?

Вы не дезактивируете данные в $_GET. Это общий подход в PHP-скриптах, но он полностью неправильный *.

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

Итак, если вы встраиваете строку в SQL-запрос, вам нужно выйти из нее на выходе:

$sql= "SELECT * FROM accounts WHERE username='".pg_escape_string($_GET['username'])."'";

И если вы выплевываете строку в HTML, вам нужно ее избежать:

Cannot log in as <?php echo(htmlspecialchars($_GET['username'], ENT_QUOTES)) ?>.

Если вы сделали оба этих шага экранирования в массиве $_GET в начале, как рекомендовано людьми, которые не знают, что они делают:

$_GET['username']= htmlspecialchars(pg_escape_string($_GET['username']));

Затем, когда у вас был "& в вашем имени пользователя, таинственно превратится в '& в вашей базе данных, и если у вас был апостроф в вашем имени пользователя, он превратился бы в два апострофа на странице. Тогда, когда у вас есть форма с этими символами, в этом случае легко закончить двойное экранирование, когда они редактируются, поэтому многие плохие PHP CMS заканчиваются сломанными заголовками статей, такими как" Новые книги из O \\\\ \\\\\\\\\\\\\\\ 'Reilly".

Естественно, помня о pg_escape_string или mysql_real_escape_string и htmlspecialchars каждый раз, когда вы отправляете переменную, это немного утомительно, поэтому каждый хочет сделать это (неправильно) в одном месте в начале script. Для вывода HTML вы можете, по крайней мере, сохранить некоторую типизацию, указав функцию с коротким именем, которое выполняет эхо (htmlspecialchars (...)).

Для SQL вам лучше использовать параметризованные запросы. Для Postgres pg_query_params. Или действительно, подготовленные заявления, как вы упомянули (хотя я лично считаю их менее управляемыми). В любом случае вы можете забыть о "дезинфекции или утечке для SQL", но вы все равно должны избегать, если вы вставляете другие типы строк, включая HTML.

strip_tags() не является хорошим способом обработки ввода для отображения HTML. Раньше у него были проблемы с безопасностью, поскольку анализаторы браузеров на самом деле намного сложнее в интерпретации того, что может быть тегом, чем вы могли бы подумать. htmlspecialchars() почти всегда правильная вещь для использования вместо этого, так что, если кто-то набирает меньше, чем знак, они на самом деле получают буквальный знак меньше, чем знак, и не обнаруживают, что их текст таинственно исчезает.

(*: как общий подход к решению проблем с инъекциями, в любом случае. Естественно, существуют определенные для домена проверки, которые стоит делать на определенных полях, и есть полезные задачи очистки, которые вы можете сделать, например, удаление всех управляющих символов из представленных значений. Но это не то, что большинство программистов PHP подразумевает под дезинфекцией.)

Ответ 2

Если вы говорите о дезинфекции вывода, я бы порекомендовал хранить содержимое в вашей базе данных в нем в виде полной, неэкранированной формы, а затем избегать ее (htmlspecialchars или что-то еще), когда вы эхом отдаете данные, таким образом у вас есть больше возможностей для вывода. См. этот вопрос для обсуждения санитарии/экранирования содержимого базы данных.

В терминах сохранения в postgres используйте pg_escape_string для каждой переменной в запросе, чтобы избежать кавычек и, как правило, защищать от SQL-инъекции.

Edit:

Мои обычные шаги для хранения данных в базе данных и последующего их извлечения:

  • Вызвать функцию экранирования данных базы данных (pg_escape_string, mysql_escape_string и т.д.), чтобы избежать каждой входящей переменной $_GET, используемой в вашем запросе. Обратите внимание, что использование этих функций вместо addlashes приводит к отсутствию лишних косых черт в тексте при сохранении в базе данных.

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

Ответ 3

Вы должны дезинфицировать все запросы, а не только POST как GET.

Вы можете использовать функцию htmlentities(), функцию preg_replace() с регулярным выражением или фильтр с помощью cast:

<?
$id = (int)$_GET['id'];
?>

[] 's

Ответ 4

Санируйте свои входы в зависимости от того, куда он идет.

  • Если вы отобразите его (на странице или в качестве значения поля ввода), используйте htmlspecialchars и/или str_replace.
  • Если вы используете его как другой тип, произведите его.
  • Если вы включите его в SQL-запрос, сбегите его с помощью соответствующей функции, возможно, разделите html-теги, если хотите, чтобы они были полностью удалены (что не совпадает с экранированным).

То же самое для POST или даже данных из вашей БД, поскольку данные внутри вашей БД вообще не должны быть экранированы.

Две вещи, которые вы должны проверить:

  • Кодирование вашего ввода в сравнении с вашим скриптом PHP/выводом/таблицей DB
  • Если у вас включен [magic_quotes_gpc][1], вы должны либо отключить его (когда можете), либо stripslashes() значения GET, POST и COOKIE. magic_quotes_gpc устарел, вы должны дезинфицировать данные, которые вы управляете, в зависимости от использования этих данных.