Внедрение данных (injection) — класс уязвимостей, при котором злоумышленник передаёт в приложение управляющие символы, интерпретируемые как код. Самый известный пример — SQL injection, но категория шире: NoSQL, LDAP, OS command, XPath. OWASP Top 10 в редакции 2021 года поставил Injection на 3-е место среди угроз веб-приложений (категория A03).
- Что такое внедрение данных в приложение
- OWASP Top 10 и место инъекций в рейтинге
- Четыре шага защиты от SQL-инъекции
- Prepared statements vs escape vs stored procedures
- Ограничения защитных мер
- История уязвимостей и первые задокументированные случаи
- Мифы о защите от инъекций
- WAF полностью защищает от injection
- ORM полностью исключает риск
- Вопрос-ответ
Что такое внедрение данных в приложение
Внедрение данных возникает, когда пользовательский ввод попадает в интерпретатор без экранирования и меняет смысл команды. По определению CWE-89 (Common Weakness Enumeration, версия 4.14, 2024), SQL injection — это «неправильная нейтрализация специальных элементов, используемых в SQL-команде». Формально это дефект класса CWE-74 — Improper Neutralization of Special Elements in Output Used by a Downstream Component.
Классический пример: приложение строит запрос конкатенацией — «SELECT * FROM users WHERE name='» + input + «‘». Если пользователь введёт ‘ OR ‘1’=’1, запрос превратится в универсальный обход авторизации. Согласно отчёту Verizon Data Breach Investigations Report 2024, инъекции остаются причиной 8% всех взломов веб-приложений — цифра стабильна с 2018 года.
Внедрение данных не ограничивается SQL. Атаки на MongoDB через операторы $where, LDAP-инъекции через управляющие символы (, |, & и OS command injection через backtick или semicolon работают по тому же принципу — ввод интерпретируется как код. Каждый класс требует отдельной защиты.
OWASP Top 10 и место инъекций в рейтинге
OWASP (Open Web Application Security Project) публикует Top 10 самых опасных уязвимостей раз в 3–4 года. В редакции 2013 и 2017 годов инъекции занимали 1-е место, в 2021 году спустились на 3-е — категория A03:2021 Injection. Смена позиции не означает, что проблема исчезла: изменилась методология подсчёта.
Согласно официальному документу OWASP Top 10 2021 (owasp.org), категория A03 покрывает 33 CWE и затрагивает 94% протестированных приложений. Средняя частота инцидентов (incidence rate) составляет 3.37%, а максимальная возможная — 19.09%. Это делает внедрение данных одной из трёх самых массовых угроз в вебе.
OWASP также поддерживает Cheat Sheet Series — набор практических инструкций по защите от injection на разных стеках. Отдельные листы посвящены Java, .NET, Python, Node.js, PHP. По сравнению с Top 10, Cheat Sheets содержат конкретный код и применяются в CI-проверках.
Четыре шага защиты от SQL-инъекции
Порядок действий стандартизирован в OWASP SQL Injection Prevention Cheat Sheet. Применяйте все четыре шага, а не только первый.
Шаг 1. Используйте prepared statements с параметрами. В Java — PreparedStatement из java.sql, в Python — psycopg2 с плейсхолдером %s, в PHP — PDO с bindParam. Драйвер сам экранирует значения, и SQL-парсер отличает код от ввода.
Шаг 2. Экранируйте вход, если параметризация невозможна. Функции — mysqli_real_escape_string в PHP, quote_ident в PostgreSQL. Ручное экранирование — крайняя мера, потому что легко забыть один вход из десяти и открыть уязвимость.
Шаг 3. Валидируйте вход на прикладном уровне. Проверяйте тип, длину, формат — email по RFC 5322, номер телефона по E.164. Валидация не заменяет параметризацию, но снижает поверхность атаки.
Шаг 4. Применяйте ORM — Hibernate, SQLAlchemy, Django ORM, Sequelize. Библиотека сама формирует безопасный запрос из объектной модели. Внедрение данных через ORM возможно только при явном использовании raw SQL — этот участок кода требует ревью.
Prepared statements vs escape vs stored procedures
Три техники защиты часто путают. Разница между ними принципиальна и определяет эффективность.
Prepared statements. Драйвер отправляет SQL и параметры отдельно. Сервер БД компилирует запрос один раз, затем подставляет значения. По сравнению с ручным экранированием, prepared statements защищают от 100% классических инъекций и не зависят от кодировки.
Экранирование строк. Приложение вставляет специальные символы (кавычки, обратные слэши) с учётом синтаксиса СУБД. В отличие от prepared, экранирование хрупко: смена драйвера или кодировки может сломать защиту. OWASP считает эту технику fallback, а не основной.
Stored procedures. Логика вынесена в БД, приложение вызывает процедуру с параметрами. Защита сильнее ручного экранирования, но слабее prepared statements, если внутри процедуры собирается динамический SQL. По сравнению с ORM, хранимки хуже масштабируются и сложнее версионируются.
Ограничения защитных мер
Ни одна техника не даёт полной гарантии — важно понимать границы применимости.
Обычное экранирование строк недостаточно для NoSQL: в MongoDB инъекция идёт через объект {$ne: null}, а не через кавычку. Здесь помогает только строгая валидация типов и запрет $-операторов. По данным OWASP NoSQL Injection Cheat Sheet, около 20% MongoDB-приложений в 2023 году были уязвимы к обходу авторизации через инъекцию оператора.
Prepared statements не защищают от XSS: параметризованный SQL безопасен на уровне БД, но данные всё равно попадают в HTML без экранирования. XSS не отменяет CSRF, а CSRF — отдельная угроза, требующая Anti-CSRF Token по стандарту OWASP CSRF Cheat Sheet. Каждая уязвимость требует отдельного контура защиты.
Валидация регуляркой не заменяет параметризацию: строка ‘ OR ‘1’=’1 проходит проверку на «только буквы и цифры», если разработчик забыл про пробел и апостроф. Нельзя доверять входу, даже если он прошёл валидатор — параметризация обязательна на нижнем уровне.
История уязвимостей и первые задокументированные случаи
Первое публичное описание SQL injection появилось в статье Джеффа Форристала (псевдоним rain forest puppy) в журнале Phrack, номер 54, за 25 декабря 1998 года. С того момента прошло более 25 лет, но техника остаётся актуальной. В базе CVE к 2024 году зарегистрировано свыше 17 000 уязвимостей категории CWE-89.
Крупнейший инцидент, связанный с injection, — утечка Heartland Payment Systems 2008 года: 130 миллионов записей о картах, ущерб более 140 миллионов долларов. По данным судебных документов США (Docket No. 4:09-md-02046), первопричиной стал именно SQL-запрос без параметризации. Другой случай — TalkTalk 2015 года, штраф ICO составил 400 тысяч фунтов согласно официальному решению регулятора.
Такая история подтверждает, что внедрение данных — не теоретическая, а промышленная угроза. Даже крупные компании с бюджетами на безопасность страдают от классических инъекций, потому что параметризация не применена хотя бы в одном месте кодовой базы.
Мифы о защите от инъекций
Вокруг темы сложилось несколько устойчивых заблуждений — они опровергаются документами OWASP и SANS.
WAF полностью защищает от injection
Web Application Firewall (ModSecurity, AWS WAF, Cloudflare) блокирует известные шаблоны атак, но обходится обфускацией — Unicode-нормализацией, комментариями SQL, разными кодировками. По данным OWASP WAF Bypass Cheat Sheet, до 15% реальных атак проходят через типовой WAF. Firewall — дополнительный слой, а не замена параметризации.
ORM полностью исключает риск
ORM — не серебряная пуля. Django Q-expressions, Hibernate HQL и Sequelize literal позволяют встраивать сырой SQL — там инъекция всё ещё возможна. По сравнению с чистыми prepared statements, ORM требует ревью каждого места с raw() и exec_sql(), иначе внедрение данных проходит через якобы безопасный слой.
Вопрос-ответ
Что такое SQL-инъекция простыми словами? Это способ атаки, при котором злоумышленник передаёт в форму ввод, интерпретируемый как SQL-код. Приложение выполняет чужую команду и открывает злоумышленнику доступ к базе или обходит авторизацию. Внедрение данных проходит через слабое экранирование.
Как быстро исправить уязвимость? Переведите весь код на prepared statements: PreparedStatement в Java, psycopg2 с %s в Python, PDO в PHP. Одно это устранит 90% случаев внедрения данных. Далее пройдитесь по raw SQL внутри ORM и переведите его на параметры.
Какое место занимает injection в OWASP Top 10? В редакции 2021 года — 3-е место, категория A03. Ранее (2017 и 2013) — 1-е место. Смена позиции связана с ростом других угроз и изменением методики подсчёта, а не с падением опасности инъекций.
Достаточно ли фаервола WAF? Нет. WAF ловит типовые шаблоны, но обходится обфускацией и Unicode. Согласно OWASP, WAF — четвёртый рубеж, а первый — параметризация запросов. Полагаться только на firewall без исправления кода — устойчивое заблуждение среди начинающих команд.
Работает ли внедрение данных против NoSQL? Да. MongoDB уязвим к операторной инъекции через $ne, $gt, $where. Cassandra и CouchDB имеют собственные вектора атак. Prepared statements в SQL-смысле там неприменимы — используются строгая типизация и allowlist операторов на прикладном уровне.
