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

Что произошло
Инженер 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-приложений оценивается как довольно крепкая, и именно поэтому ИИ-агент полезен в первую очередь как способ масштабировать разбор открытого кода — одинаково для веба, мобильных и десктопных приложений.
Первоисточники
- GitHub Blog — Kevin Stubbings, «How we found 24 Android vulnerabilities using our open source AI security agent» (28 сентября 2026)
- GitHub Security Lab — AI agents: страница проектов и раскрытых уязвимостей
- GitHub — GitHubSecurityLab/seclab-taskflows: открытые таскфлоу для аудита, включая run_mobile.sh
- GitHub — GitHubSecurityLab/seclab-taskflow-agent: фреймворк Taskflow Agent