Ответ
SQL-инъекция (SQL Injection) — это тип атаки на веб-приложения, при которой злоумышленник внедряет произвольный SQL-код в запросы к базе данных. Это становится возможным, когда приложение напрямую вставляет пользовательский ввод в SQL-запрос без должной обработки.
Успешная атака может привести к утечке, изменению или удалению данных, а в некоторых случаях — к полному захвату контроля над сервером.
Пример уязвимости (Python):
Предположим, есть код для поиска пользователя по имени. Ввод от пользователя напрямую конкатенируется со строкой запроса.
# НЕБЕЗОПАСНЫЙ КОД!
user_input = "' OR '1'='1' -- " # Ввод злоумышленника
query = f"SELECT * FROM users WHERE name = '{user_input}';"
# cursor.execute(query)
Итоговый SQL-запрос будет выглядеть так:
SELECT * FROM users WHERE name = '' OR '1'='1' -- ';
Условие OR '1'='1' всегда истинно, поэтому запрос вернет всех пользователей из таблицы. -- комментирует оставшуюся часть запроса.
Как защититься?
Основной принцип защиты — разделение кода и данных. Данные, полученные от пользователя, никогда не должны интерпретироваться как часть исполняемого SQL-кода.
-
Использование параметризованных запросов (Prepared Statements) Это самый надежный метод. Драйвер базы данных сам безопасно подставляет значения в запрос, экранируя все спецсимволы.
# БЕЗОПАСНЫЙ КОД user_input = "' OR '1'='1' -- " # Знак '?' — это плейсхолдер для данных query = "SELECT * FROM users WHERE name = ?;" cursor.execute(query, (user_input,)) -
Использование ORM (Object-Relational Mapping) Библиотеки вроде SQLAlchemy (Python), Hibernate (Java) или Eloquent (PHP) по умолчанию используют параметризованные запросы, что значительно снижает риск инъекций.
-
Принцип наименьших привилегий Пользователь базы данных, от имени которого приложение выполняет запросы, должен иметь только необходимые ему права. Например, ему не нужен доступ на удаление таблиц (
DROP TABLE).