SQL-инъекция¶
SQL-инъекция (англ. SQL injection) — это один из наиболее распространённых видов атак на веб-приложения, основанный на внедрении в запрос к базе данных произвольного SQL-кода. Атака возможна, когда приложение формирует SQL-запросы путём конкатенации (склеивания) строк с данными, полученными от пользователя, без предварительной проверки или экранирования. В результате злоумышленник может выполнить несанкционированные операции с базой данных: чтение, изменение, удаление данных, а в некоторых случаях — получить контроль над сервером.
¶История
Концепция SQL-инъекции была впервые описана в 1998 году исследователем в области безопасности Джеффом Форристалом (Jeff Forristal), который опубликовал статью под псевдонимом Rain Forest Puppy в журнале Phrack. В статье демонстрировалась возможность манипуляции SQL-запросами через веб-формы. Однако широкую известность уязвимость получила после публикации в 2000 году работы Криса Анли (Chris Anley) «Advanced SQL Injection In SQL Server Applications».
В 2000-х годах SQL-инъекции стали одной из главных угроз для веб-приложений. По данным отчётов OWASP (Open Web Application Security Project), с 2004 по 2017 год SQL-инъекция неизменно входила в первую тройку самых критичных уязвимостей веб-приложений. Крупные инциденты, связанные с SQL-инъекциями, произошли в 2008 году (взлом сайта компании Heartland Payment Systems, компрометация 130 миллионов кредитных карт) и в 2011 году (атака на сайт компании Sony Pictures, утечка данных 1 миллиона пользователей).
¶Механизм атаки
¶Принцип работы
SQL-инъекция возникает, когда приложение не разделяет код и данные. Вместо использования параметризованных запросов (prepared statements) разработчик вставляет пользовательский ввод непосредственно в строку запроса. Например, при аутентификации пользователя может использоваться запрос:
``sql SELECT * FROM users WHERE username = 'пользовательский_ввод' AND password = 'пользовательский_ввод'; ``
Если злоумышленник вводит в поле имени пользователя строку admin' --, то запрос преобразуется в:
``sql SELECT * FROM users WHERE username = 'admin' --' AND password = '...'; ``
Символы -- в SQL начинают комментарий, поэтому часть условия AND password = '...' игнорируется. Запрос возвращает данные пользователя admin без проверки пароля.
¶Типы SQL-инъекций
- Классическая (внутренняя) инъекция — злоумышленник видит результат выполнения запроса непосредственно в ответе сервера (например, на странице сайта). Позволяет извлекать данные из базы напрямую.
- Слепая (blind) инъекция — результат запроса не отображается на странице, но злоумышленник может определить истинность или ложность условия по косвенным признакам (например, по времени ответа сервера или по наличию/отсутствию определённого контента).
- Boolean-based blind — анализ ответа сервера на истинные и ложные условия.
- Time-based blind — использование функции задержки (например,
SLEEP()в MySQL) для определения истинности условия по времени ответа.
- Out-of-band (внеполосная) инъекция — данные передаются по другому каналу (например, через DNS-запросы или HTTP-запросы на сервер злоумышленника). Используется, когда прямой вывод данных невозможен, а временные задержки неэффективны.
- Error-based (основанная на ошибках) инъекция — злоумышленник провоцирует вывод сообщения об ошибке, которое может содержать фрагменты данных из базы.
¶Примеры уязвимого кода
¶PHP (уязвимый)
``php $username = $_POST['username']; $password = $_POST['password']; $query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'"; $result = mysqli_query($connection, $query); ``
¶PHP (защищённый — параметризованный запрос)
``php $stmt = $connection->prepare("SELECT * FROM users WHERE username = ? AND password = ?"); $stmt->bind_param("ss", $username, $password); $stmt->execute(); $result = $stmt->get_result(); ``
¶Python (уязвимый)
``python cursor.execute("SELECT * FROM users WHERE username = '%s' AND password = '%s'" % (username, password)) ``
¶Python (защищённый)
``python cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password)) ``
¶Методы защиты
¶Параметризованные запросы (Prepared Statements)
Наиболее эффективный метод защиты. SQL-запрос компилируется заранее, а пользовательские данные передаются отдельно, как параметры. Это гарантирует, что ввод пользователя никогда не будет интерпретирован как SQL-код. Поддерживается большинством языков программирования и СУБД.
¶Экранирование специальных символов
Если использование параметризованных запросов невозможно (например, при построении динамических запросов с изменяемой структурой), необходимо экранировать специальные символы (кавычки, обратную косую черту) с помощью функций, предоставляемых СУБД (например, mysqli_real_escape_string() в PHP). Однако этот метод менее надёжен, чем параметризация.
¶Проверка входных данных (Input Validation)
Фильтрация и валидация пользовательского ввода на стороне сервера. Например, для числовых полей — проверка, что введённые данные являются целым числом; для строк — ограничение длины и набора символов. Валидация не заменяет параметризацию, но снижает риск атаки.
¶Принцип наименьших привилегий
Учётная запись, под которой приложение подключается к базе данных, должна иметь минимально необходимые права. Например, для чтения данных не следует давать права на удаление или изменение таблиц. Это ограничивает ущерб в случае успешной атаки.
¶Хранение процедур (Stored Procedures)
Использование хранимых процедур, которые принимают параметры, также может снизить риск, если процедуры написаны безопасно (без динамического формирования SQL внутри процедуры). Однако если внутри процедуры всё равно используется конкатенация строк, уязвимость сохраняется.
¶Последствия атак
- Утечка конфиденциальных данных — кража паролей, номеров кредитных карт, персональных данных пользователей.
- Потеря или повреждение данных — злоумышленник может удалить или изменить содержимое базы данных.
- Несанкционированный доступ — получение прав администратора системы или базы данных.
- Распространение вредоносного ПО — через уязвимый сайт может быть загружен вредоносный код.
- Финансовые потери — штрафы за утечку данных, судебные иски, затраты на восстановление.
¶Инструменты для обнаружения и эксплуатации
- SQLMap — автоматизированный инструмент с открытым исходным кодом для обнаружения и эксплуатации SQL-инъекций. Поддерживает большинство типов инъекций и СУБД.
- Burp Suite — платформа для тестирования безопасности веб-приложений, включающая модули для ручного и автоматизированного поиска SQL-инъекций.
- OWASP ZAP — бесплатный сканер безопасности веб-приложений с функциями обнаружения SQL-инъекций.
- jSQL Injection — кроссплатформенный инструмент с графическим интерфейсом для автоматизации атак.
¶Интересные факты
- В 2012 году компания Yahoo! пострадала от SQL-инъекции, в результате которой были скомпрометированы данные 450 тысяч пользователей. Атака была проведена с использованием SQLMap.
- В 2014 году хакерская группа «Lizard Squad» использовала SQL-инъекцию для взлома сайта компании Microsoft (Xbox Live).
- По данным отчёта Positive Technologies за 2023 год, SQL-инъекции остаются одной из трёх самых распространённых уязвимостей в веб-приложениях, составляя около 15% от всех выявленных уязвимостей.
¶Источники
- Forristal, J. (1998). «NT Web Technology Vulnerabilities». Phrack Magazine, Volume 8, Issue 54.
- Anley, C. (2002). «Advanced SQL Injection In SQL Server Applications». Next Generation Security Software Ltd.
- OWASP. «SQL Injection Prevention Cheat Sheet».
- OWASP. «OWASP Top 10 – 2021: The Ten Most Critical Web Application Security Risks».
- Positive Technologies. «Web Application Vulnerabilities: Statistics 2023».
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →

