CodeScoring
Содержание
01.10.2026

Достижимость уязвимостей: как перестать тонуть в оповещениях и начать управлять рисками

Open-source под контролем: как анализ достижимости повышает эффективность защиты от киберугроз

Сегодня сложно представить проект, который обходится без открытого программного обеспечения. Но чем больше готовых компонентов использует компания, тем выше риски. Причина — открытый код часто содержит уязвимости, которые со временем становится все тяжелее выявлять и приоритизировать.

Отделить реальные риски от потенциальных и сфокусироваться на том, что действительно опасно, помогают инструменты фильтрации и приоритизации — такие как анализ достижимости. В этой статье расскажем подробнее об этом подходе.

Уязвимости в open source: обзор проблемы

Открытые реестры сегодня насчитывают более 250 млн проектов, которые разрабатывает сообщество из 100 млн человек. Общее количество пакетов уже превышает 11 млн, а их версий — 195 млн. Но вместе с ростом open source растут и связанные риски.

Только в 2025 году среди всех версий пакетов было зарегистрировано 457 тыс вредоносных — в 11 раз больше, чем годом ранее. Результат — череда успешных атак на цепочки поставок ПО, которые в 2025 году обошлись компаниям в $60 млрд.

Особенно остро проблема стоит в случае с JavaScript. В типовом проекте используются сотни зависимостей, однако напрямую разработчик указывает лишь около 10% из них. Остальные 90% — это транзитивные зависимости, которые «подтягиваются» по цепочке через другие библиотеки. Значительная часть уязвимостей приходится как раз на них, и проверять на безопасность такие зависимости труднее.

Дополнительно ситуацию осложняет дефицит специалистов по безопасности. Команд мало, проектов много. Разбирать каждую найденную уязвимость вручную слишком долго — это тормозит вывод новых продуктов на рынок. В попытках ускорить процесс разработчики вынуждены игнорировать часть алертов или недостаточно глубоко погружаются в код, что неизбежно ведет к росту рисков безопасности.

Почему базового сканирования уже недостаточно

Для поиска уязвимостей традиционно используют SCA-инструменты (инструменты композиционного анализа). Они находят уязвимые библиотеки в проекте, но базовые сканеры “не понимают” контекста работы приложения. Из-за этого опасными выглядят слишком много элементов: сканер выдает сотни предупреждений об уязвимостях, но на практике большинство из них могут быть неактуальны, так как уязвимый код нигде не вызывается.

Чтобы решить эту проблему и перестать тратить время команд безопасности впустую, компании переходят от простой констатации уязвимостей к оценке их реальной опасности. Именно эту задачу решает анализ достижимости.

Что такое анализ достижимости?

Анализ достижимости отвечает на важный вопрос: может ли конкретная уязвимость быть реально использована злоумышленником в конкретном приложении? В результате такого анализа компания не просто получает уведомление «в библиотеке есть дыра», а узнает, использует ли клиентский код эту уязвимую функцию.

При этом важно понимать, что анализ достижимости — инструмент приоритизации, а не фильтрации. Если отфильтровать все “недостижимые”, можно пропустить опасные уязвимости, которые могут быть всё равно использованы для атаки. Это связано с разными причинами. Наиболее частый пример, когда часть уязвимостей в принципе невозможно проверить на достижимость силами статического анализа. Это могут быть уязвимости, связанные с окружением, конфигурацией, инфраструктурой или сетевым взаимодействием, то есть тем, что обычно находится вне области работы классического SAST-инструмента. Помимо этого, могут встречаться особенности технологий и языков программирования, не позволяющие получить полный граф вызовов для последующего поиска сигнатур функций. Примером таких конструкций являются динамические вызовы, рефлексия, лямбда-функции. Отдельно стоит отметить полноту базы сигнатур опасных вызовов. Без этих знаний даже при построенном идеальном графе вызовов для проверки достижимости анализатор не будет знать, что должен искать, приводя к ложноотрицательным сработкам.

Уровни анализа достижимости

