_Firefox versions before 123 have a tricky cache flaw that let hackers “poison” pages you visit by exploiting how the browser dealt with caching for both navigation and fetch(). Here’s how it worked, why headers matter, and what a real-world attack could look like—breaking it down with clear explanations, code snippets, official links, and hands-on exploit details._

What is CVE-2024-1554?

CVE-2024-1554 is a vulnerability in Firefox (prior to version 123) stemming from the browser’s caching implementation. Normally, the browser stores fetched resources so they don’t need to be re-downloaded. Cache “keys” are used to ensure only identical requests get the same cached response.

The bug: With fetch() requests, Firefox didn’t include all relevant headers as part of the cache key. fetch() can use custom headers, but these were missing from the cache’s lookup logic. So, a fetch with a unique header could store a response in cache, and then the same URL (without the extra headers) would retrieve that cached response when a user navigated to the page—dangerously mixing up resource contexts.

Why Is This Dangerous?

If a hacker could “prime” the cache via fetch() with a malicious response, your browser might load their content the next time you visited the page—even if you used navigation, not fetch()—leading to:

Problematic Caching Flow

// Attacker running JS on a page at https://example.com
fetch('https://target.com/page';, {
  headers: {
    'X-Cache-Attack': '1' // Custom header
  }
}).then(r => r.text()).then(data => {
  // "data" could be any malicious HTML or JS
});

What went wrong:
The response from this fetch (with header X-Cache-Attack: 1) was stored in the browser cache, under the URL https://target.com/page.
*But the custom header wasn’t included in the cache key!* If the victim later navigated their browser to https://target.com/page, Firefox would re-use the same cached response—even though the original request lacked the custom header.

Normal Expected Operation

Normally, caches treat requests with different headers as different resources.

Example

GET /page             => Should be cached as [key: url + headers]
GET /page + custom header => Should be cached separately!

With the bug, both would map to the same cache entry.

Step-by-step

1. Victim visits attacker’s page — The attacker has a site (malicious.com) that uses JavaScript to run a fetch() against a legitimate target like bank.com.
2. Attacker primes the cache — The fetch() request includes a custom header and gets a malicious (maybe attacker-hosted) response, using CORS or caching misconfigurations on the target server.
3. Browser stores the response — The response is cached for bank.com/page.
4. Victim later visits bank.com/page directly by clicking a bookmark.

Sample Code for Cache Priming

// This code runs when the victim visits attacker.com
fetch('https://bank.com/login';, {
  headers: {
    'X-Attack-Header': 'IAmEvil' // Just as an example, any custom header
  }
})
.then(res => res.text())
.then(html => {
  console.log('Primed cache with:', html);
});

If the server responds with something cacheable (maybe because of a weak CORS setting or accidental cache headers), the user’s browser stores the “bad” response. When they later browse to https://bank.com/login, Firefox loads the cached fake page—potentially even bypassing the real login form!

How Was It Fixed?

Bugzilla #1879639 shows the official bug report. In version 123, Firefox’s cache handling was updated to include custom headers from fetch() requests in the cache key. Now, a fetch with extra headers and a navigation without them will not hit the same cached response.

Key References

- CVE-2024-1554 NVD Entry
- Mozilla Security Advisory 2024-10
- Bugzilla 1879639

Web developers:

- Avoid exposing sensitive resources or responses to cross-origin fetch() unless absolutely necessary.
- Set cache control headers (e.g., Cache-Control: no-store) on sensitive pages like logins, dashboards, or pages with personal info.

In Summary

CVE-2024-1554 proves how subtle browser security bugs—especially those involving headers and caching—can have significant real-world impact. If you’re running Firefox < 123, you’re at risk of cache poisoning and should immediately update your browser. Developers should double-check their cache and CORS headers to minimize exposure to such attacks.

Stay safe, keep your software updated, and pay close attention to how browsers handle your web data!

Timeline

Published on: 02/20/2024 14:15:08 UTC
Last modified on: 08/20/2024 20:35:08 UTC