ВНИМАНИЕ: Запись на курсы по HTML, CSS, JavaScript, PHP, Python, React, Vue, Laravel и другим фреймворкам и CMS,
а также: помощь в поиске работы и заказов, стажировка на реальных проектах→
62 of 95 menu
Бесплатный курс по выкладке сайтов на хостинг. Разбираем все нюансы! Начало 14 октября. Жми для записи!

Список значений в SQL в PHP

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

К примеру, у нас на сайте может быть несколько ролей: админ, ученик и учитель. Пусть пользователь может зарегистрироваться по своему выбору: или учеником, или учителем. Сделаем для этого выпадающий список:

<form action="" method="POST"> <input name="login"> <input name="password" type="password"> <select name="role"> <option value="2">ученик</option> <option value="3">учитель</option> </select> <input type="submit"> </form>

Теперь у нас нет вариантов - мы обязательно должны вставлять роль из переменной:

<?php $login = $_POST['login']; $password = $_POST['password']; $role = $_POST['role']; $query = "INSERT INTO users SET login='$login', password='$password', role=$role "; mysqli_query($link, $query); ?>

Но мы опять возвращаемся к пробеме с подменой. Ведь злоумышленник опять может поменять значение поля, в нашем случае уже селекта, на 1 и стать админом.

В этом случае есть два варианта решения проблемы: черный список и белый список. Давайте их рассмотрим.

Черный список

Под черным списком имеется ввиду набор значений, которые мы запрещаем. В нашем случае мы хотим запретить роль со значением 1. В этом случае защищенный код будет следующем:

<?php $login = $_POST['login']; $password = $_POST['password']; $role = $_POST['role']; if ($role !== 1) { // 1 в черном списке $query = "INSERT INTO users SET login='$login', password='$password', role=$role "; mysqli_query($link, $query); } else { // попытка взлома } ?>

Белый список

Черные списки, однако, как правило - плохое решение. Более безопасно делать списки с разрешенными значениями. Такие списки называются белыми.

Давайте исправим нашу уязвимость с помощью белого списка разрешенных значений:

<?php $login = $_POST['login']; $password = $_POST['password']; $role = $_POST['role']; $list = [2, 3]; // белый список if (in_array($role, $list)) { $query = "INSERT INTO users SET login='$login', password='$password', role=$role "; mysqli_query($link, $query); } else { // попытка взлома } ?>

Практические задачи

Воспроизведите пример, приведенный в уроке. Проверьте наличие уязвимости. Устраните ее.

В приведенном коде также есть возможность провести SQL-инъекцию. Придумайте, как ее сделать. Воспользуйтесь уявимостью. Устраните уязвимость.

byenru