From 0c5ec5181a9ebedccd90d6068cf8a96ddf02b17f Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Fri, 16 Jan 2026 18:45:49 +0000 Subject: [PATCH] Add content from: Leaking fbevents: OAuth code exfiltration via postMessage tr... --- src/pentesting-web/oauth-to-account-takeover.md | 17 ++++++++++++++--- .../postmessage-vulnerabilities/README.md | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/pentesting-web/oauth-to-account-takeover.md b/src/pentesting-web/oauth-to-account-takeover.md index f8b019d0c4b..6594dfb3497 100644 --- a/src/pentesting-web/oauth-to-account-takeover.md +++ b/src/pentesting-web/oauth-to-account-takeover.md @@ -139,9 +139,13 @@ Connection: close code=77515&redirect_uri=http%3A%2F%2F10.10.10.10%3A3000%2Fcallback&grant_type=authorization_code&client_id=public_client_id&client_secret=[bruteforce] ``` -### Referer Header leaking Code + State +### Referer/Header/Location artifacts leaking Code + State + +Once the client has the **code and state**, if they surface in **`location.href`** or **`document.referrer`** and are forwarded to third parties, they leak. Two recurring patterns: + +- **Classic Referer leak**: after the OAuth redirect, any navigation that keeps `?code=&state=` in the URL will push them into the **Referer** header sent to CDNs/analytics/ads. +- **Telemetry/analytics confused deputy**: some SDKs (pixels/JS loggers) react to `postMessage` events and then **send the current `location.href`/`referrer` to backend APIs using a token supplied in the message**. If you can inject your own token into that flow (e.g., via an attacker-controlled postMessage relay), you can later read the SDK’s API request history/logs and recover the victim’s OAuth artifacts embedded in those requests. -Once the client has the **code and state**, if it's **reflected inside the Referer header** when he browses to a different page, then it's vulnerable. ### Access Token Stored in Browser History @@ -167,7 +171,13 @@ Combining a replay-friendly code with any `redirect_uri` or logging bug allows p ### Authorization/Refresh Token not bound to client -If you can get the **authorization code and use it with a different client then you can takeover other accounts**. +If you can get the **authorization code** and **redeem it for a different client/app**, you can takeover other accounts. Test for weak binding by: + +- Capturing a `code` for **app A** and sending it to **app B’s token endpoint**; if you still receive a token, audience binding is broken. +- Trying first-party token minting endpoints that should be restricted to their own client IDs; if they accept arbitrary `state`/`app_id` while only validating the code, you effectively perform an **authorization-code swap** to mint higher-privileged first-party tokens. +- Checking whether client binding ignores nonce/redirect URI mismatches. If an error page still loads SDKs that log `location.href`, combine with Referer/telemetry leaks to steal codes and redeem them elsewhere. + +Any endpoint that exchanges `code` → token **must** verify the issuing client, redirect URI, and nonce; otherwise, a stolen code from any app can be upgraded to a first-party access token. ### Happy Paths, XSS, Iframes & Post Messages to leak code & state values @@ -332,5 +342,6 @@ In mobile OAuth implementations, apps use **custom URI schemes** to receive redi - [**https://blog.doyensec.com/2025/01/30/oauth-common-vulnerabilities.html**](https://blog.doyensec.com/2025/01/30/oauth-common-vulnerabilities.html) - [An Offensive Guide to the OAuth 2.0 Authorization Code Grant](https://www.nccgroup.com/research-blog/an-offensive-guide-to-the-authorization-code-grant/) - [OAuth Discovery as an RCE Vector (Amla Labs)](https://amlalabs.com/blog/oauth-cve-2025-6514/) +- [Leaking fbevents: OAuth code exfiltration via postMessage trust leading to Instagram ATO](https://ysamm.com/uncategorized/2026/01/16/leaking-fbevents-ato.html) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/postmessage-vulnerabilities/README.md b/src/pentesting-web/postmessage-vulnerabilities/README.md index de19a76d9f9..d3e10be64e3 100644 --- a/src/pentesting-web/postmessage-vulnerabilities/README.md +++ b/src/pentesting-web/postmessage-vulnerabilities/README.md @@ -128,6 +128,21 @@ In order to **find event listeners** in the current page you can: - The `document.domain` property in JavaScript can be set by a script to shorten the domain, allowing for more relaxed same-origin policy enforcement within the same parent domain. +### Origin-only trust + trusted relays + +If a receiver only checks **`event.origin`** (e.g., trusts any `*.trusted.com`) you can often find a **"relay" page on that origin that echoes attacker-controlled params via `postMessage`** to a supplied `targetOrigin`/`targetWindow`. Examples include marketing/analytics gadgets that take query params and forward `{msg_type, access_token, ...}` to `opener`/`parent`. You can: + +- **Open the victim page in a popup/iframe that has an `opener`** so its handlers register (many pixels/SDKs only attach listeners when `window.opener` exists). +- **Navigate another attacker window to the relay endpoint on the trusted origin**, populating message fields you want injected (message type, tokens, nonces). +- Because the message now comes **from the trusted origin**, origin-only validation passes and you can trigger privileged behaviors (state changes, API calls, DOM writes) in the victim listener. + +Abuse patterns seen in the wild: + +- Analytics SDKs (e.g., pixel/fbevents-style) consume messages like `FACEBOOK_IWL_BOOTSTRAP`, then **call backend APIs using a token supplied in the message** and include **`location.href` / `document.referrer`** in the request body. If you supply your own token, you can **read these requests in the token’s request history/logs** and exfil **OAuth codes/tokens** present in the URL/referrer of the victim page. +- Any relay that reflects arbitrary fields into `postMessage` lets you **spoof message types** expected by privileged listeners. Combine with weak input validation to reach Graph/REST calls, feature unlocks, or CSRF-equivalent flows. + +Hunting tips: enumerate `postMessage` listeners that only check `event.origin`, then look for **same-origin HTML/JS endpoints that forward URL params via `postMessage`** (marketing previews, login popups, OAuth error pages). Stitch both together with `window.open()` + `postMessage` to bypass origin checks. + ### e.origin == window.origin bypass When embedding a web page within a **sandboxed iframe** using %%%%%%, it's crucial to understand that the iframe's origin will be set to null. This is particularly important when dealing with **sandbox attributes** and their implications on security and functionality. @@ -236,6 +251,7 @@ For **more information**: - [https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html](https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html) - [https://dev.to/karanbamal/how-to-spot-and-exploit-postmessage-vulnerablities-36cd](https://dev.to/karanbamal/how-to-spot-and-exploit-postmessage-vulnerablities-36cd) +- [Leaking fbevents: OAuth code exfiltration via postMessage trust leading to Instagram ATO](https://ysamm.com/uncategorized/2026/01/16/leaking-fbevents-ato.html) - To practice: [https://github.com/yavolo/eventlistener-xss-recon](https://github.com/yavolo/eventlistener-xss-recon) {{#include ../../banners/hacktricks-training.md}}