Безопасность

«LLM находит логические уязвимости, а не только общие классы багов»: ИИ-агент GitHub Security Lab отчитался о 24 уязвимостях в Android-приложениях

GitHub Security Lab добавила в свой открытый ИИ-агент Taskflow Agent таскфлоу для аудита Android-приложений и отчиталась о 24 подтверждённых уязвимостях. Среди разобранных примеров — слежка за геолокацией в навигаторе OsmAnd и захват аккаунта Wikipedia через deeplink. Автор материала предупреждает: модель хорошо находит уязвимости, но плохо оценивает их серьёзность, поэтому каждый отчёт обязан проверять человек.

«LLM находит логические уязвимости, а не только общие классы багов»: ИИ-агент GitHub Security Lab отчитался о 24 уязвимостях в Android-приложениях

Что произошло

Инженер GitHub Security Lab Кевин Стаббингс описал, как собрал набор таскфлоу для аудита Android-приложений поверх открытого GitHub Security Lab Taskflow Agent — фреймворка, который позволяет исследователям безопасности упаковывать, автоматизировать и переиспользовать ИИ-промпты и рабочие процессы. Через эти таскфлоу он отправил вендорам больше 20 уязвимостей в Android-приложениях, а к моменту публикации статьи счётчик остановился на 24 находках.

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

Повод для отдельного набора таскфлоу конкретный: базовые аудиторские процессы Security Lab рассчитаны на смешанные репозитории, а у мобильных приложений своя поверхность атаки — экспортированные компоненты, intent'ы, WebView и deeplink'и, и её нужно было явно прописать в промптах.

Две правки промптов, которые изменили результат

Первое изменение — новый таскфлоу gather_mobile_entry_point_info.yaml. Он берёт все точки входа, через которые в код может попасть управляемый злоумышленником ввод, и разделяет их на мобильные и немобильные. Это нужно, чтобы агент строил корректную поверхность атаки в репозиториях, где рядом с мобильным приложением лежат веб-серверы или десктопные части.

Второе — правка classify_application_local.yaml: в него добавлен список популярных классов уязвимостей, которые модель обязана проверить для каждой точки входа и каждого компонента. Если на предыдущем шаге точка входа определена как intent-based, агент получает набор типовых проблем именно этого класса — например, confused deputy или незащищённые broadcast-сообщения.

Автор отдельно объясняет, зачем нужны оба подхода сразу: строгий промпт и повторные прогоны не дают пропустить очевидное, а широкий промпт оставляет модели свободу для нестандартных находок. Комбинация, по его наблюдению, и даёт лучший результат на реальных приложениях.

OsmAnd: экспортированная активность превращается в слежку

Первый разобранный пример — OsmAnd, популярный сторонний навигатор на данных OpenStreetMap: у Android-версии больше 10 миллионов загрузок, найдено три уязвимости, и самая интересная позволяет стороннему приложению отслеживать местоположение устройства.

Причина — экспортированная активность MapActivity, которая открывает файлы настроек и обрабатывает deeplink'и внутри приложения. Настройки импортируются функцией handleOsmAndSettingsImport, а параметры приходят в intent extras: settings_version, silent_import, replace и export_type_list_key. По замыслу они должны были передаваться через AIDL-сервис внутри процесса, но Android не даёт ограничить, какие extras может выставить внешний вызывающий: любое приложение вправе отправить экспортированной активности интент с произвольными extras.

Флаги silent_import, replace и список типов экспорта позволяют незаметно подменить настройки приложения — без уведомления и без подтверждения пользователем. Дальше атакующий подменяет шаблон URL для тайлов карты на свой домен, и координаты x, y каждого загруженного тайла уезжают на его сервер; по тому же шаблону утекают точки старта и финиша маршрутов. Пользователь не видит ни одного изменения в интерфейсе.

Wikipedia: deeplink, WebView и захват аккаунта

