Full Report
The author was hunting for a CSRF vulnerability when they noticed some odd functionality: a random subdomain was capable of performing authorized actions on the main API of the website. This was possible because of a cookie named sid with SameSite=None and Secure. This request required a valid CSRF token though. From testing, the CORS policy was verbose, allowing all requests from subdomains of the main domain. What does this mean? XSS on any sub-domain from the website would lead to access to the sensitive API. They went after some out of scope subdomains on the site, which is a weird thing to do. While on another site, they noticed a postMessage call without an origin check; this is a pretty obvious bad code sink. The functionality was calling arbitrary functions from app window, potentially leading to XSS. However, they couldn't find an easy eval() or something else simple. This turned into a ROP-like challenge, where the user can call arbitrary functions within the application. The function APP.util.setCookie() allowed them to set arbitrary cookies on the various domains. Additionally, they found a powerful JSONP endpoint. The purpose was sending a call to a JSONP endpoint to lead an external script with the user choosing the domain. This JSONP code that could load arbitrary JavaScript is real bad! Since the data could be reflected, by making a postMessage call to this, it would load inline JavaScript. How do we get a one-click interaction though? I don't believe that the postMessage call is accessible from other windows. We need a reference to the page in order to send data via postMessage. But, the website had X-Frame-Options: SAMEORIGIN options, which prevented framing. As an attacker, this can still be opened in a pop-up window to get a reference, which is news to me! Using the issues above, we can do the following: Get user to visit our page. Open a pop-up window that creates a reference to the page with the vulnerable functionality. Use the postMessage call to get XSS via the JSONP endpoint. Our attack payload is to ask for a CSRF token then make various API calls to modify and retrieve data. Overall, a great bug chain leading to a horrible CSRF. To me, the poorly misconfigured CORS and lack of origin check on the postMessage were defense-in-depth issues that led to the exploitation of this; this is why these small things matter.
Analysis Summary
# Vulnerability: Bug Chain Leading to CSRF via Insecure Subdomain Functionality
## CVE Details
- CVE ID: Not explicitly assigned in the provided text. The author reports the finding to a bug bounty program.
- CVSS Score: 7.1 (High) - Based on author's self-assessed vector: `AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:N`
- CWE: Multiple, including CWE-384 (Missing Authentication for Critical Function), CWE-918 (Server-Side Request Forgery (SSRF) via SSRF/JSONP misuse), CWE-20 (Improper Input Validation for postMessage), and CWE-352 (Cross-Site Request Forgery).
## Affected Systems
- Products: Undisclosed web application and its associated subdomains (`redacted.com`).
- Versions: Not specified. The vulnerability is configuration/implementation-dependent.
- Configurations:
1. Main API endpoints susceptible to CSRF because they rely on an anti-CSRF token but are accessible from any authenticated subdomain via ambient authority (`sid` cookie, `SameSite=None`, `Secure`).
2. Permissive Cross-Origin Resource Sharing (CORS) policy allowing requests from *any* subdomain of `redacted.com` to the sensitive API.
3. An out-of-scope subdomain exhibiting an insecure `window.postMessage` handler lacking adequate origin validation.
4. A JSONP endpoint reflecting user-controlled data, leading to controllable script execution.
5. Use of `X-Frame-Options: SAMEORIGIN`, which was bypassed by opening the vulnerable page in a pop-up window.
## Vulnerability Description
The core issue is a **bug chain** that leverages several configuration weaknesses and coding errors across different application components (in-scope API, out-of-scope subdomain, and exposed endpoints) to achieve a high-impact Cross-Site Request Forgery (CSRF) against the main, authenticated API.
1. **CORS Misconfiguration:** The main API endpoint allows requests from any subdomain of `redacted.com` if the authenticated `sid` cookie is present. This allows an attacker who controls an out-of-scope subdomain to potentially steal the required CSRF token.
2. **Insecure `postMessage` Sink (Out-of-Scope):** An accessible function on an out-of-scope subdomain allowed arbitrary function calls in the `window` object via an unvalidated `postMessage` listener.
3. **Arbitrary Function Execution:** The attacker identified `APP.util.setCookie()` as a callable function, demonstrating control over cookie settings, including cross-domain cookies.
4. **Malicious JSONP Endpoint:** A separate JSONP endpoint was found to be vulnerable to reflected XSS when data from the `postMessage` sink was routed to it. Crucially, this allowed loading arbitrary JavaScript from an external source specified by the user.
The combination of these flaws enabled an attacker to execute arbitrary JavaScript in the context of the vulnerable subdomain, which could then be leveraged to interact with the main API.
## Exploitation
- Status: PoC available. The attacker successfully chained these vulnerabilities, implying a proof-of-concept was developed.
- Complexity: Medium to High. While individual components had low complexity issues (e.g., missing origin check), chaining them, including overcoming `X-Frame-Options` via a pop-up window technique, required significant effort.
- Attack Vector: Network (via cross-origin communication).
The full attack flow was:
1. Attacker crafts a page that opens the vulnerable subdomain in a pop-up window (bypassing X-Frame-Options).
2. Attacker uses `postMessage` (which lacks an origin check) on the vulnerable subdomain to trigger execution via the JSONP endpoint.
3. The executed payload requests the CSRF token from the in-scope API (using the permissive CORS policy).
4. The payload then uses the stolen CSRF token and the ambient `sid` cookie to perform authenticated, unauthorized API calls on behalf of the victim (CSRF).
## Impact
- Confidentiality: Low (Sensitive data can be read, e.g., API profile information).
- Integrity: High (Allows modification of user data via authenticated API calls).
- Availability: None (No impact on service availability identified).
## Remediation
### Patches
- No specific patch versions are mentioned as the target organization is redacted. Recommended fixes involve:
1. Correcting the CORS policy to only allow known, necessary origins, not all subdomains.
2. Implementing strict origin validation on all `window.postMessage` listeners.
3. Removing or securely configuring the JSONP endpoint to prevent data reflection/arbitrary script loading.
4. Reviewing the use of `SameSite=None` for sensitive session cookies or implementing strong alternative CSRF protections.
### Workarounds
- Restricting the `sid` cookie to `SameSite=Lax` or `Strict` (relying on native browser protection against cross-site context).
- Temporarily disabling the accessible subdomain if remediation is not immediately possible.
- Setting `X-Frame-Options: DENY` or Content Security Policy (CSP) frame-ancestors directive to prevent framing/pop-up abuse, though the pop-up technique was a workaround for X-Frame-Options itself.
## Detection
- Indicators of Compromise: Network traffic originating from suspicious out-of-scope subdomains attempting to send authenticated requests to the in-scope API endpoints using CSRF tokens. Logs showing unexpected `postMessage` events directing to code that interacts with sensitive infrastructure.
- Detection methods and tools: Web Application Firewalls (WAFs) or security monitoring tools should alert on requests missing expected CSRF tokens if they appear to initiate from unexpected origins granted by the permissive CORS policy. Monitoring for the execution of functions like `APP.util.setCookie` initiated remotely.
## References
- Vendor Advisories: None available (Private disclosure).
- Relevant links - defanged: `hXXps://jub0bs.com/posts/2023-05-05-smorgasbord-of-a-bug-chain/`