«Самое опасное в инъекциях — не код злоумышленника, а доверие вашего приложения к данным извне. Вы сами даёте атакующему ключи, когда не проверяете ввод.»
Суть угрозы
Инъекция кода — это не просто ещё один пункт в списке уязвимостей. Это фундаментальный сбой в архитектуре доверия приложения. Система принимает внешние данные как инструкции, а не как пассивную информацию. Последствия выходят за рамки потери данных и ведут к полной компрометации логики работы системы.
XML-инъекция: атака на структуру
Атаки на XML часто остаются в тени SQL-инъекций, но их потенциал разрушения выше. XML — это не просто формат данных, это язык разметки с собственной логикой. Уязвимость возникает, когда приложение некритично склеивает пользовательский ввод с XML-документом и затем интерпретирует результат.
Как это используется на практике
Злоумышленник может модифицировать структуру XML, внедряя новые элементы, изменяя атрибуты существующих или даже подменяя всю схему документа. Цель — обмануть парсер. Например, передав <![CDATA[<script>alert('xss')</script>]]> в поле, ожидающее текста, можно обойти фильтры, экранирующие угловые скобки. Более изощрённые атаки используют внешние сущности (XXE) для чтения локальных файлов сервера или сканирования внутренней сети.
Пример уязвимого парсера
// Уязвимый код, не проверяющий входные данные
String userInput = request.getParameter("xmlData");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// Важно: по умолчанию обработка внешних сущностей может быть разрешена!
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); // Защита
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(userInput)));
// Если userInput содержит объявление внешней сущности &xxe;, парсер попытается её загрузить.
SQL-инъекция: классика, которая не стареет
Несмотря на десятилетия известности, SQL-инъекции остаются в топе OWASP Top 10. Причина — не недостаток знаний, а человеческий фактор и legacy-код. Атака возможна, когда данные пользователя напрямую конкатенируются со строкой SQL-запроса.
Эволюция атак
Простые атаки типа ' OR '1'='1 сегодня легко отлавливаются. Современные методы включают слепые SQL-инъекции (Blind SQLi), когда приложение не возвращает данных запроса напрямую, но по изменению времени отклика или поведению ошибок можно извлечь информацию побитово. Другой вектор — Out-of-Band инъекции, когда данные извлекаются через DNS-запросы или HTTP-обращения на контролируемый атакующим сервер.
| Тип инъекции | Механизм | Сложность обнаружения |
|---|---|---|
| Классическая (In-band) | Результат виден сразу в ответе приложения (ошибка или данные). | Низкая |
| Слепая (Blind) | Применяется логика ИСТИНА/ЛОЖЬ или анализ времени отклика для вывода данных. | Высокая |
| С выводом по стороннему каналу (Out-of-Band) | Данные извлекаются через DNS, HTTP или другие сетевые запросы на сервер злоумышленника. | Очень высокая |
Защита: не только prepared statements
Параметризованные запросы — золотой стандарт, но не панацея. Они помогают, когда данные подставляются в значения (WHERE id = ?). Если же пользовательский ввод должен определять имя таблицы или столбца (динамический SQL), prepared statements бессильны. Здесь нужна белая метка разрешённых значений.
DLL-инъекция: взлом изнутри процесса
Этот тип атаки выходит за рамки веб-приложений и бьёт по сердцу операционной системы. Цель — заставить легитимный процесс загрузить и выполнить чужой код. Успешная DLL-инъекция означает, что вредоносный код работает с теми же привилегиями, что и целевое приложение, часто обходя межсетевые экраны и системы предотвращения вторжений (IPS).
Техники внедрения
- Remote Thread Injection: Наиболее распространённый метод. Злоумышленник открывает дескриптор целевого процесса, выделяет в его памяти место под свой код, записывает туда DLL-путь или шелл-код, а затем создаёт удалённый поток, который выполняет код.
- Hooking: Внедрение путём установки перехватчиков (hooks) на системные API, такие как
SetWindowsHookEx. Когда целевое приложение вызовет hooked-функцию, управление передастся в код злоумышленника. - DLL Search Order Hijacking: Использование особенностей порядка поиска библиотек Windows. Если приложение пытается загрузить
legit.dllбез указания полного пути, и в каталоге приложения лежит maliciouslegit.dll, будет загружен он.
LDAP-инъекция: компрометация корпоративной инфраструктуры
LDAP — это каркас корпоративной аутентификации и авторизации. Успешная инъекция здесь может дать доступ не к одной базе данных, а ко всей структуре пользователей, групп и политик организации. Уязвимость возникает, когда пользовательский ввод напрямую используется для построения фильтров LDAP без экранирования специальных символов: ( ) & | = > < ~ *.
Пример последствий
// Ожидаемый фильтр для поиска пользователя по логину и паролю:
(&(uid=user_input_login)(userPassword=user_input_md5_hash))
// Если атакующий введёт в логин "*)(uid=*))(|(uid=*",
// а пароль оставит пустым, фильтр превратится в:
(&(uid=*)(uid=*))(|(uid=*)(userPassword=...))
// Первая часть (&(uid=*)(uid=*)) всегда истинна,
// оператор ИЛИ (|) делает весь фильтр истинным,
// что может привести к успешной аутентификации без пароля.
Специфика защиты
Помимо стандартных мер, таких как экранирование и подготовленные операторы (параметризованные запросы LDAP), критически важен принцип минимальных привилегий. Учётная запись, от имени которой приложение обращается к LDAP-каталогу, должна иметь доступ ровно к тем ветвям и атрибутам, которые необходимы для работы. Никаких прав на чтение или запись в корне каталога.
Общая стратегия защиты
Борьба с инъекциями — это не установка одного фильтра. Это многослойный подход, встроенный в жизненный цикл разработки.
- Валидация по белому списку: Определите строгий формат для каждого входящего параметра (например, только цифры для ID). Всё, что не соответствует, отвергается.
- Экранирование (кодирование) контекстно-зависимое: Экранирование для SQL не подходит для LDAP, а для LDAP — для командной строки. Используйте специальные функции библиотек, предназначенные для конкретного контекста.
- Принцип минимальных привилегий: База данных, LDAP-сервер, системный процесс — всё должно выполняться с наименьшими возможными правами. Атакуемый веб-сервер не должен иметь доступ к командам операционной системы.
- Статический и динамический анализ (SAST/DAST): Регулярное сканирование кода на шаблоны уязвимостей и тестирование работающего приложения на проникновение.
- WAF как последний рубеж: Веб-приложение-брандмауэр может блокировать известные сигнатуры инъекций, но это не заменяет исправления ошибки в коде.
Главный вывод: доверять можно только самому приложению и его строгой логике. Любые данные извне, будь от пользователя, другого сервиса или системы, должны считаться потенциально враждебными и обрабатываться соответственно.