<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://web.dev/</id>
  <title>Arthur Sonzogni on web.dev</title>
  <updated>2026-04-15T23:21:06Z</updated>
  <author>
    <name>Arthur Sonzogni</name>
  </author>
  <link href="https://web.dev/authors/arthursonzogni/feed.xml" rel="self"/>
  <link href="https://web.dev/"/>
  <icon>https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/McVMXjWzmTFo66lqFLms.jpg?auto=format</icon>
  <logo>https://web.dev/images/shared/rss-banner.png</logo>
  <subtitle>Software Engineer at Google</subtitle>
  
  
  <entry>
    <title>Improve security and privacy by updating HTTP Cache</title>
    <link href="https://web.dev/http-cache-security/"/>
    <updated>2022-02-07T00:00:00Z</updated>
    <id>https://web.dev/http-cache-security/</id>
    <content type="html" mode="escaped">&lt;p&gt;By default, resources are always allowed to be cached by any type of cache.
Not using or misusing the &lt;code&gt;Cache-Control&lt;/code&gt; header might negatively impact the
security of your website and your users&#39; privacy.&lt;/p&gt;
&lt;p&gt;For personalized responses you want to keep private, we recommend you either:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prevent intermediaries from caching the resource. Set
&lt;code&gt;Cache-Control: private&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set an appropriate &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc7234#section-4.1&quot; rel=&quot;noopener&quot;&gt;secondary cache
key&lt;/a&gt;.
If the response varies due to cookies—which can happen when the
cookie stores credentials—set &lt;code&gt;Vary: Cookie&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read on to learn why this matters and discover:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Security and privacy problems you might be unaware of&lt;/li&gt;
&lt;li&gt;Different types of HTTP caches and common misconceptions&lt;/li&gt;
&lt;li&gt;Recommended actions for high-value websites&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;cache-related-security-and-privacy-risks&quot;&gt;Cache-related security and privacy risks &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/http-cache-security/#cache-related-security-and-privacy-risks&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;leaky-resources-from-spectre-vulnerabilities&quot;&gt;Leaky resources from Spectre vulnerabilities &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/http-cache-security/#leaky-resources-from-spectre-vulnerabilities&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&quot; rel=&quot;noopener&quot;&gt;Spectre
vulnerability&lt;/a&gt;
allows a page to read an OS process&#39;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
&lt;a href=&quot;https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;SharedArrayBuffer&lt;/code&gt;&lt;/a&gt;
or &lt;a href=&quot;https://developer.chrome.com/blog/cross-origin-isolated-hr-timers/&quot; rel=&quot;noopener&quot;&gt;high resolution timer&lt;/a&gt;—to
pages with &lt;a href=&quot;https://web.dev/cross-origin-isolation-guide/&quot;&gt;cross-origin
isolation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Modern web browsers enforce &lt;a href=&quot;https://developer.chrome.com/blog/coep-credentialless-origin-trial/&quot; rel=&quot;noopener&quot;&gt;Cross-Origin Embedder Policy
(COEP)&lt;/a&gt;. This ensures cross-origin
resources are either:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Public resources, requested without cookies&lt;/li&gt;
&lt;li&gt;Resources explicitly allowed to be shared cross-origin, via CORS or the
&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Cross-Origin_Resource_Policy_(CORP)&quot; rel=&quot;noopener&quot;&gt;CORP&lt;/a&gt;
header&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The COEP setup doesn&#39;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
&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Cross-Origin_Resource_Policy_(CORP)&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;CORP: cross-origin&lt;/code&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;h3 id=&quot;how-does-http-caching-affect-spectre&quot;&gt;How does HTTP caching affect Spectre? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/http-cache-security/#how-does-http-caching-affect-spectre&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If the &lt;code&gt;Cache-Control&lt;/code&gt; header isn&#39;t properly set, an attacker could execute an
attack. For example:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The credentialed resource is cached.&lt;/li&gt;
&lt;li&gt;The attacker loads a cross-origin isolated page.&lt;/li&gt;
&lt;li&gt;The attacker requests the resource again.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/blog/coep-credentialless-origin-trial/&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;COEP:credentialless&lt;/code&gt; is set by the browser&lt;/a&gt;,
so the resource is fetched without cookies. However, a cache may return
the credentialled response instead.&lt;/li&gt;
&lt;li&gt;The attacker can then read the personalized resource using a Spectre
attack.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Although a web browser&#39;s HTTP cache doesn&#39;t allow this type of attack to
happen in practice, additional caches exist outside of the browser&#39;s immediate
control. This may lead to this attack&#39;s success.&lt;/p&gt;
&lt;h2 id=&quot;common-misconceptions-about-http-caches&quot;&gt;Common misconceptions about HTTP caches &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/http-cache-security/#common-misconceptions-about-http-caches&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;1-resources-are-cached-by-the-browser-only&quot;&gt;1. Resources are cached by the browser only &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/http-cache-security/#1-resources-are-cached-by-the-browser-only&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Browser caches&lt;/strong&gt;. 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.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Local proxy&lt;/strong&gt;. 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 &amp;quot;public&amp;quot; cache. Local proxies have multiple
roles.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Origin server cache / CDN&lt;/strong&gt;. This is controlled by the server. The Origin
server cache&#39;s goal is to reduce the load on the origin server by caching
the same response for multiple users. A CDN&#39;s goals are similar, but spread
across the globe and assigned to the closest set of users to reduce latency.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure data-size=&quot;full&quot;&gt;
  &lt;img alt=&quot;There are often multiple layers of cache between the browser and server.&quot; class=&quot;screenshot&quot; decoding=&quot;async&quot; height=&quot;712&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/VbsHyyQopiec0718rMq2kTE1hke2/8yvhAw0SiJi62V5yIrT3.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;
     There may be various layers of cache between the browser and server. For example, you may encounter a server cache, followed by a CDN and the browser cache. There may also be a local proxy setup between the CDN and browser cache.
  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&quot;2-ssl-prevents-intermediaries-from-caching-https-resources&quot;&gt;2. SSL prevents intermediaries from caching HTTPS resources &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/http-cache-security/#2-ssl-prevents-intermediaries-from-caching-https-resources&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;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 &lt;a href=&quot;https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_interception&quot; rel=&quot;noopener&quot;&gt;TLS
