# XSS to OAuth access token leak in office online which can be used to account takeover

Reflected XSS in oauth.online.office.com replyUrl parameter lets attacker spoof data-origin and steal OAuth access/ID tokens for account takeover.

- Payout: unconfirmed
- Severity: high
- Program: Microsoft
- Credited: Renwa
- Disclosed: 2024-01-12
- Write-up quality: 8/10
- Original: https://gist.github.com/RenwaX23/0311842bb790ce98fe0cd8f41141fdf0
- Library page: https://bugbountylibrary.com/r/blog%3Agist-github-com-renwax23-0311842bb790ce98fe0cd8f41141fdf0
- Tags: domain:web impact:ato impact:data-leak kind:bounty platform:blog sev:high tech:oauth technique:js-analysis technique:source-review vuln:account-takeover vuln:xss

**Target:** OAuth token endpoint WacOAuth.aspx
**Root cause:** replyUrl parameter reflected unescaped into script tag data-origin attribute, allowing attribute breakout and script injection despite CSP.
**Steps:**
1. Visit www.office.com, open Word new document, observe iframe to word-edit.officeapps.live.com and postMessage to oauth.online.office.com
2. Test replyUrl=https://word-edit.officeapps.live.com#test to confirm hash fragment reflected into data-origin
3. Inject `replyUrl=https://word-edit.officeapps.live.com%23"></script><script data-origin="https://example.wtf" data-scriptload="PRODUCTION.50: 20230319.13" id="sharedauthscript" src=https://wise.public.cdn.office.net/wise/owl/sharedauthclient.f6062603a9a69f15721f.js></script>`
4. Frame the page and postMessage SharedAuth_Init and SharedAuth_TryGetToken to receive tokens
**How found:** Used postMessage logger to observe SharedAuth messages between Word editor and OAuth page, then probed replyUrl parsing with @, paths, params, and hash to find reflection point.
**Exploitation:** Attacker frames the OAuth page, spoofs data-origin to attacker host, sends postMessage requests for tokens, receives access/ID tokens and user info for account takeover.
**Insight:** When CSP blocks inline handlers, look for attribute injection into script tags to hijack dataset values used for postMessage origin checks.
