Приложению не дали ни одного разрешения, а оно всё равно забрало рабочую почту. Разбор дыры в Microsoft Authenticator
23 октября ребята из Enclave выложили разбор уязвимости в Microsoft Authenticator для Android. Её уже закрыли, но устроена она настолько просто, что хочется пересказать.
Authenticator на Android работает как брокер. Teams, Outlook и остальные приложения Microsoft не спрашивают у вас пароль сами. Они идут к Authenticator и говорят: я Teams, дай мне токен на почту и файлы этого человека. Брокер проверяет, кто пришёл, и выдаёт.
Ошибка как раз в проверке. В Authenticator был экран AccountChooserActivity, и запустить его могло любое приложение на телефоне. Приложение передавало туда JSON, в котором само писало, кто оно такое: имя пакета и адрес возврата (redirect URI). Брокер брал имя пакета из этого же JSON, просил у системы сертификат подписи этого пакета, считал от него хэш и сравнивал с присланным адресом. Совпало, значит свой.
Только сертификат подписи на Android не секрет. Любое приложение может спросить у системы сертификат Teams, который у вас уже стоит, и посчитать тот же самый хэш. Проверка смотрела, сходится ли рассказ, а кто его рассказывает, не спрашивала. Как охранник, который убедился, что пропуск настоящий, и не посмотрел, тот ли человек его принёс.
На выходе злоумышленник получал access и refresh токены от имени Teams: почту, файлы, календарь и чаты рабочего аккаунта. По refresh токену доступ можно продлевать и дальше. Приложению при этом не нужно ни одного разрешения и не нужен root, от человека требовалось только его установить. Уязвимости дали 8.6 из 10, номер CVE-2026-80097.
Исправили в версии 6.2606.4246. Если у вас в Authenticator есть рабочий аккаунт, обновитесь. Админам советуют больше: токены с устройств, где стояла старая версия, считать утёкшими и отозвать refresh токены.
Я пишу ботов и сайты на заказ, и та же самая ошибка, только попроще, попадалась мне в чужом коде, который приносили доделать. Бот берёт id пользователя из параметра в ссылке или из данных кнопки, а не из того, что прислал сам Telegram. Сайт считает тебя админом, потому что так написано в скрытом поле формы. Правило тут одно: кто к тебе пришёл, спрашивай у системы, а не у того, кто пришёл. В Android для этого есть getCallingPackage() и Binder.getCallingUid(), в Telegram-боте это from.id из апдейта, на сайте сессия на сервере.
Если вы смотрите чужой код и не знаете, с чего начать, начните с этого места. Даже у Microsoft оно оказалось дырявым.