interception&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;An intermediary cache is often installed on a company employee&#39;s workstations.
Web browsers are configured to trust the local proxy&#39;s certificates.&lt;/p&gt;
&lt;p&gt;Ultimately, some HTTPS resources may be cached by these local proxies.&lt;/p&gt;
&lt;h2 id=&quot;how-http-cache-works&quot;&gt;How HTTP cache works &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/http-cache-security/#how-http-cache-works&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Resources are
&lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc7234&quot; rel=&quot;noopener&quot;&gt;implicitly&lt;/a&gt; allowed
to be cached by default.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc7234#section-2&quot; rel=&quot;noopener&quot;&gt;primary cache
key&lt;/a&gt; consists of the
URL and the method. (URL, method)&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc7234#section-4.1&quot; rel=&quot;noopener&quot;&gt;secondary cache
key&lt;/a&gt; is
the headers included in the &lt;code&gt;Vary&lt;/code&gt; header. &lt;code&gt;Vary: Cookie&lt;/code&gt; indicates the
response depends on the &lt;code&gt;Cookie&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Cache-Control&lt;/code&gt; header gives more fine grained control.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;take-these-recommended-actions-for-your-website&quot;&gt;Take these recommended actions for your website &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/http-cache-security/#take-these-recommended-actions-for-your-website&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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&#39;t if no preventative action was taken.&lt;/p&gt;
&lt;p&gt;We recommend you take one of the following steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prevent intermediaries from caching the resource. Set
&lt;code&gt;Cache-Control: private&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set an appropriate &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc7234#section-4.1&quot; rel=&quot;noopener&quot;&gt;secondary cache
key&lt;/a&gt;.
If the response varies due to cookies—which can happen when the
cookie stores credentials—set &lt;code&gt;Vary: Cookie&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In particular, change the default behavior: always define &lt;code&gt;Cache-Control&lt;/code&gt; or
&lt;code&gt;Vary&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;additional-considerations&quot;&gt;Additional considerations &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/http-cache-security/#additional-considerations&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;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 &lt;a href=&quot;https://jakearchibald.com/2021/cors/#conditionally-serving-cors-headers&quot; rel=&quot;noopener&quot;&gt;How to win at
CORS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;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&#39;t.
Chrome  &lt;a href=&quot;https://docs.google.com/document/d/1lvbiy4n-GM5I56Ncw304sgvY5Td32R6KHitjRXvkZ6U/edit#&quot; rel=&quot;noopener&quot;&gt;may split the
cache&lt;/a&gt; in the future. Note that these attacks are different and
complementary to &lt;a href=&quot;https://developer.chrome.com/blog/http-cache-partitioning&quot; rel=&quot;noopener&quot;&gt;splitting it per the top-level
origin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;Header photo by &lt;a href=&quot;https://unsplash.com/@benpattinson&quot; rel=&quot;noopener&quot;&gt;Ben Pattinson&lt;/a&gt; on &lt;a href=&quot;https://unsplash.com/photos/_Wo1Oq38tVU&quot; rel=&quot;noopener&quot;&gt;Unsplash&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</content>
    <author>
      <name>Arthur Sonzogni</name>
    </author>
  </entry>
</feed>
