Full Report
Caching is customized all over the place and many developers don't consider the ramifications of their actions. As a result, if sensitive data can be cached, then an attacker can steal this information. Web Cache Deception relies on two quirks: caching by file extension and relaxed routing. The first one is obvious and common: cache based upon the extension, such as .js or other static files. Secondly, the routing needs to accept requests that are not exactly the expectation, including things with random file endings. For instance, /auth/test.css could still route to /auth. With the combination of these two actions, a new vulnerability is born! If both of these are meant, then we can force specific routes to be cached that are unintended! This can lead to a major information disclosure. In the case of OpenAI, they were using Cloudflare for caching. They will cache all static file types, such as .css and .js. OpenAI's website also had relaxed routing. The route /auth/sesssion/test.css and /auth/session/ would both be accepted by the web server. The route /api/auth/session would return a users account information, including a session token. To exploit this, the Twitter user Nagil used the technique above and added victim.css to the end of it. The full link for the victim to click on is https://chat.openai.com/api/auth/session/victim.css. Once the link was clicked on by the user, the item would be cached! Then, an attacker could go view the request to steal the session information. With the session JWT, they could likely takeover the account. The fix was to not cache this specific endpoint. However, I find this extremely brittle. There are likely other endpoints with sensitive data that could be abused in this way. Overall, interesting finding on a new and hip website.
Analysis Summary
# Vulnerability: Web Cache Deception in ChatGPT
## CVE Details
- **CVE ID**: N/A (Disclosed as a 0-day bug bounty finding; no specific CVE was publicly assigned by OpenAI).
- **CVSS Score**: Estimated 8.3 (High)
- **CWE**: CWE-524: Use of Cache-Control Policy for Sensitive Information
## Affected Systems
- **Products**: OpenAI ChatGPT web interface.
- **Versions**: Production versions live as of March 2023.
- **Configurations**: Environments utilizing Cloudflare (or similar CDNs) with default caching rules for static extensions combined with "relaxed routing" web server configurations.
## Vulnerability Description
The vulnerability is a **Web Cache Deception (WCD)** flaw. It occurs due to a discrepancy between how the origin server and the caching proxy (Cloudflare) interpret the same URL request.
1. **Relaxed Routing**: The web server was configured to ignore trailing path components that did not match a real file. For example, a request to `/[sensitive-endpoint]/test.css` was routed back to `/[sensitive-endpoint]`.
2. **Cache Aggression**: The CDN was configured to cache files based on their extension (e.g., `.css`, `.js`, `.png`).
3. **The Flaw**: When a user was tricked into visiting a URL like `https://chat.openai[.]com/api/auth/session/victim.css`, the origin server returned the user's private session JSON data, but the CDN saw the `.css` extension and cached that private response on its edge servers.
## Exploitation
- **Status**: Exploited in a controlled environment (Bug Bounty disclosure); fixed shortly after discovery.
- **Complexity**: Low (Requires social engineering to induce a click).
- **Attack Vector**: Network (Web).
- **Mechanism**: Attacker sends a crafted link to a logged-in user. Once the user visits the link, the attacker visits the exact same URL to retrieve the cached session data.
## Impact
- **Confidentiality**: High (Exposure of JWTs, session tokens, chat history, and billing info).
- **Integrity**: High (Full account takeover is possible using the stolen session token).
- **Availability**: Low (The primary goal is data theft and account access).
## Remediation
### Patches
- **Vendor Fix**: OpenAI updated the cache-control headers and routing logic for sensitive API endpoints to ensure they are never cached, regardless of the requested file extension.
### Workarounds
- **Header Enforcement**: Explicitly set `Cache-Control: no-store, private` for all authenticated API endpoints.
- **Strict Routing**: Configure web servers to return a 404 error if an unexpected file extension is appended to a dynamic route.
## Detection
- **Indicators of Compromise**: Multiple requests to sensitive API endpoints ending in static file extensions (e.g., `.css`, `.js`, `.jpg`) originating from different IP addresses within a short timeframe.
- **Detection Methods**: Review CDN logs for "Cache Hit" status on endpoints that should strictly serve dynamic, private content.
## References
- Nagli's original disclosure: `https://x[.]com/galnagli/status/1639343866313601024`
- OWASP Web Cache Deception: `https://owasp[.]org/www-community/attacks/Web_Cache_Deception`