Проверка формы PHP
В этой и следующей главах показано, как использовать PHP для проверки данных формы.
Проверка формы PHP
Думайте о БЕЗОПАСНОСТИ при обработке PHP-форм!
На этих страницах показано, как обрабатывать PHP-формы с учетом требований безопасности. Правильная проверка данных формы важна для защиты вашей формы от хакеров и спамеров!
HTML-форма, над которой мы будем работать в этих главах, содержит различные поля ввода: обязательные и необязательные текстовые поля, переключатели и кнопку отправки:
Правила проверки для приведенной выше формы следующие:
Field | Validation Rules |
---|---|
Name | Required. + Must only contain letters and whitespace |
Required. + Must contain a valid email address (with @ and .) | |
Website | Optional. If present, it must contain a valid URL |
Comment | Optional. Multi-line input field (textarea) |
Gender | Required. Must select one |
Сначала мы рассмотрим простой HTML-код формы:
Текстовые поля
Поля имени, электронной почты и веб-сайта являются элементами ввода текста, а поле комментария — текстовой областью. HTML-код выглядит следующим образом:
Name: <input type="text" name="name">
E-mail: <input type="text" name="email">
Website: <input type="text" name="website">
Comment: <textarea name="comment" rows="5" cols="40"></textarea>
Радио-кнопки
Поля пола — это переключатели, а HTML-код выглядит следующим образом:
Gender:
<input type="radio" name="gender"
value="female">Female
<input type="radio" name="gender" value="male">Male
<input type="radio" name="gender" value="other">Other
Элемент формы
HTML-код формы выглядит следующим образом:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Когда форма отправляется, данные формы отправляются с помощью метода = "post".
Что такое переменная $_SERVER["PHP_SELF"]?
$_SERVER["PHP_SELF"] — это суперглобальная переменная, которая возвращает имя файла исполняемого в данный момент скрипта.
Таким образом, $_SERVER["PHP_SELF"] отправляет отправленные данные формы на саму страницу вместо перехода на другую страницу. Таким образом, пользователь будет получать сообщения об ошибках на той же странице, что и форма.
Что такое функция htmlspecialchars()?
Функция htmlspecialchars() преобразует специальные символы в объекты HTML. Это означает, что он заменит символы HTML, такие как < и >, на < и >. Это предотвращает использование кода злоумышленниками путем внедрения кода HTML или Javascript (атаки с использованием межсайтовых сценариев) в формах.
Большое примечание о безопасности форм PHP
Хакеры могут использовать переменную $_SERVER["PHP_SELF"]!
Если на вашей странице используется PHP_SELF, пользователь может ввести косую черту (/), а затем выполнить некоторые команды межсайтового скриптинга (XSS).
Межсайтовый скриптинг (XSS) — это тип уязвимости компьютерной безопасности, обычно встречающийся в веб-приложениях. XSS позволяет злоумышленникам внедрить скрипт на стороне клиента в веб-страницы, просматриваемые другими пользователями.
Предположим, у нас есть следующая форма на странице с именем «test_form.php»:
<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">
Теперь, если пользователь вводит обычный URL-адрес в адресной строке, например «http://www.example.com/test_form.php», приведенный выше код будет преобразован в:
<form method="post" action="test_form.php">
Все идет нормально.
Однако учтите, что пользователь вводит следующий URL-адрес в адресную строку:
http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E
В этом случае приведенный выше код будет преобразован в:
<form method="post" action="test_form.php/"><script>alert('hacked')</script>
Этот код добавляет тег скрипта и команду оповещения. И когда страница загрузится, код JavaScript будет выполнен (пользователь увидит окно с предупреждением). Это просто простой и безобидный пример того, как можно использовать переменную PHP_SELF.
Имейте в виду, что внутри тега <script> можно добавить любой код JavaScript! Хакер может перенаправить пользователя к файлу на другом сервере, и этот файл может содержать вредоносный код, который может изменить глобальные переменные или отправить форму по другому адресу, например, для сохранения данных пользователя.
Как избежать эксплойтов $_SERVER["PHP_SELF"]?
Эксплойтов $_SERVER["PHP_SELF"] можно избежать, используя функцию htmlspecialchars().
Код формы должен выглядеть так:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Функция htmlspecialchars() преобразует специальные символы в объекты HTML. Теперь, если пользователь попытается использовать переменную PHP_SELF, это приведет к следующему выводу:
<form method="post" action="test_form.php/"><script>alert('hacked')</script>">
Попытка эксплойта не удалась, и никакого вреда не было нанесено!
Проверка данных формы с помощью PHP
Первое, что мы сделаем, это передадим все переменные через функцию PHP htmlspecialchars().
Когда мы используем функцию htmlspecialchars(); затем, если пользователь попытается отправить следующее в текстовое поле:
<script>location.href('http://www.hacked.com')</script>
- это не будет выполнено, потому что будет сохранено как экранированный код HTML, например:
<script>location.href('http://www.hacked.com')</script>
Код теперь можно безопасно отображать на странице или в электронном письме.
Мы также сделаем еще две вещи, когда пользователь отправит форму:
- Удаление ненужных символов (лишний пробел, табуляция, перевод строки) из вводимых пользователем данных (с помощью функции PHP trim())
- Удалить обратную косую черту (\) из входных данных пользователя (с помощью функции PHP stripslashes())
Следующим шагом будет создание функции, которая будет делать всю проверку за нас (что гораздо удобнее, чем писать один и тот же код снова и снова).
Мы назовем функцию test_input().
Теперь мы можем проверить каждую переменную $_POST с помощью функции test_input(), и скрипт выглядит так:
Пример
<?php
// define variables and set to empty values
$name = $email = $gender = $comment = $website = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = test_input($_POST["name"]);
$email = test_input($_POST["email"]);
$website = test_input($_POST["website"]);
$comment = test_input($_POST["comment"]);
$gender = test_input($_POST["gender"]);
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
Обратите внимание, что в начале скрипта мы проверяем, была ли форма отправлена, используя $_SERVER["REQUEST_METHOD"]. Если REQUEST_METHOD имеет значение POST, то форма была отправлена и должна быть проверена. Если он не был отправлен, пропустите проверку и отобразите пустую форму.
Однако в приведенном выше примере все поля ввода являются необязательными. Скрипт отлично работает, даже если пользователь не вводит никаких данных.
Следующий шаг — сделать поля ввода обязательными и при необходимости создать сообщения об ошибках.