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 необязателен: укажите, если хотите ответ только для вас (мы не шлём рассылки).

Поделиться