Найдите уязвимость в этом PHP/Python-подобном примере построения SQL-запроса: query = "SELECT * FROM users WHERE name = '" + name + "'"; — объясните последствия, атаки SQL-инъекции и практические способы защиты
Уязвимость — классическая SQL-инъекция: строка запроса строится конкатенацией неподтверждённых данных пользователя, поэтому злоумышленник может подставить SQL-код. Примеры атак и последствия - Аутентификация/фильтрация обходится: если name="′OR′1′=′1"name = "' OR '1'='1"name="′OR′1′=′1", запрос станет SELECT * FROM users WHERE name = '' OR '1'='1' и вернёт все строки (логическое условие ′1′=′1′'1'='1'′1′=′1′ истинно). - Удаление/изменение данных: при name="′;DROPTABLEusers;−−"name = "'; DROP TABLE users; --"name="′;DROPTABLEusers;−−" итоговый SQL может выполнить удаление таблицы. - Чтение конфиденциальных данных (эксфильтрация), эскалация привилегий, удалённое выполнение команд (в некоторых СУБД через составные/многострочные запросы), DoS, компрометация сервера. - Слепая (time-based/boolean) инъекция позволяет извлечь данные по битам, даже если вывод скрыт. Практические способы защиты (приоритетные) 1. Параметризованные запросы / подготовленные выражения (самое надёжное). - PHP (PDO): $stmt = $pdo->prepare("SELECT * FROM users WHERE name = ?"); $stmt->execute([$name]); - Python (psycopg2): cur.execute("SELECT * FROM users WHERE name = %s", (name,)) Параметры передаются как данные, а не как часть SQL. 2. Привилегии на минимально необходимые (least privilege): учётная запись БД для приложения не должна иметь права DROP/ALTER/CREATE, если это не нужно. 3. Валидация/белый список: проверяйте формат входа (например, разрешённый набор символов, длину). Подходит, когда ожидается конкретный формат (имя, email, id). 4. Экранирование — только как дополнение, не как основной метод: используйте встроенные функции СУБД/драйвера (напр., mysqli_real_escape_string) если параметризация невозможна, но это более хрупко. 5. Отключение возможности выполнения нескольких операторов в одном запросе (если поддерживается драйвером) и использование ORM/библиотек, которые по умолчанию параметризуют запросы. 6. Мониторинг и WAF: логирование подозрительных запросов, Web Application Firewall как дополнительный барьер. Краткое резюме Никогда не вставляйте напрямую данные пользователя в текст SQL-запроса — используйте подготовленные запросы/параметры и минимум привилегий. Это устраняет большинство векторов SQL-инъекций.
Примеры атак и последствия
- Аутентификация/фильтрация обходится: если name="′OR′1′=′1"name = "' OR '1'='1"name="′OR′1′=′1", запрос станет
SELECT * FROM users WHERE name = '' OR '1'='1'
и вернёт все строки (логическое условие ′1′=′1′'1'='1'′1′=′1′ истинно).
- Удаление/изменение данных: при name="′;DROPTABLEusers;−−"name = "'; DROP TABLE users; --"name="′;DROPTABLEusers;−−" итоговый SQL может выполнить удаление таблицы.
- Чтение конфиденциальных данных (эксфильтрация), эскалация привилегий, удалённое выполнение команд (в некоторых СУБД через составные/многострочные запросы), DoS, компрометация сервера.
- Слепая (time-based/boolean) инъекция позволяет извлечь данные по битам, даже если вывод скрыт.
Практические способы защиты (приоритетные)
1. Параметризованные запросы / подготовленные выражения (самое надёжное).
- PHP (PDO):
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = ?");
$stmt->execute([$name]);
- Python (psycopg2):
cur.execute("SELECT * FROM users WHERE name = %s", (name,))
Параметры передаются как данные, а не как часть SQL.
2. Привилегии на минимально необходимые (least privilege): учётная запись БД для приложения не должна иметь права DROP/ALTER/CREATE, если это не нужно.
3. Валидация/белый список: проверяйте формат входа (например, разрешённый набор символов, длину). Подходит, когда ожидается конкретный формат (имя, email, id).
4. Экранирование — только как дополнение, не как основной метод: используйте встроенные функции СУБД/драйвера (напр., mysqli_real_escape_string) если параметризация невозможна, но это более хрупко.
5. Отключение возможности выполнения нескольких операторов в одном запросе (если поддерживается драйвером) и использование ORM/библиотек, которые по умолчанию параметризуют запросы.
6. Мониторинг и WAF: логирование подозрительных запросов, Web Application Firewall как дополнительный барьер.
Краткое резюме
Никогда не вставляйте напрямую данные пользователя в текст SQL-запроса — используйте подготовленные запросы/параметры и минимум привилегий. Это устраняет большинство векторов SQL-инъекций.