Full Report
Many times, websites have subdomains that need to communicate with each other. Because of the Same Origin Policy (SOP), this isn't usually possible. Some technologies allow for this, a formerly popular one being JSON with Padding (JSONP). How does this work? If you have blog.example.com and account.example.com, then the account page would have a JSONP endpoint. This works because of the cookies on the current page that get used. To prevent cross-data leakage, the endpoint verifies that the Referer header is whitelisted. The browser cache works similarly to most things. When a browser gets a GET request response, it checks for caching information in the headers. Notably, Cache-Control, Expires and Last-Modified. Now, put these things together: JSONP endpoint with browser caching. Because the browser caching doesn't consider the Referer header, it will return the response to this request without doing the check! This becomes an authentication issue as a result. The author claims that this issue also happens with Cross-Site-Script-Inclusion. To fix this, just be careful with your Cache-Control headers. I personally hadn't considered browsing caching as a security issue but it is in this case!
Analysis Summary
# Vulnerabilities: SOP Bypass via Browser Cache Partitioning Absence
## CVE Details
- **CVE ID**: N/A (General architectural weakness in browser caching logic)
- **CVSS Score**: Estimated 6.5 (Medium) | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
- **CWE**: CWE-346: Origin Validation Error, CWE-524: Use of Cache-Control Policy (Missing or Incorrect)
## Affected Systems
- **Products**: Any web application utilizing cross-origin data sharing mechanisms.
- **Versions**: Legacy browsers that do not implement "Cache Partitioning" (standard in modern Chrome and Firefox versions post-2020/2021).
- **Configurations**:
- Endpoints using JSONP (JSON with Padding) or XSSI (Cross-Site Script Inclusion).
- Endpoints relying on the `Referer` or `Origin` header for authorization.
- Endpoints that lack explicit `Cache-Control: no-store` or `no-cache` headers.
## Vulnerability Description
This vulnerability stems from a fundamental design flaw in how browsers historically managed caches. The browser cache identifies assets using a single key: the absolute URI. It traditionally did **not** record the origin (the site that requested the asset) or the headers (like `Referer`) used during the initial request.
When a legitimate site (e.g., `blog.example.com`) requests sensitive data from an authenticated endpoint (e.g., `account.example.com`), the browser checks the `Referer` header, confirms it is whitelisted, and returns the data. If that response is cached, a subsequent request to the same URI from a **malicious** site will be served directly from the browser's local cache. Because the browser fulfills the request locally, the server-side `Referer` or `Origin` check is bypassed entirely, allowing the malicious site to read the cached sensitive data.
## Exploitation
- **Status**: PoC available (Theoretical and demonstrated in research).
- **Complexity**: Low (Requires enticing a user to visit a malicious page after they have visited a legitimate one).
- **Attack Vector**: Network (Web-based).
## Impact
- **Confidentiality**: High (Sensitive user data, account details, or PII can be leaked across origins).
- **Integrity**: None (The attack is read-only).
- **Availability**: None.
## Remediation
### Patches
- **Browser Level**: Most modern browsers have moved toward "Partitioned Caching" or "Double-Keyed Caching," where the cache key includes both the requested URI and the top-level origin. Ensure browsers are updated to the latest versions.
### Workarounds
- **Strict Cache Control**: Developers must explicitly disable caching for any endpoint returning sensitive or user-specific data using:
- `Cache-Control: no-store, no-cache, must-revalidate`
- `Pragma: no-cache`
- **Avoid JSONP**: Transition to modern Cross-Origin Resource Sharing (CORS) which offers more granular security controls, though CORS can still be vulnerable if caching is not managed.
- **Vary Header**: Utilize the `Vary: Referer` or `Vary: Origin` header, which instructs the browser to partition the cache based on the value of those headers (though support varies).
## Detection
- **Indicators of Compromise**: Difficult to detect on the server side because the actual exploitation occurs entirely within the victim's browser cache and does not generate a server log.
- **Detection Methods**:
- **Dynamic Scanning**: Use web vulnerability scanners (like Acunetix) to identify sensitive endpoints that lack `no-store` headers.
- **Manual Audit**: Review server response headers for JSONP or AJAX endpoints. If `Cache-Control` is missing or set to `public/private` with a `max-age`, the endpoint is likely vulnerable.
## References
- **Acunetix Blog**: hxxps[://]www[.]acunetix[.]com/blog/web-security-zone/bypassing-sop-using-the-browser-cache/
- **Original Research (Eduardo Vela)**: hxxps[://]sirdarckcat[.]blogspot[.]com/
- **Test Site**: hxxp[://]account[.]dbggl[.]pw/ (May be offline)