Привет, Хабр! На связи Денис Макрушин, директор по продуктам безопасной разработки SourceCraft в Yandex Infrastructure. Мой любимый ежегодный рейтинг — Top 10 web hacking techniques, который готовит сообщество исследователей по инициативе компании PortSwigger. В рейтинг попадают материалы, в которых делятся инновациями в области поиска и эксплуатации уязвимостей. Сегодня я хочу рассказать об исследованиях, которые показались мне наиболее интересными, потому что показывают не просто отдельные уязвимости, а целые категории проблем и новые методы атак.
Несогласованная интерпретация: как неправильная нормализация данных и разница в их обработке ведёт к уязвимостям
Исследование со сложным названием «Дифференциал парсеров» несёт простую идею: если в системе два и более обработчика данных (JSON, YAML или HTTP) по-разному разбирают одни и те же данные, то жди беды. Автор наглядно показывает, как рост сложности системы и количества связей в ней приводит к появлению новых и нередко неочевидных проблем. Недостаточно проверить безопасность каждого компонента системы отдельно — нужно убедиться, что комбинация этих компонентов не создаёт уязвимости.
Автор приводит несколько сценариев атак:
-
Удалённое выполнение кода в CouchDB. Эта система БД написана на Erlang и использует JavaScript для валидации документов. При получении JSON с дублирующимися параметрами (например, два параметра roles) библиотека Erlang превращала их в массив и использовала первое встречное значение. А движок JavaScript брал только последнее значение из этого массива. Злоумышленник передавал два значения параметра roles в БД. JS-движок видел безопасное значение и передавал дальше, а Erlang видел первое значение (_admin) и создавал привилегированную учётную запись.
Сценарий очень напоминает класс уязвимостей HTTP Parameter Pollution, да?
-
Произвольная запись файлов. Разница парсеров Ruby и Go позволяла злоумышленнику обходить фильтр опасных параметров в YAML-файлах. Ruby-часть не фильтровала опасный параметр parent, а вот Go-парсер его видел. Атакующий успешно протащил запрещённый параметр мимо фильтров и смог записывать произвольные файлы в систему.
Другой пример похожей категории проблем — уязвимости, возникающие при нормализации Unicode. Разные элементы цепочки веб-трафика (браузер, прокси, CDN, WAF, приложение, БД) могут по-разному декодировать и нормализовать Unicode-строки. Есть что-то общее с предыдущим сценарием атаки: проверка опасных символов срабатывает на одном представлении строки, а в другом месте обрабатывается уже другая форма этой строки. Из-за различий между формами нормализации, регистром и похожими символами злоумышленник может замаскировать ввод так, чтобы обойти фильтры и правила.
В конце каждого раздела я буду давать небольшие рекомендации о том, как избежать рисков или предотвратить описанный тип атаки. Советы основаны на личном опыте и идеях, которые описывают авторы исследований.
Как защититься
Использовать принцип «передаю то, что понимаю».
Для исключения «дифференциала парсеров» на уровне архитектуры проекта не стоит пересылать сырые данные от одного парсера к другому. Необходимо провести инвентаризацию всех парсеров, которые используются в системе: с помощью SCA составить список библиотек, занимающихся парсингом, и посредством SAST определить путь «сырых» входных данных.
Для защиты от уязвимостей, связанных с нормализацией Unicode, нужно привести строку к единому виду до её применения в бизнес-логике и убедиться, что во всех компонентах используется одна и та же форма нормализации. А кроме того, стоит попросить своего appsec-товарища изучить эти атаки и настроить DAST.
Особенности протоколов: осуществление произвольных запросов в HTTP/2 и новая техника SSRF
Если HTTP-прокси настроен неправильно, атакующий может отправлять через него CONNECT-запросы к произвольным хостам и портам. Метод CONNECT предназначен для создания TCP-туннеля через прокси. Прокси пытается установить соединение с указанным адресом и возвращает результат: соединение установлено, отклонено или произошёл тайм-аут. Анализируя эти ответы, злоумышленник может определить, какие хосты и порты доступны. Если прокси разрешает метод CONNECT к внутренним адресам или не ограничивает список допустимых целей, его можно использовать для сканирования внутренних сервисов и проведения сетевой разведки.
Такой тип атак мы, скорее всего, будем наблюдать ещё долго: они эксплуатируют проблемы, которые совсем непросто исправить. Они связаны с особенностями фундаментальных протоколов, на которых держится коммуникация современных веб-приложений.
Авторы исследования «Новая техника SSRF» придумали новый способ эксплуатации SSRF: атаку Blind Server-Side Request Forgery, при которой целевое приложение делает запрос, но не возвращает тело ответа, можно превратить в SSRF с утечкой полного тела ответа.
Исследователи заметили необычное поведение обработчика перенаправлений: приложение, которое делает запрос по URL и обрабатывает ответ как JSON, при нескольких перенаправлениях падало с ошибкой Invalid JSON, а при их большом количестве выдавало другую ошибку (Network Exception).
Затем они обнаружили ещё одну аномалию: если приложению возвращался конечный ответ с HTTP-кодом 500, то оно внезапно возвращало полное тело HTTP-ответа.
Исследователи смогли сделать это поведение контролируемым и придумали технику, которая позволяет создать такую цепочку перенаправлений, в результате которой приложение выдаёт в теле ответа все результаты этих перенаправлений вместе с секретами.
Как защититься
Для проблемы с CONNECT-запросами можно подготовить правило для своего статического анализатора или IaC-сканера, которое поможет найти уязвимые конфигурации прокси-серверов. Например, стоит поискать настройки в конфиге, которые включают режим прокси или туннелирования без ограничений.
Для защиты от техники SSRF с помощью SAST можно найти в коде функции редиректа, в значении которых используются данные от пользователя.
Каналы утечки в Chromium: узнаём, куда и зачем сходил браузер
В следующих исследованиях меня заинтересовало, как кеш и незаметные сетевые артефакты браузера могут стать каналом утечки данных. Такие атаки сложнее заметить и, значит, сложнее предотвратить или остановить.
Первая атака довольна сложная в реализации, но интересная концептуально. Злоумышленник может по временным показателям понять, к каким ресурсам обращался браузер жертвы. Скрипт на странице атакующего специально забивает пул сетевых соединений в Chromium-браузере, затем в этом пуле провоцирует браузер сделать запрос и на основе признака, какой запрос получил соединение раньше, делает вывод. Например, вывод о привилегиях жертвы на том или ином ресурсе. Повторяя измерения, можно даже восстановить строку в URL, например <secret>.example.com. То есть утекают метаданные сетевого соединения браузера.
Ещё одно исследование из рейтинга показывает канал утечки в Chromium-браузере, но уже с помощью HTTP-заголовка ETag (Entity Tag). Этот заголовок сервер отдаёт в ответе как идентификатор версии ресурса (например, страницы, файла, JSON и т. п.). Его основная задача — кеширование: браузер может в следующий раз спросить: «У меня уже есть такая версия ресурса, она не изменилась?» — и не скачивать тело ответа повторно.
Злоумышленник заманивает браузер жертвы на свой ресурс со скриптом. Скрипт отправляет браузер к нужному ресурсу https://target.site/?query=<секретная_строка_которая_может_быть_на_странице>. Браузер получает ответ и сохраняет ETag. Затем скрипт меняет свой запрос, что приводит к изменению ETag. Перебирая такие запросы и отслеживая факты изменения ETag, атакующий находит канал для получения секретов.
Как защититься
Не хранить секреты и чувствительные данные в URL и особенно в субдоменах. Не отдавать ETag для страниц с ценными данными.
Фреймворки и абстракции со сложным поведением: уязвимый кеш Next.js и утечки через ORM
В исследованиях этого раздела прослеживается важный тренд: уязвимости всё чаще появляются не в коде приложения, а в механизмах вокруг него, например во фреймворках, кеше, оптимизации.
Нетривиальный вариант хорошо исследованной проблемы отравления веб-кеша обнаружен в Next.js. Авторы исследования увидели, что в системе маршрутизации этого фреймворка у одной и той же страницы есть две формы ответа: в виде обычной HTML и в специальном JSON-формате.
Проблема в том, что при определённых условиях злоумышленник может отправить специально сформированный запрос, который заставляет Next.js перепутать режимы и закешировать то, что не должно сохраняться. Так как запись происходит во встроенный кеш самого фреймворка, то атака работает даже без компонентов CDN.
Как защититься
Уязвимость описана для Next.js v13.5.1–14.2.9, поэтому стоит настраивать свой SCA на выявление этих версий.
Другое исследование связано со сложностью абстракций ORM. Object-Relational Mapping, объектно-реляционное отображение, — прослойка между кодом и базой данных. С её помощью разработчики работают с записями в БД как с обычными объектами в коде, не написав при этом ни строчки на SQL.
Бывает, что разработчики дают пользователю сложный фильтр или гибкую систему поиска, но при этом позволяют через эту систему управлять выражениями фильтрации ORM. Злоумышленник может заставить систему фильтровать или искать данные по чувствительным полям и в результате вытащить ценную информацию.
Ключевая мысль в этом исследовании: нельзя просто прикрутить фильтры к ORM — нужно явно разрешать только безопасные поля, контролировать доступ к связям и не допускать фильтрации по секретным атрибутам.
Как защититься
С помощью SAST найти все чувствительные места в коде, где пользовательский ввод попадает в ORM-объекты без строгой валидации.
Инъекции и выполнение кода: SOAPwn и SSTI техники
Следующие исследования заинтересовали меня идеей, которая их объединяет: ошибки приложения могут стать инструментом атаки. Разработчики и администраторы считают ошибку неудачным результатом запроса, а атакующий видит в ней сигнал и возможность. Злоумышленник может попытаться получить доступ к серверу или даже управлять через ответы.
Исследование SOAPwn рассказывает, как в .NET Framework ведут себя классы-прокси для SOAP, например SoapHttpClientProtocol. Они должны отправлять XML-сообщения по HTTP, но из-за ошибки в приведении типов могут быть сбиты с толку и перенаправлены на другой обработчик URL. Таким образом если приложение позволяет атакующему повлиять на URL SOAP-прокси напрямую через настройку (или параметр) или косвенно через динамический импорт, то возникает уязвимость. Вместо отправки по сети прокси может начать писать тело SOAP-запроса в файл или по заданному пути.
Исследование Successful Errors показывает, как можно использовать ошибки в процессе эксплуатации уязвимостей Blind-SSTI. Server-Side Template Injection позволяет злоумышленнику внедрять вредоносный код в шаблоны, которые интерпретируются и выполняются на стороне сервера. При слепых SSTI атакующий может выполнять произвольные команды на сервере, получать доступ к ценным данным и иногда к самому серверу, но при этом злоумышленник не видит результата внедрения. Автор исследования смог превратить ошибки от сервера в канал связи и формализовал две техники:
-
Error-Based, при которой приложение показывает подробный текст ошибки. Например, stack trace или сообщение исключения.
-
Boolean Error-Based Blind, при которой есть возможность определить факт наличия или отсутствия ошибки. Например, другой статус ошибки, другая страница, другой шаблон ответа.
В первом случае атакующий может специально спровоцировать такую ошибку, которая в своём сообщении будет содержать фрагмент вычисляемого значения. Тогда злоумышленник видит в ошибке, например, строки или числа и получает возможность контролировать атаку на основе этой обратной связи.
Во втором случае автор предлагает строить выражения вида «если условие истинно, то вызываем ошибку» и «если условие ложно, то ошибки нет». Таким образом атакующий получает возможность проверять свои гипотезы.
Как защититься
При использовании SSTI или .NET Framework стоит изучить детали этих исследований и попросить свою LLM на основе этих материалов сгенерировать сигнатуры для статического анализатора.
Перспективные исследования из списка номинантов
Эти исследования не вошли в основной рейтинг, но показались мне интересными и заслуживающими внимания. Объект атаки в них — фундаментальные слои: протоколы, на которых держится значительный пласт коммуникации между компонентами сети, ИИ-агенты, уязвимые компоненты для распаковки данных.
Промт-инъекции в ИИ-агенты для генерации или проверки качества кода
Возможность внедрения вредоносных инструкций в текст коммитов, тикетов или пул-реквестов может заставить агента выполнить привилегированные команды в процессах сборки кода. Сценарий атаки простой в реализации, а поверхность атаки стремительно растёт вместе с числом утилит в CI/CD. В 2026 году многие инциденты на GitHub будут связаны с этим вектором.
Как защититься
Проверять любые входные данные из тикетов или PR перед их передачей в контекст промта.
Возвращение атак Zip Slip
Появляются не просто новые варианты известной уязвимости, связанной с распаковкой архивов, а новые способы обойти защиту от этой категории проблем. Исследование показывает, что предварительная проверка архива сама по себе недостаточна: специально подготовленный .zip-файл может выглядеть безопасным для механизма валидации, но при распаковке тем же приложением интерпретироваться иначе и всё равно приводить к выходу за пределы директории, в которую производится распаковка. Новизна исследования заключается в эксплуатации расхождения между тем, как разные парсеры или разные API читают один и тот же архив.
Это служит напоминанием о том, что старые проблемы возвращаются в новых контекстах.
Как защититься
При реализации функций распаковки архивов необходимо внедрить проверку и убедиться, что канонический путь каждого извлекаемого файла находится строго внутри целевой директории. Тут вновь поможет статический анализатор.
Фундаментальная уязвимость протокола HTTP/1.1
В HTTP/1.1 запросы просто склеиваются друг с другом в одном сетевом соединении. Если разные серверы (фронтенд и бэкенд) по-разному интерпретируют длину сообщения, то злоумышленник может «отрезать» часть своего запроса и подставить его в начало запроса следующего пользователя.
Как защититься
Перейти на HTTP/2 во внутренней сети, так как это протокол с чётким разделением сообщений.
Общий тренд, который можно разглядеть за всеми этими исследованиями: атаки смещаются от самих приложений в сторону их инфраструктуры и протоколов.
Все рассмотренные исследования показывают один важный сдвиг: современные атаки всё чаще возникают не из-за одной ошибки в коде, а из-за несовпадения предположений между компонентами системы. Протоколы, прокси, кеши, фреймворки и инструменты автоматизации начинают вести себя по-разному в пограничных ситуациях, и именно на этих различиях строятся новые техники эксплуатации. Для разработчиков это означает, что безопасность уже нельзя рассматривать только на уровне отдельных функций или библиотек: важно понимать, как данные влияют на всю систему в целом. Хорошая новость в том, что многие из этих проблем всё ещё можно обнаружить на этапе разработки с помощью классических инструментов вроде статических анализаторов кода. Главное — знать, что именно и где именно нужно искать. Поэтому чем раньше команда разработки будет знакомиться с новыми исследованиями и следить за развитием техник атак, тем меньше шансов, что подобные нетривиальные баги появятся в проде.
ссылка на оригинал статьи https://habr.com/ru/articles/1026090/