Full Report
Meta's web ecosystem relies on cross-window messaging between first-party websites. The only security control is around origin checks on facebook.com or its subdomains. Multiple Meta modules register window message listeners that must be from a trusted domain. One of these is fbevents.js, the Meta Pixel script embedded on millions of websites. When loaded in a window, the message listener reacts to many events and sends them via the graph.facebook.com send. This includes location.href and document.referrer, which can contain OAuth codes and other sensitive values. The author founa n endpoint that constructs an object from user-supplied parameters and forwards it via postMessage to a target Facebook domain specified by the attacker. This appears to be a classic confused deputy problem, where the data is passed through without any checks from a trusted domain. The fbevents.js code receives messages originating from facebook.com. By using the primitive from above with an arbitrary message send and including an attacker's access_token for GraphQL, requests can be tricked into exposing OAuth code/tokens to the attacker. By doing this, an account takeover may be possible. Here's the flow of the attack: Trick the user into clicking on a crafted link that abuses the issues from above. To start with, an OAuth callback on Instagram to developers.facebook.com. The page developers.facebook.com, contains the fbevent.js file and has the message listener. To prevent the page from consuming the token, an invalid nonce must be used. Attacker redirects their website to the postMessage sync discussed from before with the attacker-controlled GraphQL access token. fbevents.js will consume the message and issue a GraphQL request with the sensitive information, including the OAuth code. Attacker reviews the Graph Explorer to retrieve the Instagram OAuth authorization code. There is no description of the patch. To patch this, I'd probably get rid of the postMessage sink first. Then, remove the href and referrer from the GraphQL endpoint data, if possible. The author claims that the attack surface expands beyond Meta properties and to third-party websites because of how widely deployed this is. They got $32K for this bug!
Analysis Summary
# Vulnerability: Cross-Origin Message Hijacking via Trusted Script Leading to OAuth Code Exfiltration
## CVE Details
- CVE ID: Not specified in the provided text.
- CVSS Score: Not specified in the provided text. (Likely High due to Account Takeover potential)
- CWE: CWE-201 (Improper Input Validation) and CWE-264 (Permissions, Privileges, and Access Controls) - related to Confused Deputy.
## Affected Systems
- Products: Meta (Facebook/Instagram) Web Ecosystem, specifically code within `fbevents.js` (Meta Pixel script).
- Versions: Not specified, affecting configurations where the logic relying solely on `event.origin === 'facebook.com'` validation is present.
- Configurations: Any window context (including third-party sites) loading `fbevents.js` that has an `opener` window, particularly in flows involving OAuth callbacks on `developers.facebook.com`.
## Vulnerability Description
The vulnerability is a Confused Deputy scenario rooted in Meta's cross-window messaging control relying only on origin checks (`facebook.com` or subdomains). The Meta Pixel script, `fbevents.js`, registers a message listener that trusts messages originating from Meta domains.
An attacker can leverage a publicly accessible endpoint on `www.facebook.com` to send a *crafted* `postMessage` to a trusted window (e.g., a window handling an OAuth callback on `developers.facebook.com`). This crafted message includes an attacker-controlled GraphQL `access_token`.
When `fbevents.js` receives this message, it executes a GraphQL request to `graph.facebook.com` using the attacker-supplied token. Crucially, the request payload includes sensitive context data harvested from the victim's window, specifically `location.href` and `document.referrer`. Since these values can contain sensitive artifacts like Instagram OAuth authorization codes, successful exploitation leads to data exfiltration traceable via the attacker’s Graph Explorer history.
## Exploitation
- Status: Proof-of-Concept (PoC) available in the source material (HTML files provided).
- Complexity: Low to Medium. Requires redirecting the victim through a crafted OAuth flow setup to trigger the necessary context, followed by the coordinated `postMessage`.
- Attack Vector: Network (Requires user interaction via a crafted link/redirect).
### Attack Flow Summary:
1. Victim initiates an Instagram OAuth flow redirecting to `developers.facebook.com`, deliberately using an invalid nonce to land on an error page still executing `fbevents.js`.
2. The attacker redirects the victim's window (or a cross-window opener) to a malicious URL on `www.facebook.com` designed to trigger the `postMessage` sink with the attacker's GraphQL token.
3. `fbevents.js` processes the message, sending the victim's OAuth code (present in `location.href` or `referrer`) in a GraphQL request tied back to the attacker's token.
4. Attacker retrieves the OAuth code via their Graph Explorer history.
5. The stolen code is used to generate a first-party Instagram Access Token, enabling account takeover.
### Impact
- Confidentiality: High (Theft of highly sensitive OAuth authorization codes and session tokens).
- Integrity: High (Enables unauthorized access/modification via subsequent token usage, potentially leading to **Account Takeover**).
- Availability: Low (No direct impact on service availability).
## Remediation
### Patches
- The article **does not explicitly name the patch release or version.**
- *Author Suggested Patch:* Remove the `postMessage` sink entirely, and if the sink must remain, strip `location.href` and `document.referrer` from the data forwarded to the GraphQL endpoint invocation.
### Workarounds
- No vendor-provided workarounds were listed.
- *Inferred Workaround:* If possible, restrict the use of application flows that involve communication between windows where one acts as an opener/receiver of OAuth callbacks on properties loading `fbevents.js`, or ensure strict origin checks beyond just `facebook.com`.
## Detection
- **Indicators of Compromise (IoCs):** Monitoring Graph Explorer history associated with potentially compromised/attacker-controlled access tokens for outgoing GraphQL requests containing parameters suggestive of OAuth flow context (`location.href`, `referrer`).
- **Detection Methods:** Dynamic analysis of `fbevents.js` execution context to identify unauthorized `postMessage` processing or unexpected GraphQL calls sourced from these internal handlers when non-application context is present.
## References
- Vendor Advisories: None explicitly listed, noted Meta fixed the bug internally.
- Relevant Links:
- Article Source: hxxps://ysamm.com/