Я новичок в PHP и работаю над базовым скриптом проверки подлинности. Я понимаю, что фильтрация входных данных и выходное экранирование являются жизненно важными по соображениям безопасности. Мой вопрос заключается в том, правильно ли защищен код, который я написал ниже? Сначала несколько поясняющих заметок.
Вот код (слегка очищенный):
$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-экранирование другого контента. например, котировки превращаются в "
, Это вздор.
Вместо этого, для входной санитарии, посмотрите:
проверяя, что это допустимая строка для используемой кодировки (надеюсь, 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); } }