Валидация форм в PHP
Думайте о БЕЗОПАСНОСТИ при обработке PHP-форм!
Эти страницы покажут, как обрабатывать PHP-формы с учётом безопасности. Правильная валидация данных формы важна для защиты вашей формы от хакеров и спамеров!
HTML-форма, с которой мы будем работать в этих главах, содержит различные поля ввода: обязательные и необязательные текстовые поля, радиокнопки и кнопку отправки:
Правила валидации для формы выше следующие:
| Поле | Правила валидации |
|---|---|
| Имя | Обязательно. + Должно содержать только буквы и пробелы |
| Обязательно. + Должен содержать корректный email-адрес (с @ и .) | |
| Веб-сайт | Необязательно. Если указано, должно содержать корректный URL |
| Комментарий | Необязательно. Многострочное поле ввода (textarea) |
| Пол | Обязательно. Нужно выбрать один вариант |
Сначала мы посмотрим на обычный HTML-код формы:
Текстовые поля
Поля имени, email и веб-сайта являются текстовыми элементами ввода, а поле комментария — это textarea.
HTML-код выглядит так:
Имя: <input type="text" name="name">
E-mail: <input type="text" name="email">
Веб-сайт: <input type="text" name="website">
Комментарий: <textarea name="comment" rows="5" cols="40"></textarea>
Радиокнопки
Поля пола являются радиокнопками, и HTML-код выглядит так:
Пол:
<input type="radio" name="gender" value="Женский">Женский
<input type="radio" name="gender" value="Мужской">Мужской
Элемент формы
HTML-код формы выглядит так:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Когда форма отправлена, данные формы отправляются с method="post".
Что такое переменная $_SERVER["PHP_SELF"]?
$_SERVER["PHP_SELF"] — это суперглобальная переменная, которая возвращает имя файла текущего выполняемого скрипта.
Таким образом, $_SERVER["PHP_SELF"] отправляет отправленные данные формы на ту же страницу, вместо перехода на другую страницу.
Таким образом, пользователь будет видеть сообщения об ошибках на той же странице, что и форма.
Что делает функция htmlspecialchars()?
Функция htmlspecialchars() преобразует специальные символы в HTML-сущности.
Это означает, что она заменит HTML-символы, такие как < и >,
на < и >.
Это предотвращает использование атакующими кода путём внедрения HTML- или Javascript-кода
(межсайтовый скриптинг) в формы.
Предупреждение!
Переменная $_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>
Этот код добавляет тег script и команду alert. И когда страница загружается, JavaScript-код будет выполнен (пользователь увидит окно предупреждения). Это лишь простой и безвредный пример того, как переменная PHP_SELF может быть использована.
Имейте в виду, что любой JavaScript-код может быть добавлен внутрь тега <script>! Хакер может перенаправить пользователя на файл на другом сервере, и этот файл может содержать вредоносный код, который может изменить глобальные переменные или отправить форму на другой адрес для сохранения данных пользователя, например.
Как избежать атак на $_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()) - Удалим обратные слеши
\из пользовательских данных (с помощью функции PHPstripslashes())
Следующий шаг — создать функцию, которая будет выполнять все проверки за нас (что гораздо удобнее, чем писать один и тот же код снова и снова).
Мы назовём функцию test_input().
Теперь мы можем
проверить каждую переменную $_POST с помощью функции test_input(), и скрипт выглядит так:
Пример
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<?php
// определение переменных и установка пустых значений
$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;
}
?>
<h2>Пример проверки формы на PHP</h2>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Имя: <input type="text" name="name">
<br><br>
E-mail: <input type="text" name="email">
<br><br>
Сайт: <input type="text" name="website">
<br><br>
Комментарий: <textarea name="comment" rows="5" cols="40"></textarea>
<br><br>
Пол:
<input type="radio" name="gender" value="female">Женский
<input type="radio" name="gender" value="male">Мужской
<br><br>
<input type="submit" name="submit" value="Отправить">
</form>
<?php
echo "<h2>Ваши данные:</h2>";
echo $name;
echo "<br>";
echo $email;
echo "<br>";
echo $website;
echo "<br>";
echo $comment;
echo "<br>";
echo $gender;
?>
</body>
</html>
Попробуйте сами »
Обратите внимание, что в начале скрипта мы проверяем, была ли форма отправлена,
используя $_SERVER["REQUEST_METHOD"].
Если REQUEST_METHOD равен POST, то
форма была отправлена — и её
следует проверить. Если она не была отправлена, пропускаем проверку и
отображаем пустую форму.
Однако в примере выше все поля ввода являются необязательными. Скрипт работает нормально, даже если пользователь не вводит никаких данных.
Следующий шаг — сделать поля ввода обязательными и создать сообщения об ошибках, если это необходимо.