Microsoft Authenticator on Android does more than generate codes. It acts as an authentication broker, a privileged middleman that handles Single Sign-On (SSO), tracks the device’s identity state, and satisfies the Conditional Access policies Microsoft Entra ID enforces. When you open Teams or Outlook, the app rarely authenticates against the resource server itself. It hands the credential exchange to the broker.
That convenience puts a lot of risk in one place. If the broker can’t reliably tell who is asking for a token, the rest of the managed device’s security falls apart with it. This happened in September 2026 with the disclosure of CVE-2026-80097, a high-severity elevation-of-privilege vulnerability that came down to a misunderstanding of trust boundaries in Android’s inter-process communication (IPC) model.
CVE-2026-80097 at a glance
- CVE ID: CVE-2026-80097
- CVSS 3.1 base score: 8.6 (high)
- Weakness: CWE-287, Improper Authentication
- Affected component: the MSAL broker inside Microsoft Authenticator for Android
- Fixed in: Microsoft Authenticator 6.2606.4246
- Impact: a malicious app with no permissions could silently steal access, refresh and ID tokens for the device’s primary work account
Research published by Enclave showed that the attack needed no kernel exploit, no memory corruption, and no user action beyond installing the malicious app. The bug sat entirely in logic. An exported Android Activity in the Microsoft Authentication Library (MSAL) broker accepted identity claims from the caller without checking where the call actually came from.
The case is a good lesson in the gap between reachability and authorization on Android, and in why cryptographically checking untrusted input is a poor substitute for asking the operating system who the caller is.
How the Microsoft Authenticator broker works on Android
Enterprise apps reach Microsoft Graph resources such as Exchange mailboxes, SharePoint libraries and OneDrive files with OAuth 2.0 access tokens. If every app made the user type credentials and pass an MFA prompt, the device would be unusable. The broker fixes that by keeping a central token cache and running interactive sign-in flows for the whole device.
When a client app like Teams needs a token, it builds an authentication request and passes it to the Authenticator app. The broker evaluates the request and checks its cache for a valid access or refresh token. If it needs a silent refresh, it talks to Entra ID. Then it returns the token material to the client.
This only works if the broker can be certain the requester is the registered app it claims to be. If a malicious app can trick the broker into returning a token meant for Teams, the attacker gets the same delegated permissions as the victim’s Teams app. In an enterprise tenant those scopes often include Mail.ReadWrite, Files.ReadWrite.All and Calendars.ReadWrite. The broker holds the keys, so its ability to tell a registered Microsoft first-party app from a hostile third-party app riding on the user’s active session is the whole security model.
Why exported Android components matter
Android sandboxes apps by default. Each one runs under its own Linux User ID (UID), which keeps apps out of each other’s memory and private files. Apps still have to cooperate, so Android provides Intents for message passing. A developer can mark an Activity, Service or Broadcast Receiver as android:exported="true" to tell the OS that other apps may invoke it.
For an authentication broker, exporting an Activity is a functional requirement, because any app that wants SSO has to be able to reach it. The risk comes from how the component authenticates the caller once the connection exists.
The vulnerable component: AccountChooserActivity
The vulnerable component was com.microsoft.identity.client.AccountChooserActivity. It runs in the broker’s isolated :auth process and was exported to receive authentication requests from client apps. A client packages its requirements into an Intent and launches the Activity with startActivityForResult. The Activity parses the Intent and starts acquiring tokens.
📬 Stay Ahead of Cyber Threats
Get the latest cybersecurity news, critical vulnerabilities, threat intelligence, tutorials, and exclusive giveaways delivered straight to your inbox. No spam. Unsubscribe anytime.
Subscribe to the Newsletter →The threat model went wrong at one assumption: that the data in the Intent extras could be trusted to describe who the caller was.
Root cause: the broker trusted the caller’s own identity claims
The MSAL broker protocol passes a JSON structure in the broker_request_v2 Intent extra. It carries the requested scopes, the target authority, the client ID, and the claimed package name and redirect URI of the requesting app. A secure broker would treat those values as hints and compare them against the OS-verified identity of the process that launched the Activity.
The vulnerable AccountChooserActivity did the reverse. It pulled the caller’s UID, package name and redirect URI from the attacker-controlled JSON and used those values to make its security decision.
The check lived in a routine conceptually like isValidCallingApp. The broker took the package name from the JSON (say the attacker claimed com.microsoft.teams) and asked Android’s PackageManager for the signing certificate of the installed Teams app. It hashed that certificate, derived the expected redirect URI for the package, and compared it to the redirect URI in the payload. A match meant the caller was authorized.
This verified the internal consistency of the attacker’s claim and never checked where the claim came from. The broker proved that the redirect URI matched Teams’ signing certificate. It never asked whether the process making the request held that certificate.
PackageManager is a public API, so any unprivileged app can read another package’s signing certificates. An attacker can read the real Teams signature, repeat the broker’s hashing and encoding, and build a valid redirect URI. The broker’s check then passes. It’s like asking someone for a password and accepting it when they read it off a sticky note on the monitor.
How the exploit worked, step by step
The attack needed no special permissions and no root. A malicious app declaring zero Android permissions could run it in the background:
- Query
PackageManagerfor the UID and signing signature of the target app, such as Microsoft Teams. - Compute the valid redirect URI from that signature.
- Build a
broker_request_v2JSON payload claiming Teams’ identity, using the legitimate Teams client ID (1fec8e78-bce4-4aaf-ab1b-5451cc387264) and broad Microsoft Graph scopes such ashttps://graph.microsoft.com/.default. - Create an explicit Intent aimed at
com.microsoft.identity.client.AccountChooserActivityin thecom.azure.authenticatorpackage, with the spoofedcaller.info.uidextra set to the real Teams UID. - Call
startActivityForResultwith the poisoned Intent.
Because the Activity was exported, Android delivered the Intent. The broker parsed the JSON, ran its flawed validation, and found a valid redirect URI, a recognized client ID and a matching UID. The user already had an active session in Authenticator, so the broker silently got fresh access and refresh tokens for the requested Graph scopes from Entra ID. It then returned them through the standard activity result mechanism, and the access, refresh and ID tokens landed in plaintext in the malicious app’s onActivityResult callback. The app could have been a game or a weather widget.
What attackers can do with stolen Microsoft Graph tokens
Once the malicious app holds a Graph token, it no longer needs the phone. It can send the token to a command-and-control server and call Microsoft 365 APIs from anywhere. The tokens carry Teams’ delegated permissions, so the attacker inherits the victim’s access. That includes reading and sending email, downloading files from SharePoint and OneDrive, reading calendar invites with confidential meeting links, and reading internal Teams chats. Entra ID sees these calls as legitimate traffic from an authorized client acting for a compliant user.
The flaw gave delegated access, not tenant-wide admin rights or application permissions that skip user consent. Delegated access means the attacker can do anything the victim can do, and for a typical knowledge worker that is close to full account compromise. Stealing the refresh token also gives persistence. A password change or an expiring access token doesn’t help, because the attacker keeps minting new access tokens until an administrator explicitly revokes the refresh token.
How to verify callers securely on Android
Android already provides OS-level ways to identify the source of an IPC request. When an Activity is started with startActivityForResult, getCallingActivity() and getCallingPackage() return the real package name of the calling process, derived from its Linux UID. For bound Services using Binder IPC, Binder.getCallingUid() identifies the caller.
The Authenticator’s problem wasn’t missing APIs. Logs and decompiled code suggest the broker knew the real calling package. It used that value for parallel-request bookkeeping and logging, and it made its authorization decisions from the spoofed JSON instead. The client-to-broker boundary was treated as friendly when it should have been treated as hostile. Anything that crosses a trust boundary is untrusted input, and the caller’s identity is a fact the receiver has to establish with trusted system primitives.
A secure broker should work in this order:
- Read the true caller identity with
getCallingPackage()orBinder.getCallingUid(). - Compare it to an internal allowlist of registered, trusted client apps.
- Only then parse the Intent payload to see what the caller is asking for.
The payload may set scopes or the target authority. It must never set the caller’s identity. Redirect URI validation helps against open redirects in web flows, but it can’t establish process identity in local IPC.
CVE-2026-80097 remediation: what admins should do
Update every managed Android device to Microsoft Authenticator 6.2606.4246 or later, which enforces proper caller verification. Patching is only the first step. The flaw allowed silent theft of long-lived refresh tokens, so assume tokens may be compromised on any device that ran a vulnerable broker version.
Hunt for token abuse in Entra ID and Defender for Cloud Apps
Review audit logs for unusual token use. Look for tokens issued to the Microsoft Teams client ID that show up from unexpected IP addresses, impossible-travel locations or unfamiliar user agents. The attacker holds legitimate delegated tokens, so standard sign-in risk detections may stay quiet if the attacker mimics the victim’s normal behavior.
Tighten Conditional Access and revoke sessions
Enforce strict device compliance in Conditional Access. If a device runs a vulnerable broker version or fails integrity checks, Entra ID should block token issuance and revoke existing sessions. Revoke refresh tokens for affected users as well, since that is what ends the attacker’s persistence.
Lessons for Android developers
The lesson applies well beyond Microsoft. Anyone building an authentication broker, password manager, payment gateway or secure enclave on a mobile platform can make the same mistake. Android Intents make IPC easy, which hides the security cost of exported components. Developers often conflate reachability with authorization and assume the OS will keep out anyone a partner API wasn’t meant for. It won’t. An exported component is a public surface, and attackers will probe, fuzz and abuse it.
Anchor trust in the OS-level identity of the calling process, and never infer it from how well a request is formed or how consistent its payload is. Identity brokers keep consolidating access to corporate infrastructure, so they will stay high-value targets, and the basic trust boundary at the edge of the app is where they are won or lost.
FAQs
What is CVE-2026-80097?
CVE-2026-80097 is a high-severity elevation-of-privilege vulnerability (CVSS 3.1 score 8.6, CWE-287) in the MSAL broker inside Microsoft Authenticator for Android. It was disclosed in September 2026. An exported Activity trusted identity claims supplied by the caller, which let a malicious app impersonate a legitimate Microsoft app and collect its tokens.
Does the attack need root access or special permissions?
No. The malicious app needed zero declared Android permissions, no root, and no kernel exploit. The only user action required was installing the app.
Is updating Microsoft Authenticator enough?
No. The flaw allowed silent theft of long-lived refresh tokens, so a patched app does not undo earlier theft. Treat tokens on devices that ran a vulnerable broker version as potentially compromised, and have an administrator revoke refresh tokens for affected users. A password change alone does not cut off an attacker who holds a stolen refresh token.
Can the stolen tokens be used away from the phone?
Yes. Once the malicious app has a valid Microsoft Graph token, it can send it to a remote server and call Microsoft 365 APIs from anywhere. Entra ID sees those calls as legitimate activity from an authorized client.
What was the root cause of the vulnerability?
The broker took the caller’s package name, UID and redirect URI from the attacker-controlled broker_request_v2 JSON and validated them against each other. It did not base its decision on the OS-verified caller identity, even though that was available through getCallingPackage() and Binder.getCallingUid().









