Forgetting or misusing the Cache-Control header may negatively impact the security of your website and your users' privacy.
By default, resources are always allowed to be cached by any type of cache.
Not using or misusing the Cache-Control
header might negatively impact the
security of your website and your users' privacy.
For personalized responses you want to keep private, we recommend you either:
- Prevent intermediaries from caching the resource. Set
Cache-Control: private
. - Set an appropriate secondary cache
key.
If the response varies due to cookies—which can happen when the
cookie stores credentials—set
Vary: Cookie
.
Read on to learn why this matters and discover:
- Security and privacy problems you might be unaware of
- Different types of HTTP caches and common misconceptions
- Recommended actions for high-value websites
Cache-related security and privacy risks
Leaky resources from Spectre vulnerabilities
The Spectre
vulnerability
allows a page to read an OS process's memory. This means an attacker can
gain unauthorized access to cross-origin data. As a consequence, modern web
browsers have restricted usage of some of their features—such as
SharedArrayBuffer
or high resolution timer—to
pages with cross-origin
isolation.
Modern web browsers enforce Cross-Origin Embedder Policy (COEP). This ensures cross-origin resources are either:
- Public resources, requested without cookies
- Resources explicitly allowed to be shared cross-origin, via CORS or the CORP header
The COEP setup doesn't prevent an attacker from exploiting Spectre. However, it
ensures cross-origin resources are not valuable to the attacker (when loaded
by the browser as public resource) or allowed to be shared with the attacker (when shared with
CORP: cross-origin
).
How does HTTP caching affect Spectre?
If the Cache-Control
header isn't properly set, an attacker could execute an
attack. For example:
- The credentialed resource is cached.
- The attacker loads a cross-origin isolated page.
- The attacker requests the resource again.
COEP:credentialless
is set by the browser, so the resource is fetched without cookies. However, a cache may return the credentialled response instead.- The attacker can then read the personalized resource using a Spectre attack.
Although a web browser's HTTP cache doesn't allow this type of attack to happen in practice, additional caches exist outside of the browser's immediate control. This may lead to this attack's success.
Common misconceptions about HTTP caches
1. Resources are cached by the browser only
There are often multiple layers of cache. Some caches are dedicated to a single user, some to multiple users. Some are controlled by the server, some by the user, and some by intermediaries.
- Browser caches. These caches are owned by and dedicated to a single user, implemented in their web browser. They improve performance by avoiding fetching the same response multiple times.
- Local proxy. This might have been installed by the user, but can also be managed by intermediaries: their company, their organization, or their internet provider. Local proxies often cache a single response for multiple users, which constitutes a "public" cache. Local proxies have multiple roles.
- Origin server cache / CDN. This is controlled by the server. The Origin server cache's goal is to reduce the load on the origin server by caching the same response for multiple users. A CDN's goals are similar, but spread across the globe and assigned to the closest set of users to reduce latency.
2. SSL prevents intermediaries from caching HTTPS resources
Many users regularly use locally-configured proxies, whether for access purposes (such as sharing a metered connection), virus inspection, or for data loss prevention (DLP) purposes. The intermediary cache is performing TLS interception.
An intermediary cache is often installed on a company employee's workstations. Web browsers are configured to trust the local proxy's certificates.
Ultimately, some HTTPS resources may be cached by these local proxies.
How HTTP cache works
- Resources are implicitly allowed to be cached by default.
- The primary cache key consists of the URL and the method. (URL, method)
- The secondary cache
key is
the headers included in the
Vary
header.Vary: Cookie
indicates the response depends on theCookie
. - The
Cache-Control
header gives more fine grained control.
Take these recommended actions for your website
Developers of high-value websites, which include websites with high traffic and websites which interact with personal identifying information, should act now to improve security.
The greatest risk occurs when access to a resource varies depending on cookies. An intermediary cache may return a response that was requested with cookies for a request that wasn't if no preventative action was taken.
We recommend you take one of the following steps:
- Prevent intermediaries from caching the resource. Set
Cache-Control: private
. - Set an appropriate secondary cache
key.
If the response varies due to cookies—which can happen when the
cookie stores credentials—set
Vary: Cookie
.
In particular, change the default behavior: always define Cache-Control
or
Vary
.
Additional considerations
There are other, similar types of attacks using the HTTP cache, but those rely on a different mechanism than cross-origin-isolation. For instance, Jake Archibald describes some attacks in How to win at CORS.
These attacks are mitigated by some web browsers which split their HTTP cache depending on whether the resource response was requested with credentials or not. As of 2022, Firefox does split the cache, while Chrome and Safari don't. Chrome may split the cache in the future. Note that these attacks are different and complementary to splitting it per the top-level origin.
Even if this problem can be mitigated for web browsers, the problem will remain in local proxy caches. Therefore, we still suggest you follow the recommendations above.
Header photo by Ben Pattinson on Unsplash.