Фильтрация входных форм PHP

Я новичок в PHP и работаю над базовым скриптом проверки подлинности. Я понимаю, что фильтрация входных данных и выходное экранирование являются жизненно важными по соображениям безопасности. Мой вопрос заключается в том, правильно ли защищен код, который я написал ниже? Сначала несколько поясняющих заметок.

  1. Я понимаю, что существует разница между дезинфекцией и валидацией. В приведенном ниже поле примера поле представляет собой обычный текст, поэтому все, что мне нужно сделать, это его дезинфицировать.
  2. $ clean ['myfield'] – это значение, которое я бы отправил в базу данных MySQL. Я использую подготовленные инструкции для взаимодействия с базой данных.
  3. $ html ['myfield'] – это значение, которое я отправляю обратно клиенту, так что, когда он / она отправляет форму с недопустимыми / неполными данными, дезинфицированные поля, у которых есть данные в них, будут заселены, поэтому им не нужно введите все с нуля.

Вот код (слегка очищенный):

$clean = array(); $html = array(); $_POST['fname'] = filter_var($_POST['fname'], FILTER_SANITIZE_STRING); $clean['fname'] = $_POST['fname']; $html['fname'] = htmlentities($clean['fname'], ENT_QUOTES, 'UTF-8'); if ($_POST['fname'] == "") { $formerrors .= 'Please enter a valid first name.<br/><br/>'; } else { $formerrors .= 'Name is valid!<br/><br/>'; } 

Спасибо за вашу помощь!

~ Jared

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

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

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

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

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

Да. Увы, FILTER_SANITIZE_STRING никоим образом не является здравым санитаром. Он полностью удаляет некоторый контент ( strip_tags , который сам по себе очень strip_tags ), в то время как HTML-экранирование другого контента. например, котировки превращаются в &#34; , Это вздор.

Вместо этого, для входной санитарии, посмотрите:

  • проверяя, что это допустимая строка для используемой кодировки (надеюсь, UTF-8, см., например, это регулярное выражение для этого);

  • удаление управляющих символов, U + 0000-U + 001F и U + 007F-U + 009F. Разрешить использование новой строки только на преднамеренных многострочных текстовых полях;

  • удаление символов, которые не подходят для разметки ;

  • проверка входных данных соответствует требованиям приложения в поле за полем, для данных, модель контента которых более специфична, чем произвольные текстовые строки. Хотя ваше экранирование должно корректно обрабатывать символ < , это, вероятно, хорошая идея, чтобы избавиться от него в начале полей, где нет смысла его иметь.

Для шага выхода на выходе я обычно предпочитаю htmlspecialchars() для htmlentities() , хотя ваше правильное использование аргумента UTF-8 останавливает эту функцию в том, как это обычно происходит.

В зависимости от того, что вы хотите защитить, фильтр, который вы вызываете, может быть чрезмерно активным (см. Комментарии). В случае инъекций вы должны быть в безопасности, так как вы используете подготовленные заявления (см. Этот ответ )

В примечании к дизайну, которое вы, возможно, захотите сначала отфильтровать, а затем проверьте пустые значения. При этом вы можете сократить свой код;)

Я понимаю, что входная фильтрация … жизненно важна по соображениям безопасности.

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

все, что мне нужно сделать, это дезинфицировать его.

Нет такой вещи, как « общая дезинфекция ». Вы должны понимать каждый конкретный случай и его ограничения. Например, для базы данных вам нужно использовать несколько различных методов санитарии, а не одну. Хотя для имен файлов это будет совсем другое.

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

Таким образом, вы не должны касаться данных вообще. Просто оставьте это как есть.

Вот код (слегка очищенный):

Кажется, в вашем коде есть избыток.
вы дважды очищаете данные HTML, хотя возможно, что вам это совсем не понадобится. и по какой-то причине вы делаете ошибку об успехе.

Я бы сделал это довольно так

 $formerrors = ''; if ($_POST['fname'] == "") { $formerrors .= 'Please enter a valid first name.<br/><br/>'; } if (!$formerrors) { $html = array(); foreach ($_POST as $key => $val) { $html[$key] = htmlspecialchars($val,ENT_QUOTES); } }