Enclave: Nice2Meet: We Turned Teams Mobile Meetings Into a Silent Account Takeover<br>Skip to main content
Back to BlogNice2Meet: We Turned Teams Mobile Meetings Into a Silent Account Takeover<br>How a small code mistake allowed hijacking the Microsoft accounts of everyone in a Teams meeting.<br>Yanir TsarimiCo-founder & CPOAugust 12, 2026
Ever hopped on a Microsoft Teams meeting? What you didn’t know is that everyone on that call could have direct access to everything in your account: email, files, calendar, and more.<br>The vulnerability? Just requires sharing a whiteboard screen on the meeting - and you can steal everyone’s account tokens.<br>The tokens allow full access to the Microsoft 365 account: mail, files, calendar, SharePoint, cloud. Full account takeover, for every mobile user in the meeting, simultaneously .
Initial Clue<br>We were looking at the Teams Mobile whiteboard feature. The whiteboard lets you draw anything you want to other participants. Teams Mobile renders the whiteboard inside a WebView, a browser embedded in the native app.<br>However, we noticed a feature that was interesting. The whiteboard WebView accepted a changeWhiteboardUrl event.<br>The event is designed to sync the whiteboard URL across all participants in a session. When one participant fires it, everyone else's WebView loads the new URL.<br>We passed it an arbitrary URL, and… It loaded. Zero restrictions.<br>Then we asked: what can we do with this feature?<br>Looking Deeper<br>To communicate between the whiteboard and the native app, Teams registers a JavaScript bridge called nativeInterface.<br>We figured out this bridge was actually accessible through the whiteboard WebView. Since we could redirect anyone to our controlled domain, we could make direct requests on the participants’ behalf to their native application.<br>Imagine our surprise when we’ve found nativeInterface supports.. generating account tokens.<br>Understanding the Mistake<br>Teams does have a domain allowlist for which URLs can be used.<br>It runs at shouldOverrideUrlLoading, the standard Android WebView hook for intercepting user-initiated navigation.<br>But changeWhiteboardUrl didn’t go through shouldOverrideUrlLoading. It called loadUrl() directly. This path only validates if it’s a valid URL.<br>The interesting question is why these two paths diverged. loadUrl() called directly in code does not trigger shouldOverrideUrlLoading. Whoever implemented the URL sync logic used the direct API call. A small mistake but a high price to pay.<br>All The Tokens, All At Once<br>To test, we set up a server and a rogue Android device that attempts to harvest those tokens.<br>After joining our meeting, our Android device shares a whiteboard, then injects this into their own whiteboard WebView:<br>nativeInterface.framelessPostMessage(JSON.stringify({<br>id: 999,<br>func: "changeWhiteboardUrl",<br>args: [""]<br>}));Teams broadcasts this to all other participants. On each victim device, WhiteboardWebView.handleWhiteboardUrlChange() receives the URL and calls loadUrl() directly. The attacker's page loads inside Teams' privileged WebView, with full nativeInterface access, on every mobile participant's device simultaneously.<br>Then, from the attacker's hosted page, now running on every victim device, we could use the API to retrieve a token, then exfiltrate it to our own server.<br>nativeInterface.framelessPostMessage(JSON.stringify({<br>id: 1,<br>func: "authentication.getAuthToken",<br>args: [[""]]<br>}));A meeting with ten people on mobile is ten accounts. One shot.<br>Behind The Tokens<br>In testing, on real non-emulated devices running the latest Teams on both platforms, we retrieved:<br>Microsoft Graph (graph.microsoft.com): Mail.ReadWrite, Mail.Send, Files.ReadWrite.All, Calendars.ReadWrite, ChatMessage.Send, Sites.ReadWrite.All<br>Outlook (outlook.office365.com): EWS.AccessAsUser.All, Mail.ReadWrite, Mail.Send, OWA.AccessAsUser.All, Files.ReadWrite.All<br>SharePoint (00000003-0000-0ff1-ce00-000000000000): Sites.FullControl.All, Sites.Manage.All, User.ReadWrite.All, MyFiles.Write<br>Azure (cfa8b339-82a2-471a-a3c9-0fc0be7a4093): user_impersonation<br>Mail.Send means the attacker sends email as the victim. Files.ReadWrite.All covers every file in OneDrive. The SharePoint and Azure scopes allows full access downstream.<br>Affects both iOS and Android<br>The root cause is the same: changeWhiteboardUrl passes the URL to loadUrl() without domain validation on either platform.<br>The iOS behavior is slightly different. During token exfiltration, the Microsoft Authenticator app visibly opens on the victim's device, a side effect of how iOS routes certain token requests through the bridge. You can see it in our POC video.<br>Takeaways<br>We are seeing those types of bugs more and more. A small code mistake leads to a critical vulnerability.<br>Whoever wrote this code didn’t ship a vulnerability. They were doing everything right, but they were just unaware of the threat model of the application. And to be fair, it is not an easy task.<br>That’s why the app needs to be analyzed often, with the context of the...