Второй пример — Android-приложение Wikipedia. Оно регистрирует обработчик схемы wikipedia:// и передаёт адрес в PageActivity, но проверка хоста сделана через endsWith(WikiSite.BASE_DOMAIN). Логическая ошибка в разборе имени хоста позволяет загрузить не википедийный адрес — например, evil-wikipedia.org.

Это даёт сразу два опасных примитива: пользователя можно увести на подконтрольную страницу, замаскированную под Wikipedia, и выполнить произвольный JavaScript внутри WebView приложения — то есть попасть в среду, которая обычно считается безопасной.

Вторая уязвимость того же класса живёт в SharedPreferenceCookieManager.kt: проверка domain.endsWith(domainSpec) решает, отдавать ли странице cookie от wikipedia.org. Сложив обе ошибки, исследователь получает захват аккаунта: жертва кликает по deeplink'у на вредоносной странице, приложение открывает подконтрольный адрес, похожий на википедийный, и само отправляет свои cookie атакующему — вместе с именем пользователя, долгоживущим токеном и сессионным токеном, действующим во всех проектах Wikimedia, от всех Википедий до Commons, Wikidata и Meta.

Где модель ошибается

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

Вторая проблема — оценка серьёзности. Реальный ущерб зависит от смягчающих факторов, которых модель не видит без отдельного промпта: например, path traversal в Android-приложении, где путь ограничен внешним хранилищем, на практике малоопасен. Чтобы это выяснить, приходится просить модель собрать proof of concept, а это требует дополнительных прогонов и времени на уязвимости, которые в итоге могут оказаться несерьёзными.

Отдельно отмечены ложные срабатывания из-за сложного поведения приложений. Если приложение читает данные и из внутреннего, и из внешнего хранилища, а приоритет у внутреннего, то запись во внешнее хранилище через path traversal ничего не изменит — уязвимости нет, хотя модель её заявит. По мнению автора, такие ошибки будут сокращаться по мере роста контекста и качества рассуждений моделей.

Зато знание API оказалось сильной стороной: по наблюдению команды, модель хорошо понимает поведение security-значимых функций в разных языках даже без доступа к их исходникам — например, разницу между path.Clean и filepath.Clean в Go. Почти все proof of concept, которые просили написать по готовому отчёту, потребовали лишь минимальных правок.

Как проверить свой репозиторий

Таскфлоу открыты: нужно зайти в репозиторий seclab-taskflows, поднять там codespace и выполнить в терминале./scripts/audit/run_mobile.sh myorg/myrepo. На среднем по размеру репозитории прогон занимает час-два, результат открывается в SQLite-просмотрщике, а искать надо строки с отметкой в колонке has_vulnerability таблицы audit_results.

Ограничения названы прямо: нужна лицензия GitHub Copilot, промпты расходуют premium-запросы, а большое число вызовов инструментов быстро съедает токены.

Список уже раскрытых находок команда ведёт отдельно — на странице AI-агентов GitHub Security Lab.

Выводы автора шире одного класса приложений: уязвимости нашлись ровно там, где исследователь мобильной безопасности и ожидал их найти, — cross-app scripting в WebView и открытые JavaScript-мосты. При этом защита Android-приложений оценивается как довольно крепкая, и именно поэтому ИИ-агент полезен в первую очередь как способ масштабировать разбор открытого кода — одинаково для веба, мобильных и десктопных приложений.

Первоисточники

  1. GitHub Blog — Kevin Stubbings, «How we found 24 Android vulnerabilities using our open source AI security agent» (28 сентября 2026)
  2. GitHub Security Lab — AI agents: страница проектов и раскрытых уязвимостей
  3. GitHub — GitHubSecurityLab/seclab-taskflows: открытые таскфлоу для аудита, включая run_mobile.sh
  4. GitHub — GitHubSecurityLab/seclab-taskflow-agent: фреймворк Taskflow Agent