Существует несколько уровней анализа достижимости.
Ниже варианты в порядке увеличения сложности и снижения количества ложных срабатываний:

  1. Поиск подключения библиотеки в коде. Показывает сам факт использования библиотеки без других подробностей. Это самый простой и быстрый способ исключить лишние неиспользуемые библиотеки из результатов композиционного анализа. Но этот подход даёт много ложных срабатываний. Например, приводящие к уязвимости вызовы могут быть не задействованы в коде, что делает использование библиотеки безопасным в контексте конкретных найденных уязвимостей. А ещё есть ситуации, когда библиотека найдена в проекте, но используется только в тестах, т.е. не представляет угрозы в рамках исполнения программы в рамках целевого сценария эксплуатации.
  2. Поиск сигнатур вызовов. При таком подходе специальные инструменты по шаблонам ищут в коде «признаки опасности» — сигнатуры вызовов, через которые злоумышленники могут проэксплуатировать уязвимость. Здесь проверяется уже не только факт подключения библиотеки, но и её использование. Это отсекает часть ложноположительных срабатываний из предыдущего пункта и делает точность подхода выше, но собрать базу таких сигнатур — сложно. Готовых публичных справочников не существует — вендоры собирают эти данные самостоятельно и предоставляют к ним доступ только в рамках своих решений.
  3. Построение графа вызовов. В этом случае инструмент строит целую карту, которая показывает все возможные цепочки вызовов. Это уже более глубокий анализ, который позволяет проверять уязвимости даже в транзитивных зависимостях. Но он сложнее в реализации и требует качественной базы знаний об уязвимых функциях и методах. Но у этого подхода тоже есть недостатки. Например, не учитываются сами данные, которые передаются в рамках цепочки вызовов. Если данные изначально поступают в безопасном виде, отфильтрованные или экранированные, то проэксплуатировать уязвимость будет невозможно. Для решения этой проблемы применяют следующий метод.
  4. Анализ потока данных. Самый точный и ресурсоемкий метод — автоматическая проверка, может ли пользовательский ввод (то есть данные, которые контролирует злоумышленник) достичь уязвимой функции. Этот подход даёт высокую точность, но значительно сложнее в реализации и заметно уступает в скорости методам, рассмотренным ранее.

Чем точнее анализ, тем больше ресурсов он требует. Поэтому оптимальная стратегия — комбинировать подходы. На этапе проверки нового кода, когда результат нужен быстро, можно использовать менее точные, но быстрые методы. А вот при подготовке релиза лучше запускать максимально точный анализ из доступных. Кроме того, всегда нужно делать проверку транзитивных зависимостей, потому что они часто остаются вне поля зрения анализатора.

Что учесть помимо достижимости

Анализ достижимости — лишь один из этапов «воронки приоритизации». В списке задач команд безопасности, как правило, огромное количество потенциальных проблем безопасности сторонних компонентов. Исправлять их все не всегда нужно в силу неприменимости в конкретном проекте. У подавляющего большинства компаний остро стоит вопрос человеческих ресурсов для разбора таких данных. Тут как раз и помогает “воронка приоритизации”, помогая сфокусироваться в первую очередь на наиболее опасных и важных проблемах.
К примеру, важно проверить наличие версии с исправлением. Если библиотеку можно обновить с минимальными проверками обратной совместимости — это самый эффективный в плане трудозатрат способ повысить безопасность проекта.

Также стоит следить за публичными эксплойтами. Если способ атаки становится известен широкому кругу лиц, риск многократно возрастает. Такие атаки могут проводить даже неопытные злоумышленники, поэтому в рамках приоритизации этот критерий будет крайне полезен.

Анализ достижимости: главное

Анализ достижимости — не панацея, но критически важный инструмент безопасной разработки.

Анализ достижимости отвечает на вопрос: может ли конкретная уязвимость быть проэксплуатирована в конкретном приложении?

Анализ достижимости — это инструмент приоритизации, а не фильтрации. Недостижимые сегодня уязвимости могут стать достижимыми завтра.

Существует несколько уровней анализа. В самом простом варианте это базовая проверка факта использования библиотеки. В более сложных системах применяется анализ директивных и транзитивных зависимостей (с использованием сигнатур, графов вызовов и потока данных). Чем глубже анализ, тем выше его точность и практическая польза, но ниже скорость.

Из-за необходимости выбирать между точностью и скоростью, оптимальная стратегия — комбинирование уровней анализа. Быстрые проверки подойдут на каждый коммит или MR, а глубокий анализ будет полезен при подготовке релизов.

Внедрение анализа достижимости сокращает ручной труд команд безопасности и ускоряет исправление реальных уязвимостей, предоставляя более подробную информацию о коде проекта и использованию в нём опасных библиотек. Аналитики не тратят время на поиск и подтверждение информации о вызовах библиотек в коде, а сразу переходят к исправлению потенциально опасных мест.

Наш опыт

В продукте CodeScoring тоже реализован механизм проверки достижимости для найденных уязвимостей в языках Java, Kotlin, Python, Go, C#, Javascript и Typescript. Для наполнения базы знаний мы использовали не самый быстрый, но наиболее качественный подход с ручной разметкой уязвимых методов. Это позволило получить более 26 тысяч сигнатур методов для почти 8 тысяч уязвимостей. И мы регулярно проводим расширение покрытия, так что это число постоянно растёт. Для построения графа вызовов реализована интеграция с хорошо зарекомендовавшем себя статическим анализатором Svace от ИСП РАН. Это позволяет получать полное покрытие приложения в рамках call-graph с учётом транзитивных зависимостей и находить в коде реально использующиеся функции и методы.

Автор:
руководитель разработки продукта платформы безопасной разработки CodeScoring Антон Володченко

На нашем сайте мы используем cookie файлы, содержащие информацию о предыдущих посещениях веб-сайта. Данные обрабатываются для улучшения качества работы нашего веб-сайта. Если вы не хотите использовать cookie файлы, измените настройки браузера.