sql инъекция
SQL инъекция (SQL Injection) — это тип атаки на веб-приложения, при котором злоумышленник внедряет произвольные SQL-команды в запрос к базе данных через пользовательский ввод. SQL инъекция входит в список OWASP Top 10 на протяжении многих лет и является одной из наиболее распространённых и опасных уязвимостей в веб-разработке.
Как работает SQL инъекция
Уязвимость возникает, когда приложение напрямую подставляет пользовательский ввод в SQL-запрос без надлежащей обработки. Пример уязвимого кода на Python:
query = "SELECT * FROM users WHERE login='" + username + "' AND password='" + password + "'"
Если злоумышленник введёт в поле логина строку admin' --, запрос превратится в:
SELECT * FROM users WHERE login='admin' --' AND password='что угодно'
Символы -- комментируют остаток запроса, проверка пароля исчезает, и атакующий входит под именем администратора без знания пароля.
Типы SQL инъекций
- In-band SQLi — результат инъекции виден напрямую в ответе приложения. Включает Error-based (данные получают через сообщения об ошибках) и Union-based (данные извлекают через UNION SELECT).
- Blind SQLi — результат не виден напрямую. Boolean-based: задают условие (если username='admin', страница отображает один контент, иначе другой) и методом перебора получают данные. Time-based: используют задержки (SLEEP, WAITFOR DELAY) для определения истинности условий.
- Out-of-band SQLi — данные извлекаются через DNS или HTTP-запросы от сервера БД к атакующему.
Последствия атак SQL инъекции
SQL инъекция позволяет атакующему: читать конфиденциальные данные из любых таблиц БД (включая пароли, персональные данные, платёжную информацию), изменять или удалять данные, в ряде СУБД выполнять системные команды на сервере (через xp_cmdshell в SQL Server или LOAD_FILE/INTO OUTFILE в MySQL), получить полный контроль над сервером.
Защита: параметризованные запросы
Единственный надёжный способ предотвратить SQL инъекцию — использовать параметризованные запросы (prepared statements) или ORM с правильно реализованным экранированием. При параметризации SQL-структура запроса отделена от данных:
cursor.execute("SELECT * FROM users WHERE login = %s AND password = %s", (username, password))
Пользовательский ввод никогда не интерпретируется как SQL-код — только как данные. Это устраняет уязвимость в корне, а не лечит симптомы.
Дополнительные меры защиты
- ORM — Django ORM, SQLAlchemy, Hibernate используют параметризацию автоматически. Сырые запросы через ORM тоже должны параметризоваться.
- Принцип минимальных привилегий — приложение должно подключаться к БД с аккаунтом, имеющим только необходимые права (SELECT, INSERT, UPDATE). DROP TABLE, CREATE USER — только для административных задач.
- WAF (Web Application Firewall) — дополнительный рубеж, но не замена параметризации.
- Input validation — проверка типов и форматов входных данных снижает attack surface.
- Error handling — не отображайте детальные сообщения об ошибках БД пользователю: они дают атакующему информацию о структуре базы.
Обнаружение уязвимостей
Для поиска SQL инъекций в своих приложениях используют: sqlmap — автоматизированный инструмент обнаружения и эксплуатации SQLi; статические анализаторы кода (Semgrep, CodeQL) с правилами для опасных паттернов; DAST-сканеры (OWASP ZAP, Burp Suite) для динамического тестирования; ручное code review с фокусом на точки конкатенации SQL-строк.
SQL инъекция в современном стеке
GraphQL и NoSQL (MongoDB) также подвержены аналогичным атакам — NoSQL injection. При использовании MongoDB через JavaScript злоумышленник может внедрять объекты вместо строк. Принципы защиты те же: валидация типов и использование безопасных API вместо конкатенации строк запросов.
SQL инъекция в реальных инцидентах
SQL инъекция стоит за крупнейшими утечками данных в истории. Взлом Heartland Payment Systems в 2008 году через SQLi привёл к компрометации 130 миллионов номеров кредитных карт. Утечка данных TalkTalk в 2015 году — результат элементарной SQL инъекции в форме поиска, выполненной 15-летним хакером. Yahoo в 2012 году потеряла 450 000 учётных записей через SQLi в сервисе Voice. Эти случаи объединяет одно: уязвимость была предотвратима параметризованными запросами. OWASP регулярно публикует обновлённый список Top 10, где injection остаётся в первой тройке уже более десяти лет.
Частые вопросы
Защищает ли ORM от SQL инъекций?
В большинстве случаев да, если использовать ORM правильно. Опасность возникает при использовании raw() запросов или format()-интерполяции строк вместо параметров. Всегда используйте параметризованные запросы даже внутри ORM.
Помогает ли экранирование символов вместо параметризации?
Экранирование менее надёжно, чем параметризация. Существуют edge cases (многобайтовые кодировки, специфика СУБД), где экранирование можно обойти. Параметризованные запросы — единственный рекомендуемый подход.
Как проверить своё приложение на SQL инъекции?
Используйте sqlmap для автоматического тестирования, Burp Suite или OWASP ZAP для ручного тестирования, статический анализ кода через Semgrep с правилами для SQLi. Ищите все места, где пользовательский ввод попадает в SQL-запросы.
Другие термины в теме «Безопасность»
Не хватает деталей?
Напишите, что уточнить по теме «sql инъекция» — это помогает улучшать материал и подсказывает, какие термины добавить дальше. Email необязателен: укажите, если хотите ответ только для вас (мы не шлём рассылки).