<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://web.dev/</id>
  <title>Maud Nalpas on web.dev</title>
  <updated>2026-04-15T23:21:06Z</updated>
  <author>
    <name>Maud Nalpas</name>
  </author>
  <link href="https://web.dev/authors/maudn/feed.xml" rel="self"/>
  <link href="https://web.dev/"/>
  <icon>https://web-dev.imgix.net/image/O2RNUyVSLubjvENAT3e7JSdqSOx1/9ORwve80jFiyYnPvNcWF.jpg?auto=format</icon>
  <logo>https://web.dev/images/shared/rss-banner.png</logo>
  <subtitle>Developer Advocate for Chrome and web</subtitle>
  
  
  <entry>
    <title>Network Error Logging (NEL)</title>
    <link href="https://web.dev/network-error-logging/"/>
    <updated>2022-01-31T00:00:00Z</updated>
    <id>https://web.dev/network-error-logging/</id>
    <content type="html" mode="escaped">&lt;h2 id=&quot;intro&quot;&gt;Introduction &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#intro&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Network Error Logging (NEL) is a mechanism for
collecting &lt;strong&gt;client-side network errors&lt;/strong&gt; from an origin.&lt;/p&gt;
&lt;p&gt;It uses the &lt;code&gt;NEL&lt;/code&gt; HTTP response header to tell the browser to collect network errors, then integrates with the Reporting API to report the errors to a server.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-bad-bg color-state-bad-text&quot;&gt;&lt;p class=&quot;cluster color-state-bad-text&quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Error sign&quot;&gt;   &lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15v-2h2v2h-2zm0-10v6h2V7h-2z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Caution&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; To set up Network Error Logging for your site, you will need to use the &lt;strong&gt;legacy&lt;/strong&gt; Reporting API that relies on the &lt;code&gt;Report-To&lt;/code&gt; header.  This is because the new Reporting API, that relies on the &lt;code&gt;Reporting-Endpoints&lt;/code&gt; header, does &lt;strong&gt;not&lt;/strong&gt; support Network Error Logging. Learn more in &lt;a href=&quot;https://web.dev/reporting-api/#browser-support&quot;&gt;Browser support&lt;/a&gt;.  Instead, a new mechanism for Network Error Logging will be developed in the future. Once that becomes available, switch from the legacy Reporting API to that new mechanism. &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;overview-of-the-legacy-reporting-api&quot;&gt;Overview of the legacy Reporting API &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#overview-of-the-legacy-reporting-api&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;header&quot;&gt;The legacy &lt;code&gt;Report-To&lt;/code&gt; Header &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#header&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To use the legacy Reporting API, you&#39;ll need to set a &lt;code&gt;Report-To&lt;/code&gt; HTTP response header. Its
value is an object which describes an endpoint group for the browser
to report errors to:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;Report-To:&lt;br /&gt;{&lt;br /&gt;    &quot;max_age&quot;: 10886400,&lt;br /&gt;    &quot;endpoints&quot;: [{&lt;br /&gt;    &quot;url&quot;: &quot;https://analytics.provider.com/browser-errors&quot;&lt;br /&gt;    }]&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;If your endpoint URL lives on a different origin than your site, the
endpoint should support CORS preflight requests. (e.g. &lt;code&gt;Access-Control-Allow-Origin: *; Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS; Access-Control-Allow-Headers: Content-Type, Authorization, Content-Length, X-Requested-With&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;In the example, sending this response header with your main page
configures the browser to report browser-generated warnings
to the endpoint &lt;code&gt;https://analytics.provider.com/browser-errors&lt;/code&gt; for &lt;code&gt;max_age&lt;/code&gt; seconds.
It&#39;s important to note that all subsequent HTTP requests made by the page
(for images, scripts, etc.) are ignored. Configuration is setup during
the response of the main page.&lt;/p&gt;
&lt;h3 id=&quot;fields&quot;&gt;Explanation of header fields &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#fields&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Each endpoint configuration contains a &lt;code&gt;group&lt;/code&gt; name, &lt;code&gt;max_age&lt;/code&gt;, and &lt;code&gt;endpoints&lt;/code&gt;
array. You can also choose whether to consider subdomains when reporting
errors by using the &lt;code&gt;include_subdomains&lt;/code&gt; field.&lt;/p&gt;
&lt;div class=&quot;table-wrapper scrollbar&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;group&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Optional. If a &lt;code&gt;group&lt;/code&gt; name is not specified, the endpoint is given a name of &amp;quot;default&amp;quot;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max_age&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;number&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Required&lt;/strong&gt;. A non-negative integer that defines the lifetime of the endpoint in seconds. A value of &amp;quot;0&amp;quot; will cause the endpoint group to be removed from the user agent’s reporting cache.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;endpoints&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Array&amp;lt;Object&amp;gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Required&lt;/strong&gt;. An array of JSON objects that specify the actual URL of your report collector.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;include_subdomains&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;boolean&lt;/td&gt;
&lt;td&gt;Optional. A boolean that enables the endpoint group for all subdomains of the current origin&#39;s host. If omitted or anything other than &amp;quot;true&amp;quot;, the subdomains are not reported to the endpoint.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;p&gt;The &lt;code&gt;group&lt;/code&gt; name is a unique name used to associate a string with
an endpoint. Use this name in other places that integrate
with the Reporting API to refer to a specific endpoint group.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;max-age&lt;/code&gt; field is also required and specifies how
long the browser should use the endpoint and report errors to it.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;endpoints&lt;/code&gt; field is an array to provide failover and load balancing
features. See the section on &lt;a href=&quot;https://web.dev/network-error-logging/#load&quot;&gt;Failover and load balancing&lt;/a&gt;. It&#39;s
important to note that the &lt;strong&gt;browser will select only one endpoint&lt;/strong&gt;, even
if the group lists several collectors in &lt;code&gt;endpoints&lt;/code&gt;. If you want to send a
report to several servers at once, your backend will need to forward the
reports.&lt;/p&gt;
&lt;h3 id=&quot;send-how&quot;&gt;How does the browser send reports? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#send-how&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The browser periodically batches reports and sends them to the reporting
endpoints that you configure.&lt;/p&gt;
&lt;p&gt;To send reports, the browser issues a &lt;code&gt;POST&lt;/code&gt;
request with
&lt;code&gt;Content-Type: application/reports+json&lt;/code&gt; and a body containing the array of
warnings/errors which were captured.&lt;/p&gt;
&lt;h3 id=&quot;send-when&quot;&gt;When does the browser send reports? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#send-when&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Reports are delivered out-of-band from your app&lt;/strong&gt;, meaning the browser
controls when reports are sent to your server(s).&lt;/p&gt;
&lt;p&gt;The browser attempts to
deliver queued reports at the most opportune time. This may be as soon as they&#39;re ready (in order to provide
timely feedback to the developer) but the browser can also delay delivery if it&#39;s
busy processing higher priority work, or if the user is on a slow and/or
congested network at the time.
The browser may also prioritize sending
reports about a particular origin first, if the user is a frequent visitor.&lt;/p&gt;
&lt;p&gt;There&#39;s little to no performance concern
(e.g. network contention with your app) when using the Reporting API. There&#39;s
also no way to control when the browser sends queued reports.&lt;/p&gt;
&lt;h3 id=&quot;multi&quot;&gt;Configuring multiple endpoints &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#multi&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A single response can configure several endpoints at once by sending
multiple &lt;code&gt;Report-To&lt;/code&gt; headers:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Report-To&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;{&lt;br /&gt;             &quot;group&quot;: &quot;default&quot;,&lt;br /&gt;             &quot;max_age&quot;: 10886400,&lt;br /&gt;             &quot;endpoints&quot;: [{&lt;br /&gt;               &quot;url&quot;: &quot;https://example.com/browser-reports&quot;&lt;br /&gt;             }]&lt;br /&gt;           }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Report-To&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;{&lt;br /&gt;             &quot;group&quot;: &quot;network-errors-endpoint&quot;,&lt;br /&gt;             &quot;max_age&quot;: 10886400,&lt;br /&gt;             &quot;endpoints&quot;: [{&lt;br /&gt;               &quot;url&quot;: &quot;https://example.com/network-errors&quot;&lt;br /&gt;             }]&lt;br /&gt;           }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;or by combining them into a single HTTP header:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Report-To&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;{&lt;br /&gt;             &quot;group&quot;: &quot;network-errors-endpoint&quot;,&lt;br /&gt;             &quot;max_age&quot;: 10886400,&lt;br /&gt;             &quot;endpoints&quot;: [{&lt;br /&gt;               &quot;url&quot;: &quot;https://example.com/network-errors&quot;&lt;br /&gt;             }]&lt;br /&gt;           },&lt;br /&gt;           {&lt;br /&gt;             &quot;max_age&quot;: 10886400,&lt;br /&gt;             &quot;endpoints&quot;: [{&lt;br /&gt;               &quot;url&quot;: &quot;https://example.com/browser-errors&quot;&lt;br /&gt;             }]&lt;br /&gt;           }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Once you&#39;ve sent the &lt;code&gt;Report-To&lt;/code&gt; header, the browser caches the endpoints
according to their &lt;code&gt;max_age&lt;/code&gt; values, and sends all of those nasty console
warnings/errors to your URLs.&lt;/p&gt;
&lt;h3 id=&quot;load&quot;&gt;Failover and load balancing &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#load&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Most of the time you&#39;ll be configuring one URL collector per group. However,
since reporting can generate a good deal of traffic, the spec includes failover
and load-balancing features inspired by the DNS
&lt;a href=&quot;https://tools.ietf.org/html/rfc2782#&quot; rel=&quot;noopener&quot;&gt;SRV record&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The browser will do its best to deliver a report to &lt;strong&gt;at most one&lt;/strong&gt; endpoint
in a group. Endpoints can be assigned a &lt;code&gt;weight&lt;/code&gt; to distribute load, with each
endpoint receiving a specified fraction of reporting traffic. Endpoints can
also be assigned a &lt;code&gt;priority&lt;/code&gt; to set up fallback collectors.&lt;/p&gt;
&lt;p&gt;Fallback collectors are only tried when uploads to primary collectors fail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: Create a fallback collector at &lt;code&gt;https://backup.com/reports&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Report-To&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;{&lt;br /&gt;             &quot;group&quot;: &quot;endpoint-1&quot;,&lt;br /&gt;             &quot;max_age&quot;: 10886400,&lt;br /&gt;             &quot;endpoints&quot;: [&lt;br /&gt;               {&quot;url&quot;: &quot;https://example.com/reports&quot;, &quot;priority&quot;: 1},&lt;br /&gt;               {&quot;url&quot;: &quot;https://backup.com/reports&quot;, &quot;priority&quot;: 2}&lt;br /&gt;             ]&lt;br /&gt;           }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h2 id=&quot;setup-nel&quot;&gt;Setting up Network Error Logging &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#setup-nel&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;setup&quot;&gt;Setup &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#setup&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To use NEL, set up the &lt;code&gt;Report-To&lt;/code&gt; header with a
collector that uses a named group:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Report-To&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;{&lt;br /&gt;    ...&lt;br /&gt;  }, {&lt;br /&gt;    &quot;group&quot;: &quot;network-errors&quot;,&lt;br /&gt;    &quot;max_age&quot;: 2592000,&lt;br /&gt;    &quot;endpoints&quot;: [{&lt;br /&gt;      &quot;url&quot;: &quot;https://analytics.provider.com/networkerrors&quot;&lt;br /&gt;    }]&lt;br /&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Next, send the &lt;code&gt;NEL&lt;/code&gt; response header to start collecting errors. Since NEL
is opt-in for an origin, you only need to send the header once. Both &lt;code&gt;NEL&lt;/code&gt; and
&lt;code&gt;Report-To&lt;/code&gt; will apply to future requests to the same origin and will continue
to collect errors according to the &lt;code&gt;max_age&lt;/code&gt; value that was used to set up
the collector.&lt;/p&gt;
&lt;p&gt;The header value should be a JSON object that contains a &lt;code&gt;max_age&lt;/code&gt; and
&lt;code&gt;report_to&lt;/code&gt; field. Use the latter to reference the group name of your
network errors collector:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token request-line&quot;&gt;&lt;span class=&quot;token method property&quot;&gt;GET&lt;/span&gt; &lt;span class=&quot;token request-target url&quot;&gt;/index.html&lt;/span&gt; &lt;span class=&quot;token http-version property&quot;&gt;HTTP/1.1&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;NEL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;{&quot;report_to&quot;: &quot;network-errors&quot;, &quot;max_age&quot;: 2592000}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;aside class=&quot;aside flow bg-state-bad-bg color-state-bad-text&quot;&gt;&lt;p class=&quot;cluster color-state-bad-text&quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Error sign&quot;&gt;   &lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15v-2h2v2h-2zm0-10v6h2V7h-2z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Caution&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; The &lt;code&gt;Report-To&lt;/code&gt; header uses a hyphen. Here, &lt;code&gt;report_to&lt;/code&gt; uses an underscore. &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;sub&quot;&gt;Subresources &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#sub&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;aside class=&quot;aside flow bg-tertiary-box-bg color-tertiary-box-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; role=&quot;img&quot; aria-label=&quot;Lightbulb&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;   &lt;path d=&quot;M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6A4.997 4.997 0 017 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Important&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; NEL works across navigations and subresources fetches. But for subresources, the containing page has no visibility into the NEL reports about cross-origin requests that it makes. &lt;/div&gt;&lt;/aside&gt;
&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: If &lt;code&gt;example.com&lt;/code&gt; loads &lt;code&gt;foobar.com/cat.gif&lt;/code&gt; and that resource fails
to load:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;foobar.com&lt;/code&gt;&#39;s NEL collector is notified&lt;/li&gt;
&lt;li&gt;&lt;code&gt;example.com&lt;/code&gt;&#39;s NEL collector is &lt;strong&gt;not&lt;/strong&gt; notified&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The
rule of thumb is that NEL reproduces server-side logs, just generated on
the client.&lt;/p&gt;
&lt;p&gt;Since &lt;code&gt;example.com&lt;/code&gt; has no visibility into &lt;code&gt;foobar.com&lt;/code&gt;&#39;s server
logs, it also has no visibility into its NEL reports.&lt;/p&gt;
&lt;h3 id=&quot;debug&quot;&gt;Debugging report configurations &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#debug&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you don&#39;t see reports showing up on your server, head over to
&lt;code&gt;chrome://net-export/&lt;/code&gt;. That page is useful for
verifying things are configured correctly and reports are being sent
out properly.&lt;/p&gt;
&lt;h3 id=&quot;reporting-observer&quot;&gt;What about ReportingObserver? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#reporting-observer&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://web.dev/reporting-observer&quot;&gt;&lt;code&gt;ReportingObserver&lt;/code&gt;&lt;/a&gt; is a related, but different reporting mechanism. It&#39;s based on JavaScript calls.
&lt;strong&gt;It&#39;s not suited for network error logging&lt;/strong&gt;, as network errors
can&#39;t be intercepted via JavaScript.&lt;/p&gt;
&lt;h2 id=&quot;example&quot;&gt;Example server &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#example&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Below is an example Node server that uses Express. It shows how to configure reporting for network errors, and creates a dedicated handler to capture the result.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;express&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br /&gt;  express&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;application/json&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;application/reports+json&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;express&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;urlencoded&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// Note: report_to and not report-to for NEL.&lt;/span&gt;&lt;br /&gt;  response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;NEL&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;{&quot;report_to&quot;: &quot;network-errors&quot;, &quot;max_age&quot;: 2592000}&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// The Report-To header tells the browser where to send network errors.&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// The default group (first example below) captures interventions and&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// deprecation reports. Other groups, like the network-error group, are referenced by their &quot;group&quot; name.&lt;/span&gt;&lt;br /&gt;  response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token string&quot;&gt;&#39;Report-To&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;{&lt;br /&gt;    &quot;max_age&quot;: 2592000,&lt;br /&gt;    &quot;endpoints&quot;: [{&lt;br /&gt;      &quot;url&quot;: &quot;https://reporting-observer-api-demo.glitch.me/reports&quot;&lt;br /&gt;    }],&lt;br /&gt;  }, {&lt;br /&gt;    &quot;group&quot;: &quot;network-errors&quot;,&lt;br /&gt;    &quot;max_age&quot;: 2592000,&lt;br /&gt;    &quot;endpoints&quot;: [{&lt;br /&gt;      &quot;url&quot;: &quot;https://reporting-observer-api-demo.glitch.me/network-reports&quot;&lt;br /&gt;    }]&lt;br /&gt;  }&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sendFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;./index.html&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;echoReports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// Record report in server logs or otherwise process results.&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; report &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;report&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/network-reports&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; Network error reports:&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;echoReports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; listener &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Your app is listening on port &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;listener&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h2 id=&quot;further-reading&quot;&gt;Further reading &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/network-error-logging/#further-reading&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/reporting-api&quot;&gt;Monitor your web application with the Reporting API&lt;/a&gt; (main post on the Reporting API)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/reporting-api-migration&quot;&gt;Migration guide from Reporting API v0 to v1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.w3.org/TR/reporting/&quot; rel=&quot;noopener&quot;&gt;Specification: legacy Reporting API (v0)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://w3c.github.io/reporting/&quot; rel=&quot;noopener&quot;&gt;Specification: new Reporting API (v1)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    <author>
      <name>Eric Bidelman</name>
    </author><author>
      <name>Maud Nalpas</name>
    </author>
  </entry>
  
  <entry>
    <title>Security headers quick reference</title>
    <link href="https://web.dev/security-headers/"/>
    <updated>2021-05-18T00:00:00Z</updated>
    <id>https://web.dev/security-headers/</id>
    <content type="html" mode="escaped">&lt;p&gt;This article lists the most important security headers you can use to protect
your website. Use it to understand web-based security features, learn how to
implement them on your website, and as a reference for when you need a reminder.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Security headers recommended for websites that handle sensitive user data:&lt;/dt&gt;
&lt;dd&gt;&lt;a href=&quot;https://web.dev/security-headers/#csp&quot;&gt;Content Security Policy (CSP)&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a href=&quot;https://web.dev/security-headers/#tt&quot;&gt;Trusted Types&lt;/a&gt;&lt;/dd&gt;
&lt;dt&gt;Security headers recommended for all websites:&lt;/dt&gt;
&lt;dd&gt;&lt;a href=&quot;https://web.dev/security-headers/#xcto&quot;&gt;X-Content-Type-Options&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a href=&quot;https://web.dev/security-headers/#xfo&quot;&gt;X-Frame-Options&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a href=&quot;https://web.dev/security-headers/#corp&quot;&gt;Cross-Origin Resource Policy (CORP)&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a href=&quot;https://web.dev/security-headers/#coop&quot;&gt;Cross-Origin Opener Policy (COOP)&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a href=&quot;https://web.dev/security-headers/#hsts&quot;&gt;HTTP Strict Transport Security (HSTS)&lt;/a&gt;&lt;/dd&gt;
&lt;dt&gt;Security headers for websites with advanced capabilities:&lt;/dt&gt;
&lt;dd&gt;&lt;a href=&quot;https://web.dev/security-headers/#cors&quot;&gt;Cross-Origin Resource Sharing (CORS)&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a href=&quot;https://web.dev/security-headers/#coep&quot;&gt;Cross-Origin Embedder Policy (COEP)&lt;/a&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;details&gt;
&lt;summary&gt;
  Known threats on the web
  &lt;p class=&quot;text-base color-core-text gap-top-base&quot;&gt; Before diving into security headers, learn about known threats on the web and why you&#39;d want to use these security headers.&lt;/p&gt;
&lt;/summary&gt;
&lt;p&gt;Before diving into security headers, learn about known threats on the web
and why you&#39;d want to use these security headers.&lt;/p&gt;
&lt;h3 id=&quot;protect-your-site-from-injection-vulnerabilities&quot;&gt;Protect your site from injection vulnerabilities &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#protect-your-site-from-injection-vulnerabilities&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Injection vulnerabilities arise when untrusted data processed by your
application can affect its behavior and, commonly, lead to the execution of
attacker-controlled scripts. The most common vulnerability caused by injection
bugs is &lt;a href=&quot;https://portswigger.net/web-security/cross-site-scripting&quot; rel=&quot;noopener&quot;&gt;cross-site
scripting&lt;/a&gt; (XSS) in
its various forms, including &lt;a href=&quot;https://portswigger.net/web-security/cross-site-scripting/reflected&quot; rel=&quot;noopener&quot;&gt;reflected
XSS&lt;/a&gt;,
&lt;a href=&quot;https://portswigger.net/web-security/cross-site-scripting/stored&quot; rel=&quot;noopener&quot;&gt;stored XSS&lt;/a&gt;,
&lt;a href=&quot;https://portswigger.net/web-security/cross-site-scripting/dom-based&quot; rel=&quot;noopener&quot;&gt;DOM-based
XSS&lt;/a&gt;, and
other variants.&lt;/p&gt;
&lt;p&gt;An XSS vulnerability can typically give an attacker complete access to user data
processed by the application and any other information hosted in the same &lt;a href=&quot;https://web.dev/same-site-same-origin/#origin&quot;&gt;web
origin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Traditional defenses against injections include consistent use of autoescaping
HTML template systems, avoiding the use of &lt;a href=&quot;https://domgo.at/cxss/sinks&quot; rel=&quot;noopener&quot;&gt;dangerous JavaScript
APIs&lt;/a&gt;, and properly processing user data by hosting
file uploads in a separate domain and sanitizing user-controlled HTML.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;a href=&quot;https://web.dev/security-headers/#csp&quot;&gt;Content Security Policy (CSP)&lt;/a&gt; to control which scripts can be
executed by your application to mitigate the risk of injections.&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;https://web.dev/security-headers/#tt&quot;&gt;Trusted Types&lt;/a&gt; to enforce sanitization of data passed into dangerous
JavaScript APIs.&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;https://web.dev/security-headers/#xcto&quot;&gt;X-Content-Type-Options&lt;/a&gt; to prevent the browser from
misinterpreting the MIME types of your website&#39;s resources, which can lead to
script execution.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;isolate-your-site-from-other-websites&quot;&gt;Isolate your site from other websites &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#isolate-your-site-from-other-websites&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The openness of the web allows websites to interact with each other in ways that
can violate an application&#39;s security expectations. This includes unexpectedly
making authenticated requests or embedding data from another application in the
attacker&#39;s document, allowing the attacker to modify or read application data.&lt;/p&gt;
&lt;p&gt;Common vulnerabilities that undermine web isolation include
&lt;a href=&quot;https://portswigger.net/web-security/clickjacking&quot; rel=&quot;noopener&quot;&gt;clickjacking&lt;/a&gt;, &lt;a href=&quot;https://portswigger.net/web-security/csrf&quot; rel=&quot;noopener&quot;&gt;cross-site
request forgery&lt;/a&gt; (CSRF), &lt;a href=&quot;https://www.scip.ch/en/?labs.20160414&quot; rel=&quot;noopener&quot;&gt;cross-site
script inclusion&lt;/a&gt; (XSSI), and various
&lt;a href=&quot;https://xsleaks.dev/&quot; rel=&quot;noopener&quot;&gt;cross-site leaks&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;a href=&quot;https://web.dev/security-headers/#xfo&quot;&gt;X-Frame-Options&lt;/a&gt; to prevent your documents from being embedded by a
malicious website.&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;https://web.dev/security-headers/#corp&quot;&gt;Cross-Origin Resource Policy (CORP)&lt;/a&gt; to prevent your website&#39;s
resources from being included by a cross-origin website.&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;https://web.dev/security-headers/#coop&quot;&gt;Cross-Origin Opener Policy (COOP)&lt;/a&gt; to protect your website&#39;s
windows from interactions by malicious websites.&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;https://web.dev/security-headers/#cors&quot;&gt;Cross-Origin Resource Sharing (CORS)&lt;/a&gt; to control access to your
website&#39;s resources from cross-origin documents.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://www.w3.org/TR/post-spectre-webdev/&quot; rel=&quot;noopener&quot;&gt;Post-Spectre Web
Development&lt;/a&gt; is a great read
if you are interested in these headers.&lt;/p&gt;
&lt;h3 id=&quot;build-a-powerful-website-securely&quot;&gt;Build a powerful website securely &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#build-a-powerful-website-securely&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://ieeexplore.ieee.org/document/8835233&quot; rel=&quot;noopener&quot;&gt;Spectre&lt;/a&gt; puts any data loaded
into the same &lt;a href=&quot;https://web.dev/why-coop-coep/&quot;&gt;browsing context group&lt;/a&gt; potentially readable
despite &lt;a href=&quot;https://web.dev/same-origin-policy/&quot;&gt;same-origin policy&lt;/a&gt;. Browsers restrict features
that may possibly exploit the vulnerability behind a special environment called
&amp;quot;&lt;a href=&quot;https://web.dev/coop-coep/&quot;&gt;cross-origin isolation&lt;/a&gt;&amp;quot;. With cross-origin isolation, you can
use powerful features such as &lt;code&gt;SharedArrayBuffer&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;a href=&quot;https://web.dev/security-headers/#coep&quot;&gt;Cross-Origin Embedder Policy (COEP)&lt;/a&gt; along with &lt;a href=&quot;https://web.dev/security-headers/#coop&quot;&gt;COOP&lt;/a&gt; to
enable cross-origin isolation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;encrypt-traffic-to-your-site&quot;&gt;Encrypt traffic to your site &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#encrypt-traffic-to-your-site&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Encryption issues appear when an application does not fully encrypt data in
transit, allowing eavesdropping attackers to learn about the user&#39;s interactions
with the application.&lt;/p&gt;
&lt;p&gt;Insufficient encryption can arise in the following cases: not using HTTPS,
&lt;a href=&quot;https://web.dev/what-is-mixed-content/&quot;&gt;mixed content&lt;/a&gt;, setting cookies without the &lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Cookies#restrict_access_to_cookies&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;Secure&lt;/code&gt;
attribute&lt;/a&gt;
(or &lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Cookies#Cookie_prefixes&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;__Secure&lt;/code&gt;
prefix&lt;/a&gt;),
or &lt;a href=&quot;https://blog.detectify.com/2018/04/26/cors-misconfigurations-explained/&quot; rel=&quot;noopener&quot;&gt;lax CORS validation
logic&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;a href=&quot;https://web.dev/security-headers/#hsts&quot;&gt;HTTP Strict Transport Security (HSTS)&lt;/a&gt; to consisitently serve your
contents through HTTPS.&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;h2 id=&quot;csp&quot;&gt;Content Security Policy (CSP) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#csp&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.google.com/about/appsecurity/learning/xss/&quot; rel=&quot;noopener&quot;&gt;Cross-Site Scripting
(XSS)&lt;/a&gt; is an attack
where a vulnerability on a website allows a malicious script to be injected and
executed.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Content-Security-Policy&lt;/code&gt; provides an added layer to mitigate XSS attacks by
restricting which scripts can be executed by the page.&lt;/p&gt;
&lt;p&gt;It&#39;s recommended that you enable strict CSP using one of the following approaches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you render your HTML pages on the server, use &lt;strong&gt;a nonce-based strict CSP&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If your HTML has to be served statically or cached, for example if it&#39;s a
single-page application, use &lt;strong&gt;a hash-based strict CSP&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;label&quot;&gt;Example usage: A nonce-based CSP&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;Content-Security-Policy:&lt;br /&gt;  script-src &#39;nonce-{RANDOM1}&#39; &#39;strict-dynamic&#39; https: &#39;unsafe-inline&#39;;&lt;br /&gt;  object-src &#39;none&#39;;&lt;br /&gt;  base-uri &#39;none&#39;;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;details&gt;
&lt;summary&gt;
  How to use CSP
&lt;/summary&gt;
&lt;h3 id=&quot;recommended-usages&quot;&gt;Recommended usages &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#recommended-usages&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt;  A CSP can be an &lt;em&gt;extra&lt;/em&gt; protection against XSS attacks; you should still make sure to escape (and sanitize) user input.  &lt;/div&gt;&lt;/aside&gt;
&lt;h4 id=&quot;nonce-based-csp&quot;&gt;1. Use a nonce-based strict CSP &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#nonce-based-csp&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;If you render your HTML pages on the server, use &lt;strong&gt;a nonce-based strict CSP&lt;/strong&gt;.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-bad-bg color-state-bad-text&quot;&gt;&lt;p class=&quot;cluster color-state-bad-text&quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Error sign&quot;&gt;   &lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15v-2h2v2h-2zm0-10v6h2V7h-2z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Caution&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt;  A nonce is a random number used only once. A nonce-based CSP is only secure if you can generate a different nonce for each response. If you can&#39;t do this, use &lt;a href=&quot;https://web.dev/security-headers/#hash-based-csp&quot;&gt;a hash-based CSP&lt;/a&gt; instead.  &lt;/div&gt;&lt;/aside&gt;
&lt;p&gt;Generate a new script nonce value for every request on the server side and set
the following header:&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;server configuration file&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;Content-Security-Policy:&lt;br /&gt;  script-src &#39;nonce-{RANDOM1}&#39; &#39;strict-dynamic&#39; https: &#39;unsafe-inline&#39;;&lt;br /&gt;  object-src &#39;none&#39;;&lt;br /&gt;  base-uri &#39;none&#39;;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;In HTML, in order to load the scripts, set the &lt;code&gt;nonce&lt;/code&gt; attribute of all
&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags to the same &lt;code&gt;{RANDOM1}&lt;/code&gt; string.&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;index.html&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;{RANDOM1}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://example.com/script1.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;{RANDOM1}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// Inline scripts can be used with the `nonce` attribute.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;&lt;a href=&quot;https://photos.google.com/&quot; rel=&quot;noopener&quot;&gt;Google Photos&lt;/a&gt; is a good nonce-based strict CSP
example. Use DevTools to see how it&#39;s used.&lt;/p&gt;
&lt;h4 id=&quot;hash-based-csp&quot;&gt;2. Use a hash-based strict CSP &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#hash-based-csp&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;If your HTML has to be served statically or cached, for example if you&#39;re
building a single-page application, use &lt;strong&gt;a hash-based strict CSP&lt;/strong&gt;.&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;server configuration file&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;Content-Security-Policy:&lt;br /&gt;  script-src &#39;sha256-{HASH1}&#39; &#39;sha256-{HASH2}&#39; &#39;strict-dynamic&#39; https: &#39;unsafe-inline&#39;;&lt;br /&gt;  object-src &#39;none&#39;;&lt;br /&gt;  base-uri &#39;none&#39;;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;In HTML, you&#39;ll need to inline your scripts in order to apply a hash-based
policy, because &lt;a href=&quot;https://wpt.fyi/results/content-security-policy/script-src/script-src-sri_hash.sub.html?label=master&amp;amp;label=experimental&amp;amp;aligned&quot; rel=&quot;noopener&quot;&gt;most browsers don&#39;t support hashing external
scripts&lt;/a&gt;.&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;index.html&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;&lt;br /&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;// your script1, inlined&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;&lt;br /&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;// your script2, inlined&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;To load external scripts, read &amp;quot;Load sourced scripts dynamically&amp;quot; under
&lt;a href=&quot;https://web.dev/strict-csp/#hash-based-csp&quot;&gt;Option B: Hash-based CSP Response Header&lt;/a&gt; section.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://csp-evaluator.withgoogle.com/&quot; rel=&quot;noopener&quot;&gt;CSP Evaluator&lt;/a&gt; is a good tool to
evaluate your CSP, but at the same time a good nonce-based strict CSP example.
Use DevTools to see how it&#39;s used.&lt;/p&gt;
&lt;h3 id=&quot;supported-browsers&quot;&gt;Supported browsers &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#supported-browsers&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome, Not supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;no&quot; title=&quot;Not supported&quot; aria-label=&quot;Not supported&quot;&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;
&lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
&lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
&lt;span class=&quot;visually-hidden&quot;&gt;Firefox, Not supported&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;no&quot; title=&quot;Not supported&quot; aria-label=&quot;Not supported&quot;&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;
&lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
&lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
&lt;span class=&quot;visually-hidden&quot;&gt;Edge, Not supported&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;no&quot; title=&quot;Not supported&quot; aria-label=&quot;Not supported&quot;&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;
&lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
&lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
&lt;span class=&quot;visually-hidden&quot;&gt;Safari, Not supported&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;no&quot; title=&quot;Not supported&quot; aria-label=&quot;Not supported&quot;&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;
&lt;/li&gt;&lt;p&gt;&lt;/p&gt;
  &lt;/ul&gt;
&lt;/div&gt;
&lt;aside class=&quot;aside flow bg-tertiary-box-bg color-tertiary-box-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; role=&quot;img&quot; aria-label=&quot;Lightbulb&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;   &lt;path d=&quot;M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6A4.997 4.997 0 017 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Gotchas&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt;  * &lt;code&gt;https:&lt;/code&gt; is a fallback for Safari and &lt;code&gt;unsafe-inline&lt;/code&gt; is a fallback for very old browser versions. &lt;code&gt;https:&lt;/code&gt; and &lt;code&gt;unsafe-inline&lt;/code&gt; don&#39;t make your policy less safe because they will be ignored by browsers who support &lt;code&gt;strict-dynamic&lt;/code&gt;. Read more in &lt;a href=&quot;https://web.dev/strict-csp/#step-4-add-fallbacks-to-support-safari-and-older-browsers&quot;&gt;Add fallbacks to support Safari and older browsers&lt;/a&gt;. * Safari does &lt;em&gt;not&lt;/em&gt; support &lt;code&gt;strict-dynamic&lt;/code&gt; yet. But a strict CSP like in the examples above is safer than an allowlist CSP (and much safer than no CSP at all) for all of your users. Even in Safari, a strict CSP protects your site from some types of XSS attacks, because the presence of the CSP disallows certain unsafe patterns.  &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;other-things-to-note-about-csp&quot;&gt;Other things to note about CSP &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#other-things-to-note-about-csp&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;frame-ancestors&lt;/code&gt;&lt;/a&gt;
directive protects your site from clickjacking—a risk that arises if you allow
untrusted sites to embed yours. If you prefer simpler solution, you can use
&lt;a href=&quot;https://web.dev/security-headers/#xfo&quot;&gt;&lt;code&gt;X-Frame-Options&lt;/code&gt;&lt;/a&gt; to block being loaded, but &lt;code&gt;frame-ancestors&lt;/code&gt; gives
you an advanced configuration to only allow specific origins as embedders.&lt;/li&gt;
&lt;li&gt;You may have used &lt;a href=&quot;https://web.dev/fixing-mixed-content/#content-security-policy&quot;&gt;a CSP to ensure that all of your site&#39;s resources are
loaded over HTTPS&lt;/a&gt;. This has
become less relevant: nowadays, most browsers block
&lt;a href=&quot;https://web.dev/what-is-mixed-content/&quot;&gt;mixed-content&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;You can also set a CSP in &lt;a href=&quot;https://web.dev/strict-csp/#step-2-set-a-strict-csp-and-prepare-your-scripts&quot;&gt;report-only
mode&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If you can&#39;t set a CSP as a header server-side, you can also set it as a meta
tag. Note that you can&#39;t use &lt;strong&gt;report-only&lt;/strong&gt; mode for meta tags (though
&lt;a href=&quot;https://github.com/w3c/webappsec-csp/issues/277&quot; rel=&quot;noopener&quot;&gt;this may change&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;learn-more&quot;&gt;Learn more &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#learn-more&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/strict-csp&quot;&gt;Mitigate XSS with a Strict Content Security Policy (CSP)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html&quot; rel=&quot;noopener&quot;&gt;Content Security Policy Cheat
Sheet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;h2 id=&quot;tt&quot;&gt;Trusted Types &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#tt&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://portswigger.net/web-security/cross-site-scripting/dom-based&quot; rel=&quot;noopener&quot;&gt;DOM-based
XSS&lt;/a&gt; is an
attack where a malicious data is passed into a sink that supports dynamic code
execution such as &lt;code&gt;eval()&lt;/code&gt; or &lt;code&gt;.innerHTML&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Trusted Types provide the tools to write, security review, and maintain
applications free of DOM XSS. They can be enabled via &lt;a href=&quot;https://web.dev/security-headers/#csp&quot;&gt;CSP&lt;/a&gt; and make
JavaScript code secure by default by limiting dangerous web APIs to only accept
a special object—a Trusted Type.&lt;/p&gt;
&lt;p&gt;To create these objects you can define security policies in which you can ensure
that security rules (such as escaping or sanitization) are consistently applied
before the data is written to the DOM. These policies are then the only places
in code that could potentially introduce DOM XSS.&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;Example usages&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Content-Security-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value csp languages-csp&quot;&gt;require-trusted-types-for &#39;script&#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Feature detection&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;trustedTypes &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; trustedTypes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;createPolicy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// Name and create a policy&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; policy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; trustedTypes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;escapePolicy&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function-variable function&quot;&gt;createHTML&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; str&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&lt;span class=&quot;token escape&quot;&gt;\&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;amp;lt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;amp;gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Assignment of raw strings is blocked by Trusted Types.&lt;/span&gt;&lt;br /&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;innerHTML &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;some string&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// This throws an exception.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// Assignment of Trusted Types is accepted safely.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; escaped &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; policy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createHTML&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;img src=x onerror=alert(1)&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;innerHTML &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; escaped&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// &#39;&amp;amp;lt;img src=x onerror=alert(1)&amp;amp;gt;&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;details&gt;
&lt;summary&gt;
  How to use Trusted Types
&lt;/summary&gt;
&lt;h3 id=&quot;recommended-usages-2&quot;&gt;Recommended usages &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#recommended-usages-2&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Enforce Trusted Types for dangerous DOM sinks&lt;/p&gt;
 &lt;p class=&quot;label&quot;&gt;CSP and Trusted Types header:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Content-Security-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value csp languages-csp&quot;&gt;require-trusted-types-for &#39;script&#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Currently &lt;code&gt;&#39;script&#39;&lt;/code&gt; is the only acceptable value for
&lt;code&gt;require-trusted-types-for&lt;/code&gt; directive.&lt;/p&gt;
&lt;p&gt;Of course, you can combine Trusted Types with other CSP directives:&lt;/p&gt;
 &lt;p class=&quot;label&quot;&gt; Merging a nonce-based CSP from above with Trusted Types: &lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;Content-Security-Policy:&lt;br /&gt;  script-src &#39;nonce-{RANDOM1}&#39; &#39;strict-dynamic&#39; https: &#39;unsafe-inline&#39;;&lt;br /&gt;  object-src &#39;none&#39;;&lt;br /&gt;  base-uri &#39;none&#39;;&lt;br /&gt;  require-trusted-types-for &#39;script&#39;;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt; &lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt;  You may limit allowed Trusted Types policy names by setting an additional &lt;code&gt;trusted-types&lt;/code&gt; directive (for example, &lt;code&gt;trusted-types myPolicy&lt;/code&gt;). However, this is not a requirement.  &lt;/div&gt;&lt;/aside&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Define a policy&lt;/p&gt;
 &lt;p class=&quot;label&quot;&gt;Policy:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Feature detection&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;trustedTypes &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; trustedTypes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;createPolicy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// Name and create a policy&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; policy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; trustedTypes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;escapePolicy&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function-variable function&quot;&gt;createHTML&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; str&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&lt;span class=&quot;token escape&quot;&gt;\&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;amp;lt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;amp;gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt; &lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt;  You can define policies with arbitrary names unless you limit the names of allowed Trusted Types policies by setting the &lt;code&gt;trusted-types&lt;/code&gt; directive.  &lt;/div&gt;&lt;/aside&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Apply the policy&lt;/p&gt;
 &lt;p class=&quot;label&quot;&gt;Use the policy when writing data to the DOM:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Assignment of raw strings are blocked by Trusted Types.&lt;/span&gt;&lt;br /&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;innerHTML &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;some string&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// This throws an exception.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// Assignment of Trusted Types is accepted safely.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; escaped &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; policy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createHTML&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;img src=x onerror=alert(1)&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;innerHTML &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; escaped&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// &#39;&amp;amp;lt;img src=x onerror=alert(1)&amp;amp;gt;&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;With &lt;code&gt;require-trusted-types-for &#39;script&#39;&lt;/code&gt;, using a trusted type is a
requirement. Using any dangerous DOM API with a string will result in an
error.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;supported-browsers-2&quot;&gt;Supported browsers &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#supported-browsers-2&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome, Not supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;no&quot; title=&quot;Not supported&quot; aria-label=&quot;Not supported&quot;&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;
&lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
&lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
&lt;span class=&quot;visually-hidden&quot;&gt;Firefox, Not supported&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;no&quot; title=&quot;Not supported&quot; aria-label=&quot;Not supported&quot;&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;
&lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
&lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
&lt;span class=&quot;visually-hidden&quot;&gt;Edge, Not supported&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;no&quot; title=&quot;Not supported&quot; aria-label=&quot;Not supported&quot;&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;
&lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
&lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
&lt;span class=&quot;visually-hidden&quot;&gt;Safari, Not supported&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;no&quot; title=&quot;Not supported&quot; aria-label=&quot;Not supported&quot;&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;
&lt;/li&gt;&lt;p&gt;&lt;/p&gt;
  &lt;/ul&gt;
&lt;/div&gt;
&lt;h3 id=&quot;learn-more-2&quot;&gt;Learn more &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#learn-more-2&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/trusted-types/&quot;&gt;Prevent DOM-based cross-site scripting vulnerabilities with Trusted
Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy/require-trusted-types-for&quot; rel=&quot;noopener&quot;&gt;CSP: require-trusted-types-for - HTTP |
MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types&quot; rel=&quot;noopener&quot;&gt;CSP: trusted-types - HTTP |
MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.compass-demo.com/trusted-types/&quot; rel=&quot;noopener&quot;&gt;Trusted Types demo&lt;/a&gt;—open DevTools Inspector and see
what is happening&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;h2 id=&quot;xcto&quot;&gt;X-Content-Type-Options &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#xcto&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When a malicious HTML document is served from your domain (for example, if an
image uploaded to a photo service contains valid HTML markup), some browsers
will treat it as an active document and allow it to execute scripts in the
context of the application, leading to a &lt;a href=&quot;https://www.google.com/about/appsecurity/learning/xss/&quot; rel=&quot;noopener&quot;&gt;cross-site scripting
bug&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;X-Content-Type-Options: nosniff&lt;/code&gt; prevents it by instructing the browser that
the &lt;a href=&quot;https://mimesniff.spec.whatwg.org/#introduction&quot; rel=&quot;noopener&quot;&gt;MIME type&lt;/a&gt; set in the
&lt;code&gt;Content-Type&lt;/code&gt; header for a given response is correct. This header is
recommended for &lt;strong&gt;all of your resources&lt;/strong&gt;.&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;Example usage&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;X-Content-Type-Options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;nosniff&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;details&gt;
&lt;summary&gt;
  How to use X-Content-Type-Options
&lt;/summary&gt;
&lt;h3 id=&quot;recommended-usages-3&quot;&gt;Recommended usages &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#recommended-usages-3&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;X-Content-Type-Options: nosniff&lt;/code&gt; is recommended for all resources served from
your server along with the correct &lt;code&gt;Content-Type&lt;/code&gt; header.&lt;/p&gt;
&lt;img alt=&quot;X-Content-Type-Options: nosniff&quot; decoding=&quot;async&quot; height=&quot;237&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/IWqRWe9R1mOJImmMbLoM.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p class=&quot;label&quot;&gt;Example headers sent with a document HTML&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;X-Content-Type-Options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;nosniff&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Content-Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;text/html; charset=utf-8&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h3 id=&quot;supported-browsers-3&quot;&gt;Supported browsers &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#supported-browsers-3&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 64, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      64
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 50, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      50
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 12, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      12
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 11, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      11
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Content-Type-Options#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;h3 id=&quot;learn-more-3&quot;&gt;Learn more &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#learn-more-3&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Content-Type-Options&quot; rel=&quot;noopener&quot;&gt;X-Content-Type-Options - HTTP MDN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;h2 id=&quot;xfo&quot;&gt;X-Frame-Options &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#xfo&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If a malicious website can embed your site as an iframe, this may allow
attackers to invoke unintended actions by the user with
&lt;a href=&quot;https://portswigger.net/web-security/clickjacking&quot; rel=&quot;noopener&quot;&gt;clickjacking&lt;/a&gt;. Also, in some
cases &lt;a href=&quot;https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&quot; rel=&quot;noopener&quot;&gt;Spectre-type
attacks&lt;/a&gt; give
malicious websites a chance to learn about the contents of an embedded document.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;X-Frame-Options&lt;/code&gt; indicates whether or not a browser should be allowed to render
a page in a &lt;code&gt;&amp;lt;frame&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;embed&amp;gt;&lt;/code&gt;, or &lt;code&gt;&amp;lt;object&amp;gt;&lt;/code&gt;. &lt;strong&gt;All documents&lt;/strong&gt;
are recommended to send this header to indicate whether they allow being
embedded by other documents.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt;  If you need more granular control such as allowing only a specific origin to embed the document, use the &lt;a href=&quot;https://web.dev/security-headers/#csp&quot;&gt;CSP&lt;/a&gt; &lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors&quot;&gt;&lt;code&gt;frame-ancestors&lt;/code&gt;&lt;/a&gt; directive.  &lt;/div&gt;&lt;/aside&gt;
&lt;p class=&quot;label&quot;&gt;Example usage&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;X-Frame-Options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;DENY&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;details&gt;
&lt;summary&gt;
  How to use X-Frame-Options
&lt;/summary&gt;
&lt;h3 id=&quot;recommended-usages-4&quot;&gt;Recommended usages &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#recommended-usages-4&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;All documents that are not designed to be embedded should use &lt;code&gt;X-Frame-Options&lt;/code&gt; header.&lt;/p&gt;
&lt;p&gt;You can try how the following configurations affect loading an iframe on &lt;a href=&quot;https://cross-origin-isolation.glitch.me/&quot; rel=&quot;noopener&quot;&gt;this
demo&lt;/a&gt;. Change the &lt;code&gt;X-Frame-Options&lt;/code&gt;
dropdown menu and click the &lt;strong&gt;Reload the iframe&lt;/strong&gt; button.&lt;/p&gt;
&lt;h4 id=&quot;protects-your-website-from-being-embedded-by-any-other-websites&quot;&gt;Protects your website from being embedded by any other websites &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#protects-your-website-from-being-embedded-by-any-other-websites&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Deny being embedded by any other documents.&lt;/p&gt;
&lt;img alt=&quot;X-Frame-Options: DENY&quot; decoding=&quot;async&quot; height=&quot;237&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2ZM5obgGK38CMcZ75PkH.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;X-Frame-Options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;DENY&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h4 id=&quot;protects-your-website-from-being-embedded-by-any-cross-origin-websites&quot;&gt;Protects your website from being embedded by any cross-origin websites &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#protects-your-website-from-being-embedded-by-any-cross-origin-websites&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Allow being embedded only by same-origin documents.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;X-Frame-Options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;SAMEORIGIN&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;aside class=&quot;aside flow bg-tertiary-box-bg color-tertiary-box-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; role=&quot;img&quot; aria-label=&quot;Lightbulb&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;   &lt;path d=&quot;M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6A4.997 4.997 0 017 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Gotchas&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt;  Documents being embeddable by default means the web developers need to explicitly send &lt;code&gt;DENY&lt;/code&gt; or &lt;code&gt;SAMEORIGIN&lt;/code&gt; to stop being embedded and protect themselves from side-channel attacks. The Chrome team is considering switching to block document embeds by default so that websites will be secure even if they don&#39;t explicitly set the header. In that new world, documents would need to explicitly opt-in to be embedded.  &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;supported-browsers-4&quot;&gt;Supported browsers &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#supported-browsers-4&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 4, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      4
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 4, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      4
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 12, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      12
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 4, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      4
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Frame-Options#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;h3 id=&quot;learn-more-4&quot;&gt;Learn more &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#learn-more-4&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Frame-Options&quot; rel=&quot;noopener&quot;&gt;X-Frame-Options - HTTP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;h2 id=&quot;corp&quot;&gt;Cross-Origin Resource Policy (CORP) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#corp&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;An attacker can embed resources from another origin, for example from your site,
to learn information about them by exploiting web-based &lt;a href=&quot;https://xsleaks.dev/&quot; rel=&quot;noopener&quot;&gt;cross-site
leaks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Cross-Origin-Resource-Policy&lt;/code&gt; mitigates this risk by indicating the set of
websites it can be loaded by. The header takes one of three values:
&lt;code&gt;same-origin&lt;/code&gt;, &lt;code&gt;same-site&lt;/code&gt;, and &lt;code&gt;cross-origin&lt;/code&gt;. &lt;strong&gt;All resources&lt;/strong&gt; are
recommended to send this header to indicate whether they allow being loaded by
other websites.&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;Example usage&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Resource-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;same-origin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;details&gt;
&lt;summary&gt;
  How to use CORP
&lt;/summary&gt;
&lt;h3 id=&quot;recommended-usages-5&quot;&gt;Recommended usages &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#recommended-usages-5&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;It is recommended that &lt;strong&gt;all&lt;/strong&gt; resources are served with one of the following
three headers.&lt;/p&gt;
&lt;p&gt;You can try how the following configurations affect loading resources under a
&lt;a href=&quot;https://web.dev/security-headers/#coep&quot;&gt;&lt;code&gt;Cross-Origin-Embedder-Policy: require-corp&lt;/code&gt; environment&lt;/a&gt; on &lt;a href=&quot;https://cross-origin-isolation.glitch.me/?coep=require-corp&amp;amp;&quot; rel=&quot;noopener&quot;&gt;this
demo&lt;/a&gt;. Change the
&lt;strong&gt;Cross-Origin-Resource-Policy&lt;/strong&gt; dropdown menu and click the &lt;strong&gt;Reload the
iframe&lt;/strong&gt; or &lt;strong&gt;Reload the image&lt;/strong&gt; button to see the effect.&lt;/p&gt;
&lt;h4 id=&quot;allow-resources-to-be-loaded-cross-origin&quot;&gt;Allow resources to be loaded &lt;code&gt;cross-origin&lt;/code&gt; &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#allow-resources-to-be-loaded-cross-origin&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;It&#39;s recommended that CDN-like services apply &lt;code&gt;cross-origin&lt;/code&gt; to resources
(since they are usually loaded by cross-origin pages), unless they are already served
through &lt;a href=&quot;https://web.dev/security-headers/#cors&quot;&gt;CORS&lt;/a&gt; which has a similar effect.&lt;/p&gt;
&lt;img alt=&quot;Cross-Origin-Resource-Policy: cross-origin&quot; decoding=&quot;async&quot; height=&quot;234&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/qP2mspVMC6RazxDjWUrL.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Resource-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;cross-origin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h4 id=&quot;limit-resources-to-be-loaded-from-the-same-origin&quot;&gt;Limit resources to be loaded from the &lt;code&gt;same-origin&lt;/code&gt; &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#limit-resources-to-be-loaded-from-the-same-origin&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;same-origin&lt;/code&gt; should be applied to resources that are intended to be loaded only
by same-origin pages. You should apply this to resources that include sensitive
information about the user, or responses of an API that is intended to be called
only from the same origin.&lt;/p&gt;
&lt;p&gt;Keep in mind that resources with this header can still be loaded directly, for
example by navigating to the URL in a new browser window. Cross-Origin Resource
Policy only protects the resource from being embedded by other websites.&lt;/p&gt;
&lt;img alt=&quot;Cross-Origin-Resource-Policy: same-origin&quot; decoding=&quot;async&quot; height=&quot;238&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/7UzYMWsbKkh89m5ZImvj.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Resource-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;same-origin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h4 id=&quot;limit-resources-to-be-loaded-from-the-same-site&quot;&gt;Limit resources to be loaded from the &lt;code&gt;same-site&lt;/code&gt; &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#limit-resources-to-be-loaded-from-the-same-site&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;same-site&lt;/code&gt; is recommended to be applied to resources that are similar to above
but are intended to be loaded by other subdomains of your site.&lt;/p&gt;
&lt;img alt=&quot;Cross-Origin-Resource-Policy: same-site&quot; decoding=&quot;async&quot; height=&quot;233&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/R9yNRGSJ4xABc560WRJI.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Resource-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;same-site&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt;  To learn more about the difference between same-origin and same-site, check out &lt;a href=&quot;https://web.dev/same-site-same-origin/&quot;&gt;Understanding &amp;quot;same-site&amp;quot; and &amp;quot;same-origin&amp;quot;&lt;/a&gt;.  &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;supported-browsers-5&quot;&gt;Supported browsers &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#supported-browsers-5&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 73, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      73
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 74, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      74
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 79, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      79
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 12, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      12
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;h3 id=&quot;learn-more-5&quot;&gt;Learn more &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#learn-more-5&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://resourcepolicy.fyi/&quot; rel=&quot;noopener&quot;&gt;Consider deploying cross-origin resource policy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/coop-coep/&quot;&gt;Making your website &amp;quot;cross-origin isolated&amp;quot; using COOP and COEP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/why-coop-coep/&quot;&gt;Why you need &amp;quot;cross-origin isolated&amp;quot; for powerful features&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;h2 id=&quot;coop&quot;&gt;Cross-Origin Opener Policy (COOP) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#coop&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;An attacker&#39;s website can open another site in a popup window to learn
information about it by exploiting web-based &lt;a href=&quot;https://xsleaks.dev/&quot; rel=&quot;noopener&quot;&gt;cross-site
leaks&lt;/a&gt;. In some cases, this may also allow the
exploitation of side-channel attacks based on
&lt;a href=&quot;https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&quot; rel=&quot;noopener&quot;&gt;Spectre&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Cross-Origin-Opener-Policy&lt;/code&gt; header provides a way for a document to isolate
itself from cross-origin windows opened through &lt;code&gt;window.open()&lt;/code&gt; or a link with
&lt;code&gt;target=&amp;quot;_blank&amp;quot;&lt;/code&gt; without &lt;code&gt;rel=&amp;quot;noopener&amp;quot;&lt;/code&gt;. As a result, any cross-origin opener
of the document will have no reference to it and will not be able to interact
with it.&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;Example usage&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Opener-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;same-origin-allow-popups&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;details&gt;
&lt;summary&gt;
  How to use COOP
&lt;/summary&gt;
&lt;h3 id=&quot;recommended-usages-6&quot;&gt;Recommended usages &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#recommended-usages-6&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You can try how the following configurations affect communication with a
cross-origin popup window on &lt;a href=&quot;https://cross-origin-isolation.glitch.me/&quot; rel=&quot;noopener&quot;&gt;this demo&lt;/a&gt;.
Change the &lt;strong&gt;Cross-Origin-Opener-Policy&lt;/strong&gt; dropdown menu for both the document
and the popup window, click the &lt;strong&gt;Open a popup&lt;/strong&gt; button then click &lt;strong&gt;Send a
postMessage&lt;/strong&gt; to see if the message is actually delivered.&lt;/p&gt;
&lt;h4 id=&quot;isolate-a-document-from-cross-origin-windows&quot;&gt;Isolate a document from cross-origin windows &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#isolate-a-document-from-cross-origin-windows&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Setting &lt;code&gt;same-origin&lt;/code&gt; puts the document to be isolated from cross-origin
document windows.&lt;/p&gt;
&lt;img alt=&quot;Cross-Origin-Opener-Policy: same-origin&quot; decoding=&quot;async&quot; height=&quot;235&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/mSDG9auD7r5asxGJvJjg.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Opener-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;same-origin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h4 id=&quot;isolate-a-document-from-cross-origin-windows-but-allow-popups&quot;&gt;Isolate a document from cross-origin windows but allow popups &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#isolate-a-document-from-cross-origin-windows-but-allow-popups&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Setting &lt;code&gt;same-origin-allow-popups&lt;/code&gt; allows a document to retain a reference to
its popup windows unless they set COOP with &lt;code&gt;same-origin&lt;/code&gt; or
&lt;code&gt;same-origin-allow-popups&lt;/code&gt;. This means &lt;code&gt;same-origin-allow-popups&lt;/code&gt; can still
protect the document from being referenced when opened as a popup window, but
allow it to communicate with its own popups.&lt;/p&gt;
&lt;img alt=&quot;Cross-Origin-Opener-Policy: same-origin-allow-popups&quot; decoding=&quot;async&quot; height=&quot;233&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/2uJZ0s2VnjxJUcBI2Ol9.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Opener-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;same-origin-allow-popups&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h4 id=&quot;allow-a-document-to-be-referenced-by-cross-origin-windows&quot;&gt;Allow a document to be referenced by cross-origin windows &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#allow-a-document-to-be-referenced-by-cross-origin-windows&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;unsafe-none&lt;/code&gt; is the default value but you can explicitly indicate that this
document can be opened by a cross-origin window and retain mutual access.&lt;/p&gt;
&lt;img alt=&quot;Cross-Origin-Opener-Policy: unsafe-none&quot; decoding=&quot;async&quot; height=&quot;233&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/oSco89ZT3RP7gZzNKDjY.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;aside class=&quot;aside flow bg-tertiary-box-bg color-tertiary-box-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; role=&quot;img&quot; aria-label=&quot;Lightbulb&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;   &lt;path d=&quot;M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6A4.997 4.997 0 017 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Gotchas&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt;  &lt;code&gt;unsafe-none&lt;/code&gt; being the default means the web developers need to send &lt;code&gt;same-origin&lt;/code&gt; or &lt;code&gt;same-origin-allow-popups&lt;/code&gt; explicitly to protect their website from side-channel attacks.  &lt;/div&gt;&lt;/aside&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Opener-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;unsafe-none&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt;  Features such as &lt;code&gt;SharedArrayBuffer&lt;/code&gt; or &lt;code&gt;performance.measureUserAgentSpecificMemory()&lt;/code&gt; are disabled by default. Some browsers allow you to use them in &amp;quot;cross-origin isolated&amp;quot; contexts, which require you to set &lt;a href=&quot;https://web.dev/security-headers/#coop&quot;&gt;COOP&lt;/a&gt; and &lt;a href=&quot;https://web.dev/security-headers/#coep&quot;&gt;COEP&lt;/a&gt; headers.  To learn more, read &lt;a href=&quot;https://web.dev/coop-coep/&quot;&gt;Making your website &amp;quot;cross-origin isolated&amp;quot; using COOP and COEP&lt;/a&gt;.  &lt;/div&gt;&lt;/aside&gt;
&lt;h4 id=&quot;report-patterns-incompatible-with-coop&quot;&gt;Report patterns incompatible with COOP &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#report-patterns-incompatible-with-coop&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;You can receive reports when COOP prevents cross-window interactions with the
Reporting API.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Opener-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;same-origin; report-to=&quot;coop&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;COOP also supports a report-only mode so you can receive reports without
actually blocking communication between cross-origin documents.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Opener-Policy-Report-Only&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;same-origin; report-to=&quot;coop&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h3 id=&quot;supported-browsers-6&quot;&gt;Supported browsers &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#supported-browsers-6&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 83, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      83
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 79, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      79
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 83, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      83
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 15.2, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      15.2
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;h3 id=&quot;learn-more-6&quot;&gt;Learn more &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#learn-more-6&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/why-coop-coep/&quot;&gt;Why you need &amp;quot;cross-origin isolated&amp;quot; for powerful features&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;h2 id=&quot;cors&quot;&gt;Cross-Origin Resource Sharing (CORS) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#cors&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Unlike other items in this article, Cross-Origin Resource Sharing (CORS) is not
a header, but a browser mechanism that requests and permits access to
cross-origin resources.&lt;/p&gt;
&lt;p&gt;By default, browsers enforce &lt;a href=&quot;https://web.dev/same-origin-policy/&quot;&gt;the same-origin policy&lt;/a&gt; to
prevent a web page from accessing cross-origin resources. For example, when a
cross-origin image is loaded, even though it&#39;s displayed on the web page
visually, the JavaScript on the page doesn&#39;t have access to the image&#39;s data.
The resource provider can relax restrictions and allow other websites to read
the resource by opting-in with CORS.&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;Example usage&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;https://example.com&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Access-Control-Allow-Credentials&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;details&gt;
&lt;summary&gt;
  How to use CORS
&lt;/summary&gt;
&lt;p&gt;Before looking into how to configure CORS, it&#39;s helpful to understand the
distinction between request types. Depending on request details, a request will
be classified as a &lt;strong&gt;simple request&lt;/strong&gt; or a &lt;strong&gt;preflighted request&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Criteria for a simple request:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The method is &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;HEAD&lt;/code&gt;, or &lt;code&gt;POST&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The custom headers only include &lt;code&gt;Accept&lt;/code&gt;, &lt;code&gt;Accept-Language&lt;/code&gt;,
&lt;code&gt;Content-Language&lt;/code&gt;, and &lt;code&gt;Content-Type&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Content-Type&lt;/code&gt; is &lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt;,
&lt;code&gt;multipart/form-data&lt;/code&gt;, or &lt;code&gt;text/plain&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Everything else is classified as a preflighted request. For more details,
check out &lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/CORS#simple_requests&quot; rel=&quot;noopener&quot;&gt;Cross-Origin Resource Sharing (CORS) - HTTP |
MDN&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;recommended-usages-7&quot;&gt;Recommended usages &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#recommended-usages-7&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;h4 id=&quot;simple-request&quot;&gt;Simple request &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#simple-request&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;When a request meets the simple request criteria, the browser sends a
cross-origin request with an &lt;code&gt;Origin&lt;/code&gt; header that indicates the requesting
origin.&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;Example request header&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;Get / HTTP/1.1&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Origin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;https://example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p class=&quot;label&quot;&gt;Example response header&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;https://example.com&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Access-Control-Allow-Credentials&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Access-Control-Allow-Origin: https://example.com&lt;/code&gt; indicates that the
&lt;code&gt;https://example.com&lt;/code&gt; can access the contents of the response. Resources meant
to be readable by any site can set this header to &lt;code&gt;*&lt;/code&gt;, in which case the
browser will only require the request to be made &lt;a href=&quot;https://developer.mozilla.org/docs/Web/API/Request/credentials#value&quot; rel=&quot;noopener&quot;&gt;without
credentials&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Access-Control-Allow-Credentials: true&lt;/code&gt; indicates that requests which carry
credentials (cookies) are allowed to load the resource. Otherwise,
authenticated requests will be rejected even if the requesting origin is
present in the &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; header.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can try how the simple request affect loading resources under a
&lt;a href=&quot;https://web.dev/security-headers/#coep&quot;&gt;&lt;code&gt;Cross-Origin-Embedder-Policy: require-corp&lt;/code&gt; environment&lt;/a&gt; on &lt;a href=&quot;https://cross-origin-isolation.glitch.me/?coep=require-corp&amp;amp;&quot; rel=&quot;noopener&quot;&gt;this
demo&lt;/a&gt;. Click the
&lt;strong&gt;Cross-Origin Resource Sharing&lt;/strong&gt; checkbox and click the &lt;strong&gt;Reload the image&lt;/strong&gt;
button to see the effect.&lt;/p&gt;
&lt;h4 id=&quot;preflighted-requests&quot;&gt;Preflighted requests &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#preflighted-requests&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;A preflighted request is preceded with an &lt;code&gt;OPTIONS&lt;/code&gt; request to check if the
subsequent request is allowed to be sent.&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;Example request header&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token request-line&quot;&gt;&lt;span class=&quot;token method property&quot;&gt;OPTIONS&lt;/span&gt; &lt;span class=&quot;token request-target url&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token http-version property&quot;&gt;HTTP/1.1&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Origin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;https://example.com&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Access-Control-Request-Method&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;POST&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Access-Control-Request-Headers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;X-PINGOTHER, Content-Type&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Access-Control-Request-Method: POST&lt;/code&gt; allows the following request to be made
with the  &lt;code&gt;POST&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Access-Control-Request-Headers: X-PINGOTHER, Content-Type&lt;/code&gt; allows the
requester to set the &lt;code&gt;X-PINGOTHER&lt;/code&gt; and &lt;code&gt;Content-Type&lt;/code&gt; HTTP headers in the
subsequent request.&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;label&quot;&gt;Example response headers&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;https://example.com&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Access-Control-Allow-Credentials&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Access-Control-Allow-Methods&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;POST, GET, OPTIONS&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Access-Control-Allow-Headers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;X-PINGOTHER, Content-Type&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Access-Control-Max-Age&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;86400&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Access-Control-Allow-Methods: POST, GET, OPTIONS&lt;/code&gt; indicates that subsequent
requests can be made with the  &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;GET&lt;/code&gt; and &lt;code&gt;OPTIONS&lt;/code&gt; methods.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Access-Control-Allow-Headers: X-PINGOTHER, Content-Type&lt;/code&gt; indicates subsequent
requests can include the &lt;code&gt;X-PINGOTHER&lt;/code&gt; and &lt;code&gt;Content-Type&lt;/code&gt; headers.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Access-Control-Max-Age: 86400&lt;/code&gt;  indicates that the result of the preflighted
request can be cached for 86400 seconds.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;supported-browsers-7&quot;&gt;Supported browsers &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#supported-browsers-7&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 4, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      4
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 3.5, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      3.5
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 12, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      12
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 4, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      4
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Access-Control-Allow-Origin#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;h3 id=&quot;learn-more-7&quot;&gt;Learn more &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#learn-more-7&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/cross-origin-resource-sharing/&quot;&gt;Cross-Origin Resource Sharing (CORS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/CORS&quot; rel=&quot;noopener&quot;&gt;Cross-Origin Resource Sharing (CORS) - HTTP |
MDN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;h2 id=&quot;coep&quot;&gt;Cross-Origin Embedder Policy (COEP) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#coep&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To reduce the ability of &lt;a href=&quot;https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)&quot; rel=&quot;noopener&quot;&gt;Spectre-based
attacks&lt;/a&gt; to
steal cross-origin resources, features such as &lt;code&gt;SharedArrayBuffer&lt;/code&gt; or
&lt;code&gt;performance.measureUserAgentSpecificMemory()&lt;/code&gt; are disabled by default.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Cross-Origin-Embedder-Policy: require-corp&lt;/code&gt; prevents documents and workers from
loading cross-origin resources such as images, scripts, stylesheets, iframes and
others unless these resources explicitly opt into being loaded via &lt;a href=&quot;https://web.dev/security-headers/#cors&quot;&gt;CORS&lt;/a&gt;
or &lt;a href=&quot;https://web.dev/security-headers/#corp&quot;&gt;CORP&lt;/a&gt; headers. COEP can be combined with&lt;code&gt;Cross-Origin-Opener-Policy&lt;/code&gt;
to opt a document into &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;Use &lt;code&gt;Cross-Origin-Embedder-Policy: require-corp&lt;/code&gt; when you want to enable
&lt;a href=&quot;https://web.dev/coop-coep/&quot;&gt;cross-origin isolation&lt;/a&gt; for your document.&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;Example usage&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Embedder-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;require-corp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;details&gt;
&lt;summary&gt;
  How to use COEP
&lt;/summary&gt;
&lt;h3 id=&quot;example-usages&quot;&gt;Example usages &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#example-usages&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;COEP takes a single value of &lt;code&gt;require-corp&lt;/code&gt;. By sending this header, you can
instruct the browser to block loading resources that do not opt-in via
&lt;a href=&quot;https://web.dev/security-headers/#cors&quot;&gt;CORS&lt;/a&gt; or &lt;a href=&quot;https://web.dev/security-headers/#corp&quot;&gt;CORP&lt;/a&gt;.&lt;/p&gt;
&lt;img alt=&quot;How COEP works&quot; decoding=&quot;async&quot; height=&quot;410&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/MAhaVZdShm8tRntWieU4.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;You can try how the following configurations affect loading resources on &lt;a href=&quot;https://cross-origin-isolation.glitch.me/&quot; rel=&quot;noopener&quot;&gt;this
demo&lt;/a&gt;. Change the
&lt;strong&gt;Cross-Origin-Embedder-Policy&lt;/strong&gt; dropdown menu, the
&lt;strong&gt;Cross-Origin-Resource-Policy&lt;/strong&gt; dropdown menu, the &lt;strong&gt;Report Only&lt;/strong&gt; checkbox etc
to see how they affect loading resources. Also, open &lt;a href=&quot;https://reporting-endpoint.glitch.me/&quot; rel=&quot;noopener&quot;&gt;the reporting endpoint
demo&lt;/a&gt; to see if the blocked resources are
reported.&lt;/p&gt;
&lt;h4 id=&quot;enable-cross-origin-isolation&quot;&gt;Enable cross-origin isolation &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#enable-cross-origin-isolation&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Enable &lt;a href=&quot;https://web.dev/coop-coep&quot;&gt;cross-origin isolation&lt;/a&gt; by sending
&lt;code&gt;Cross-Origin-Embedder-Policy: require-corp&lt;/code&gt; along with
&lt;code&gt;Cross-Origin-Opener-Policy: same-origin&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Embedder-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;require-corp&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Opener-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;same-origin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h4 id=&quot;report-resources-incompatible-withn-coep&quot;&gt;Report resources incompatible withn COEP &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#report-resources-incompatible-withn-coep&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;You can receive reports of blocked resources caused by COEP with the Reporting
API.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Embedder-Policy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;require-corp; report-to=&quot;coep&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;COEP also supports report-only mode so you can receive reports without actually
blocking loading resources.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Cross-Origin-Embedder-Policy-Report-Only&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;require-corp; report-to=&quot;coep&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h3 id=&quot;supported-browsers-8&quot;&gt;Supported browsers &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#supported-browsers-8&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 83, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      83
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 79, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      79
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 83, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      83
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 15.2, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      15.2
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;h3 id=&quot;learn-more-8&quot;&gt;Learn more &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#learn-more-8&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/coop-coep/&quot;&gt;Making your website &amp;quot;cross-origin isolated&amp;quot; using COOP and COEP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/why-coop-coep/&quot;&gt;Why you need &amp;quot;cross-origin isolated&amp;quot; for powerful features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/cross-origin-isolation-guide/&quot;&gt;A guide to enable cross-origin isolation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;h2 id=&quot;hsts&quot;&gt;HTTP Strict Transport Security (HSTS) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#hsts&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Communication over a plain HTTP connection is not encrypted, making the
transferred data accessible to network-level eavesdroppers.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Strict-Transport-Security&lt;/code&gt; header informs the browser that it should never load
the site using HTTP and use HTTPS instead. Once it&#39;s set, the browser will use
HTTPS instead of HTTP to access the domain without a redirect for a duration
defined in the header.&lt;/p&gt;
&lt;p class=&quot;label&quot;&gt;Example usage&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Strict-Transport-Security&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value hsts languages-hsts&quot;&gt;max-age=31536000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;details&gt;
&lt;summary&gt;
  How to use HSTS
&lt;/summary&gt;
&lt;h3 id=&quot;recommended-usages-8&quot;&gt;Recommended usages &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#recommended-usages-8&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;All websites that transition from HTTP to HTTPS should respond with a
&lt;code&gt;Strict-Transport-Security&lt;/code&gt; header when a request with HTTP is received.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Strict-Transport-Security&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value hsts languages-hsts&quot;&gt;max-age=31536000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h3 id=&quot;supported-browsers-9&quot;&gt;Supported browsers &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#supported-browsers-9&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 4, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      4
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 4, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      4
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 12, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      12
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 7, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      7
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Strict-Transport-Security#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;h3 id=&quot;learn-more-9&quot;&gt;Learn more &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#learn-more-9&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Strict-Transport-Security&quot; rel=&quot;noopener&quot;&gt;Strict-Transport-Security -
HTTP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further reading &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/security-headers/#further-reading&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.w3.org/TR/post-spectre-webdev/&quot; rel=&quot;noopener&quot;&gt;Post-Spectre Web Development&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    <author>
      <name>Eiji Kitamura</name>
    </author><author>
      <name>Maud Nalpas</name>
    </author><author>
      <name>Artur Janc</name>
    </author>
  </entry>
  
  <entry>
    <title>How to use HTTPS for local development</title>
    <link href="https://web.dev/how-to-use-local-https/"/>
    <updated>2021-01-25T00:00:00Z</updated>
    <id>https://web.dev/how-to-use-local-https/</id>
    <content type="html" mode="escaped">&lt;aside class=&quot;aside flow bg-state-bad-bg color-state-bad-text&quot;&gt;&lt;p class=&quot;cluster color-state-bad-text&quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Error sign&quot;&gt;   &lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15v-2h2v2h-2zm0-10v6h2V7h-2z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Caution&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; Most of the time, &lt;code&gt;http://localhost&lt;/code&gt; does what you need: in browsers, it mostly behaves like HTTPS 🔒. That&#39;s why some APIs that won&#39;t work on a deployed HTTP site, will work on &lt;code&gt;http://localhost&lt;/code&gt;.  What this means is that you need to use HTTPS locally &lt;strong&gt;only in special cases&lt;/strong&gt; (see &lt;a href=&quot;https://web.dev/when-to-use-local-https&quot;&gt;When to use HTTPS for local development&lt;/a&gt;), like custom hostnames or Secure cookies across browsers. Keep reading if that&#39;s you! &lt;/div&gt;&lt;/aside&gt;
&lt;p&gt;&lt;em&gt;In this post, statements about &lt;code&gt;localhost&lt;/code&gt; are valid for &lt;code&gt;127.0.0.1&lt;/code&gt; and &lt;code&gt;[::1]&lt;/code&gt; as well, since they both describe the local computer address, also called &amp;quot;loopback address&amp;quot;. Also, to keep things simple, the port number isn&#39;t specified.&lt;/em&gt;
&lt;em&gt;So when you see &lt;code&gt;http://localhost&lt;/code&gt;, read it as &lt;code&gt;http://localhost:{PORT}&lt;/code&gt; or &lt;code&gt;http://127.0.0.1:{PORT}&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If your production website uses HTTPS, you want your local development site to behave &lt;strong&gt;like an
HTTPS site&lt;/strong&gt; (if your production website doesn&#39;t use HTTPS, &lt;a href=&quot;https://web.dev/why-https-matters/&quot;&gt;make it a priority to switch to HTTPS&lt;/a&gt;).
Most of the time, you can trust &lt;code&gt;http://localhost&lt;/code&gt; to behave &lt;strong&gt;like an HTTPS site&lt;/strong&gt;. But &lt;a href=&quot;https://web.dev/when-to-use-local-https&quot;&gt;in some
cases&lt;/a&gt;, you need to run your site locally with HTTPS. Let&#39;s take a look
at how to do this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;⏩ Are you looking for quick instructions, or have you been here before?
Skip to the &lt;a href=&quot;https://web.dev/how-to-use-local-https/#using-mkcert-cheatsheet&quot;&gt;Cheatsheet&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;running-your-site-locally-with-https-using-mkcert-recommended&quot;&gt;Running your site locally with HTTPS using mkcert (recommended) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/how-to-use-local-https/#running-your-site-locally-with-https-using-mkcert-recommended&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To use HTTPS with your local development site and access &lt;code&gt;https://localhost&lt;/code&gt; or
&lt;code&gt;https://mysite.example&lt;/code&gt; (custom hostname), you need a &lt;a href=&quot;https://en.wikipedia.org/wiki/Public_key_certificate#TLS/SSL_server_certificate&quot; rel=&quot;noopener&quot;&gt;TLS
certificate&lt;/a&gt;. But
browsers won&#39;t consider just any certificate valid: your certificate needs to be &lt;strong&gt;signed&lt;/strong&gt; by an entity that
is trusted by your browser, called a trusted &lt;strong&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Certificate_authority&quot; rel=&quot;noopener&quot;&gt;certificate authority (CA)&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;What you need to do is to create a certificate and sign it with a CA that is &lt;strong&gt;trusted locally&lt;/strong&gt; by your device
and browser. &lt;a href=&quot;https://github.com/FiloSottile/mkcert&quot; rel=&quot;noopener&quot;&gt;mkcert&lt;/a&gt; is a tool that helps you do this in a few commands. Here&#39;s how it works:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you open your locally running site in your browser using HTTPS, your browser will
check the certificate of your local development server.&lt;/li&gt;
&lt;li&gt;Upon seeing that the certificate has been signed by the mkcert-generated certificate
authority, the browser checks whether it&#39;s registered as a trusted certificate authority.&lt;/li&gt;
&lt;li&gt;mkcert is listed as a trusted authority, so your browser trusts the
certificate and creates an HTTPS connection.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A diagram of how mkcert works.&quot; decoding=&quot;async&quot; height=&quot;787&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/3kdjci7NORnOw54fMia9.jpg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;A diagram of how mkcert works.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;mkcert (and similar tools) provide several benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mkcert is specialized in creating certificates that are &lt;strong&gt;compliant with what browsers consider
valid certificates&lt;/strong&gt;. It stays updated to match requirements and best practices. This is why you
won&#39;t have to run mkcert commands with complex configurations or arguments to generate the right
certificates!&lt;/li&gt;
&lt;li&gt;mkcert is a cross-platform tool. Anyone on your team can use it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;mkcert is the tool we recommend for creating a TLS certificate for local development. You can check out &lt;a href=&quot;https://web.dev/how-to-use-local-https/#running-your-site-locally-with-https-other-options&quot;&gt;other options&lt;/a&gt; too.&lt;/p&gt;
&lt;p&gt;Many operating systems may include libraries to produce certificates, such as &lt;a href=&quot;https://www.openssl.org/&quot; rel=&quot;noopener&quot;&gt;openssl&lt;/a&gt;. Unlike mkcert
and similar tools, such libraries may not consistently produce correct certificates, may require
complex commands to be run, and are not necessarily cross-platform.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-tertiary-box-bg color-tertiary-box-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; role=&quot;img&quot; aria-label=&quot;Lightbulb&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;   &lt;path d=&quot;M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6A4.997 4.997 0 017 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Gotchas&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; The mkcert we&#39;re interested in in this post is &lt;a href=&quot;https://github.com/FiloSottile/mkcert&quot;&gt;this one&lt;/a&gt;, not &lt;a href=&quot;https://www.npmjs.com/package/mkcert&quot;&gt;this one&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;caution&quot;&gt;Caution &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/how-to-use-local-https/#caution&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;aside class=&quot;aside flow bg-state-bad-bg color-state-bad-text&quot;&gt;&lt;p class=&quot;cluster color-state-bad-text&quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Error sign&quot;&gt;   &lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15v-2h2v2h-2zm0-10v6h2V7h-2z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Caution&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt;  - Never export or share the file &lt;code&gt;rootCA-key.pem&lt;/code&gt; mkcert creates automatically when you run &lt;code&gt;mkcert -install&lt;/code&gt;. &lt;strong&gt;An attacker getting hold of this file can create on-path attacks for any site you may be visiting&lt;/strong&gt;. They could intercept secure requests from your machine to any site—your bank, healthcare provider, or social networks. If you need to know where &lt;code&gt;rootCA-key.pem&lt;/code&gt; is located to make sure it&#39;s safe, run &lt;code&gt;mkcert -CAROOT&lt;/code&gt;. - Only use mkcert for &lt;strong&gt;development purposes&lt;/strong&gt;—and by extension, never ask end-users to run mkcert commands. - Development teams: all members of your team should install and run mkcert &lt;strong&gt;separately&lt;/strong&gt; (not store and share the CA and certificate).  &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;setup&quot;&gt;Setup &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/how-to-use-local-https/#setup&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install mkcert (only once).&lt;/p&gt;
&lt;p&gt;Follow the &lt;a href=&quot;https://github.com/FiloSottile/mkcert#installation&quot; rel=&quot;noopener&quot;&gt;instructions&lt;/a&gt; for installing mkcert on your operating system.
For example, on macOS:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; mkcert&lt;br /&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; nss &lt;span class=&quot;token comment&quot;&gt;# if you use Firefox&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add mkcert to your local root CAs.&lt;/p&gt;
&lt;p&gt;In your terminal, run the following command:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;mkcert -install&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;This generates a local certificate authority (CA).
Your mkcert-generated local CA is only trusted &lt;strong&gt;locally&lt;/strong&gt;, on your device.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Generate a certificate for your site, signed by mkcert.&lt;/p&gt;
&lt;p&gt;In your terminal, navigate to your site&#39;s root directory or whichever directory you&#39;d like the certificates to be located at.&lt;/p&gt;
&lt;p&gt;Then, run:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;mkcert localhost&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;If you&#39;re using a custom hostname like &lt;code&gt;mysite.example&lt;/code&gt;, run:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;mkcert mysite.example&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The command above does two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generates a certificate for the hostname you&#39;ve specified&lt;/li&gt;
&lt;li&gt;Lets mkcert (that you&#39;ve added as a local CA in Step 2) sign this certificate.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, your certificate is ready and signed by a certificate authority your browser trusts locally. You&#39;re almost done, but your server doesn&#39;t know about your certificate yet!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configure your server.&lt;/p&gt;
&lt;p&gt;You now need to tell your server to use HTTPS (since development servers tend to use HTTP by default) and to use the TLS certificate you&#39;ve just created.&lt;/p&gt;
&lt;p&gt;How to do this exactly depends on your server. A few examples:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;👩🏻‍💻 With node:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;server.js&lt;/code&gt; (replace &lt;code&gt;{PATH/TO/CERTIFICATE...}&lt;/code&gt; and &lt;code&gt;{PORT}&lt;/code&gt;):&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; https &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;https&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;fs&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; options &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; fs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;{PATH/TO/CERTIFICATE-KEY-FILENAME}.pem&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;cert&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; fs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;{PATH/TO/CERTIFICATE-FILENAME}.pem&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;https&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createServer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;// server code&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;👩🏻‍💻 With &lt;a href=&quot;https://www.npmjs.com/package/http-server&quot; rel=&quot;noopener&quot;&gt;http-server&lt;/a&gt;:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Start your server as follows (replace &lt;code&gt;{PATH/TO/CERTIFICATE...}&lt;/code&gt;):&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;http-server -S -C &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token environment constant&quot;&gt;PATH&lt;/span&gt;/TO/CERTIFICATE-FILENAME&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;.pem -K &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token environment constant&quot;&gt;PATH&lt;/span&gt;/TO/CERTIFICATE-KEY-FILENAME&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;.pem&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;-S&lt;/code&gt; runs your server with HTTPS, while &lt;code&gt;-C&lt;/code&gt; sets the certificate and &lt;code&gt;-K&lt;/code&gt; sets the key.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;👩🏻‍💻 With a React development server:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Edit your &lt;code&gt;package.json&lt;/code&gt; as follows, and replace &lt;code&gt;{PATH/TO/CERTIFICATE...}&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token property&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token property&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HTTPS=true SSL_CRT_FILE={PATH/TO/CERTIFICATE-FILENAME}.pem SSL_KEY_FILE={PATH/TO/CERTIFICATE-KEY-FILENAME}.pem react-scripts start&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;For example, if you&#39;ve created a certificate for &lt;code&gt;localhost&lt;/code&gt; that is located in your site&#39;s root directory as follows:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;|-- my-react-app&lt;br /&gt;    |-- package.json&lt;br /&gt;    |-- localhost.pem&lt;br /&gt;    |-- localhost-key.pem&lt;br /&gt;    |--...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Then your &lt;code&gt;start&lt;/code&gt; script should look like this:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token property&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HTTPS=true SSL_CRT_FILE=localhost.pem SSL_KEY_FILE=localhost-key.pem react-scripts start&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;👩🏻‍💻 Other examples:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://angular.io/cli/serve&quot; rel=&quot;noopener&quot;&gt;Angular development server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.anvileight.com/posts/simple-python-http-server/&quot; rel=&quot;noopener&quot;&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✨ You&#39;re done!
Open &lt;code&gt;https://localhost&lt;/code&gt; or &lt;code&gt;https://mysite.example&lt;/code&gt; in your browser: you&#39;re running your site locally with HTTPS.
You won&#39;t see any browser warnings, because your browser trusts mkcert as a local certificate authority.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; Your server may use a different port for HTTPS. &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;using-mkcert-cheatsheet&quot;&gt;Using mkcert: cheatsheet &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/how-to-use-local-https/#using-mkcert-cheatsheet&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;details&gt;
&lt;summary&gt;
  mkcert in short
&lt;/summary&gt;
&lt;p&gt;To run your local development site with HTTPS:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Set up mkcert.&lt;/p&gt;
&lt;p&gt;If you haven&#39;t yet, install mkcert, for example on macOS:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; mkcert&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Check &lt;a href=&quot;https://github.com/FiloSottile/mkcert#installation&quot; rel=&quot;noopener&quot;&gt;install mkcert&lt;/a&gt; for Windows and Linux instructions.&lt;/p&gt;
&lt;p&gt;Then, create a local certificate authority:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;mkcert -install&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a trusted certificate.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;mkcert &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;YOUR &lt;span class=&quot;token environment constant&quot;&gt;HOSTNAME&lt;/span&gt; e.g. localhost or mysite.example&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;This create a valid certificate (that will be signed by &lt;code&gt;mkcert&lt;/code&gt; automatically).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configure your development server to use HTTPS and the certificate you&#39;ve created in Step 2.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✨ You&#39;re done! You can now access &lt;code&gt;https://{YOUR HOSTNAME}&lt;/code&gt; in your browser, without warnings&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;aside class=&quot;aside flow bg-state-bad-bg color-state-bad-text&quot;&gt;&lt;p class=&quot;cluster color-state-bad-text&quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Error sign&quot;&gt;   &lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15v-2h2v2h-2zm0-10v6h2V7h-2z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Caution&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt;  Do this only for &lt;strong&gt;development purposes&lt;/strong&gt; and &lt;strong&gt;never export or share&lt;/strong&gt; the file &lt;code&gt;rootCA-key.pem&lt;/code&gt; (if you need to know where this file is located to make sure it&#39;s safe, run &lt;code&gt;mkcert -CAROOT&lt;/code&gt;).  &lt;/div&gt;&lt;/aside&gt;
&lt;/details&gt;
&lt;h2 id=&quot;running-your-site-locally-with-https-other-options&quot;&gt;Running your site locally with HTTPS: other options &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/how-to-use-local-https/#running-your-site-locally-with-https-other-options&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;self-signed-certificate&quot;&gt;Self-signed certificate &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/how-to-use-local-https/#self-signed-certificate&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You may also decide to not use a local certificate authority like mkcert, and instead &lt;strong&gt;sign your certificate yourself&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Beware of a few pitfalls with this approach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Browsers don&#39;t trust you as a certificate authority and they&#39;ll show warnings you&#39;ll need to bypass manually. In Chrome, you may use the flag &lt;code&gt;#allow-insecure-localhost&lt;/code&gt; to bypass this warning automatically on &lt;code&gt;localhost&lt;/code&gt;. It feels a bit hacky, because it is.&lt;/li&gt;
&lt;li&gt;This is unsafe if you&#39;re working in an insecure network.&lt;/li&gt;
&lt;li&gt;Self-signed certificates won&#39;t behave in exactly the same way as trusted certificates.&lt;/li&gt;
&lt;li&gt;It&#39;s not necessarily easier or faster than using a local CA like mkcert.&lt;/li&gt;
&lt;li&gt;If you&#39;re not using this technique in a browser context, you may need to disable certificate verification for your server. Omitting to re-enable it in production would be dangerous.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
  &lt;img alt=&quot;Screenshots of the warnings browsers show when a self-signed certificate is used.&quot; decoding=&quot;async&quot; height=&quot;598&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/KxLz7mcUudiFwWBIdhH8.jpg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;The warnings browsers show when a self-signed certificate is used.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; If you don&#39;t specify any certificate, &lt;a href=&quot;https://create-react-app.dev/docs/using-https-in-development/&quot;&gt;React&#39;s&lt;/a&gt; and &lt;a href=&quot;https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-serve&quot;&gt;Vue&#39;s&lt;/a&gt; development server HTTPS options create a self-signed certificate under the hood. This is quick, but you&#39;ll get browser warnings and encounter other pitfalls related to self-signed certificates that are listed above. Luckily you can use frontend frameworks&#39; built-in HTTPS option &lt;strong&gt;and&lt;/strong&gt; specify a locally trusted certificate created via mkcert or similar. See how to do this in the &lt;a href=&quot;https://web.dev/#setup:~:text=a%20React%20development%20server&quot;&gt;mkcert with React example&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
&lt;details&gt;
&lt;summary&gt;
  Why don&#39;t browsers trust self-signed certificates?
&lt;/summary&gt;
&lt;p&gt;If you open your locally running site in your browser using HTTPS, your browser will check the certificate of your local development server. When it sees that the certificate has been signed by yourself, it checks whether you&#39;re registered as a trusted certificate authority. Because you&#39;re not, your browser can&#39;t trust the certificate; it displays a warning telling you that your connection is not secure. You may proceed at your own risk—if you do, an HTTPS connection will be created.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;Why browsers don&amp;#x27;t trust self-signed certificates: a diagram.&quot; decoding=&quot;async&quot; height=&quot;833&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/V2SAcIzuofqzUuestOOX.jpg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;Why browsers don&#39;t trust self-signed certificates.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/details&gt;
&lt;h3 id=&quot;certificate-signed-by-a-regular-certificate-authority&quot;&gt;Certificate signed by a regular certificate authority &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/how-to-use-local-https/#certificate-signed-by-a-regular-certificate-authority&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You may also find techniques based on having an actual certificate authority—not a local one—sign your certificate.&lt;/p&gt;
&lt;p&gt;A few things to keep in mind if you&#39;re considering using these techniques:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You&#39;ll have more setup work to do than when using a local CA technique like mkcert.&lt;/li&gt;
&lt;li&gt;You need to use a domain name that you control and that is valid. This means that you &lt;strong&gt;can&#39;t&lt;/strong&gt; use actual certificate authorities for:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;localhost&lt;/code&gt; and other domain names that are &lt;a href=&quot;https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml&quot; rel=&quot;noopener&quot;&gt;reserved&lt;/a&gt;, such as &lt;code&gt;example&lt;/code&gt; or &lt;code&gt;test&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Any domain name that you don&#39;t control.&lt;/li&gt;
&lt;li&gt;Top-level domains that are not valid. See the &lt;a href=&quot;https://www.iana.org/domains/root/db&quot; rel=&quot;noopener&quot;&gt;list of valid top-level domains&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;reverse-proxy&quot;&gt;Reverse proxy &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/how-to-use-local-https/#reverse-proxy&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Another option to access a locally running site with HTTPS is to use a &lt;a href=&quot;https://en.wikipedia.org/wiki/Reverse_proxy&quot; rel=&quot;noopener&quot;&gt;reverse proxy&lt;/a&gt; such as &lt;a href=&quot;https://ngrok.com/&quot; rel=&quot;noopener&quot;&gt;ngrok&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A few points to consider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Anyone can access your local development site once you share with them a URL created with a reverse proxy. This can be very handy when demoing your project to clients! Or this can be a downside, if your project is sensitive.&lt;/li&gt;
&lt;li&gt;You may need to consider pricing.&lt;/li&gt;
&lt;li&gt;New &lt;a href=&quot;https://web.dev/cors-rfc1918-feedback/&quot;&gt;security measures&lt;/a&gt; in browsers may affect the way these tools work.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;flag-not-recommended&quot;&gt;Flag (not recommended) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/how-to-use-local-https/#flag-not-recommended&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you&#39;re using a custom hostname like &lt;code&gt;mysite.example&lt;/code&gt;, you can use a flag in Chrome to forcefully consider &lt;code&gt;mysite.example&lt;/code&gt; secure. &lt;strong&gt;Avoid doing this&lt;/strong&gt;, because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You would need to be 100% sure that &lt;code&gt;mysite.example&lt;/code&gt; always resolves to a local address, otherwise you could leak production credentials.&lt;/li&gt;
&lt;li&gt;You won&#39;t be able to debug across browsers with this trick 🙀.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;With many thanks for contributions and feedback to all reviewers and contributors—especially Ryan Sleevi,
Filippo Valsorda, Milica Mihajlija and Rowan Merewood. 🙌&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Hero image background by &lt;a href=&quot;https://unsplash.com/@anandu&quot; rel=&quot;noopener&quot;&gt;@anandu&lt;/a&gt; on &lt;a href=&quot;https://unsplash.com/photos/pbxwxwfI0B4&quot; rel=&quot;noopener&quot;&gt;Unsplash&lt;/a&gt;, edited.&lt;/em&gt;&lt;/p&gt;
</content>
    <author>
      <name>Maud Nalpas</name>
    </author>
  </entry>
  
  <entry>
    <title>When to use HTTPS for local development</title>
    <link href="https://web.dev/when-to-use-local-https/"/>
    <updated>2021-01-25T00:00:00Z</updated>
    <id>https://web.dev/when-to-use-local-https/</id>
    <content type="html" mode="escaped">&lt;p&gt;Also see: &lt;a href=&quot;https://web.dev/how-to-use-local-https&quot;&gt;How to use HTTPS for local development&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;In this post, statements about &lt;code&gt;localhost&lt;/code&gt; are valid for &lt;code&gt;127.0.0.1&lt;/code&gt; and &lt;code&gt;[::1]&lt;/code&gt; as well, since they both describe the local computer address, also called &amp;quot;loopback address&amp;quot;. Also, to keep things simple, the port number isn&#39;t specified.&lt;/em&gt;
&lt;em&gt;So when you see &lt;code&gt;http://localhost&lt;/code&gt;, read it as &lt;code&gt;http://localhost:{PORT}&lt;/code&gt; or &lt;code&gt;http://127.0.0.1:{PORT}&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/when-to-use-local-https/#summary&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When developing locally, use &lt;code&gt;http://localhost&lt;/code&gt; by default. Service Workers, Web Authentication API, and more will work.
However, in the following cases, you&#39;ll need HTTPS for local development:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Setting Secure cookies in a consistent way across browsers&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Debugging mixed-content issues&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Using HTTP/2 and later&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Using third-party libraries or APIs that require HTTPS&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Using a custom hostname&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A list of cases when you need to use HTTPS for local development.&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/ifswaep3VUkY7cjArbIc.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;When to use HTTPS for local development.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; If you need HTTPS for one of the above use cases, check out &lt;a href=&quot;https://web.dev/how-to-use-local-https&quot;&gt;How to use HTTPS for local development&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
&lt;p&gt;✨ This is all you need to know. If you&#39;re interested in more details keep reading!&lt;/p&gt;
&lt;h2 id=&quot;why-your-development-site-should-behave-securely&quot;&gt;Why your development site should behave securely &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/when-to-use-local-https/#why-your-development-site-should-behave-securely&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To avoid running into unexpected issues, you want your local development site to behave as much as possible like your production website. So, if your production website uses HTTPS, you want your local development site to behave &lt;strong&gt;like an HTTPS site&lt;/strong&gt;.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-warn-bg color-state-warn-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block color-state-warn-text&quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;currentColor&quot; role=&quot;img&quot; aria-label=&quot;Warning sign&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;   &lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M23 21L12 2 1 21h22zm-12-3v-2h2v2h-2zm0-4h2v-4h-2v4z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Warning&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; If your production website doesn&#39;t use HTTPS, &lt;a href=&quot;https://web.dev/why-https-matters/&quot;&gt;make it a priority&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;use-httplocalhost-by-default&quot;&gt;Use &lt;code&gt;http://localhost&lt;/code&gt; by default &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/when-to-use-local-https/#use-httplocalhost-by-default&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Browsers treat &lt;code&gt;http://localhost&lt;/code&gt; in a special way: &lt;strong&gt;although it&#39;s HTTP, it mostly behaves like an HTTPS site&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;On &lt;code&gt;http://localhost&lt;/code&gt;, Service Workers, Sensor APIs, Authentication APIs, Payments, and &lt;a href=&quot;https://developer.mozilla.org/docs/Web/Security/Secure_Contexts/features_restricted_to_secure_contexts&quot; rel=&quot;noopener&quot;&gt;other features that require certain security guarantees&lt;/a&gt; are supported and behave exactly like on an HTTPS site.&lt;/p&gt;
&lt;h2 id=&quot;when-to-use-https-for-local-development&quot;&gt;When to use HTTPS for local development &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/when-to-use-local-https/#when-to-use-https-for-local-development&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You may encounter special cases where &lt;code&gt;http://localhost&lt;/code&gt; &lt;em&gt;doesn&#39;t&lt;/em&gt; behave like an HTTPS site—or you may simply want to use a custom site name that&#39;s not &lt;code&gt;http://localhost&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You need to use HTTPS for local development in the following cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You need to &lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie&quot; rel=&quot;noopener&quot;&gt;set a cookie&lt;/a&gt; locally that is &lt;code&gt;Secure&lt;/code&gt;, or &lt;code&gt;SameSite:none&lt;/code&gt;, or has the &lt;code&gt;__Host&lt;/code&gt; prefix. &lt;code&gt;Secure&lt;/code&gt; cookies are set only on HTTPS, but not on &lt;code&gt;http://localhost&lt;/code&gt; for all browsers. And because &lt;code&gt;SameSite:none&lt;/code&gt; and &lt;code&gt;__Host&lt;/code&gt; also require the cookie to be &lt;code&gt;Secure&lt;/code&gt;, setting such cookies on your local development site requires HTTPS as well.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-tertiary-box-bg color-tertiary-box-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; role=&quot;img&quot; aria-label=&quot;Lightbulb&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;   &lt;path d=&quot;M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6A4.997 4.997 0 017 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Gotchas&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; When it comes to setting &lt;code&gt;Secure&lt;/code&gt; cookies locally, not all browsers behave in the same way! For example, Chrome and Safari don&#39;t set &lt;code&gt;Secure&lt;/code&gt; cookies on localhost, but Firefox does. In Chrome, this is considered a &lt;a href=&quot;https://bugs.chromium.org/p/chromium/issues/detail?id=1056543&amp;amp;q=localhost%20secure%20cookie&amp;amp;can=2&quot;&gt;bug&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You need to debug locally an issue that only occurs on an HTTPS website but not on an HTTP site, not even &lt;code&gt;http://localhost&lt;/code&gt;, such as a &lt;a href=&quot;https://developer.mozilla.org/docs/Web/Security/Mixed_content&quot; rel=&quot;noopener&quot;&gt;mixed-content&lt;/a&gt; issue.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You need to locally test or reproduce a behaviour specific to HTTP/2 or newer. For example, if you need to test loading performance on HTTP/2 or newer. Insecure HTTP/2 or newer is not supported, not even on &lt;code&gt;localhost&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You need to locally test third-party libraries or APIs that require HTTPS (for example OAuth).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You&#39;re not using &lt;code&gt;localhost&lt;/code&gt;, but a custom host name for local development, for example &lt;code&gt;mysite.example&lt;/code&gt;. Typically, this means you&#39;ve overridden your local hosts file:&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;Screenshot of a terminal editing a hosts file&quot; decoding=&quot;async&quot; height=&quot;318&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 740px) 740px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/i7dPGFARXLbg9oIAUol2.jpg?auto=format&amp;w=1480 1480w&quot; width=&quot;740&quot; /&gt;
  &lt;figcaption&gt;Editing a hosts file to add a custom hostname.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In this case, Chrome, Edge, Safari, and Firefox by default do &lt;em&gt;not&lt;/em&gt; consider &lt;code&gt;mysite.example&lt;/code&gt; to be secure, even though it&#39;s a local site. So it won&#39;t behave like an HTTPS site.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Other cases! This is not an exhaustive list, but if you encounter a case that&#39;s not listed here, you&#39;ll know: things will break on &lt;code&gt;http://localhost&lt;/code&gt;, or it won&#39;t quite behave like your production site. 🙃&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;In all of these cases, you need to use HTTPS for local development.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;how-to-use-https-for-local-development&quot;&gt;How to use HTTPS for local development &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/when-to-use-local-https/#how-to-use-https-for-local-development&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you need to use HTTPS for local development, head over to &lt;a href=&quot;https://web.dev/how-to-use-local-https&quot;&gt;How to use HTTPS for local development&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;tips-if-youre-using-a-custom-hostname&quot;&gt;Tips if you&#39;re using a custom hostname &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/when-to-use-local-https/#tips-if-youre-using-a-custom-hostname&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;If you&#39;re using a custom hostname, for example, editing your hosts file:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don&#39;t use a bare hostname like &lt;code&gt;mysite&lt;/code&gt; because if there&#39;s a &lt;a href=&quot;https://en.wikipedia.org/wiki/Top-level_domain&quot; rel=&quot;noopener&quot;&gt;top-level domain (TLD)&lt;/a&gt; that happens to have the same name (&lt;code&gt;mysite&lt;/code&gt;), you&#39;ll run into issues. And it&#39;s not that unlikely: in 2020, there are over 1,500 TLDs, and the list is growing. &lt;code&gt;coffee&lt;/code&gt;, &lt;code&gt;museum&lt;/code&gt;, &lt;code&gt;travel&lt;/code&gt;, and many large company names (maybe even the company you&#39;re working at!) are TLDs. &lt;a href=&quot;https://data.iana.org/TLD/tlds-alpha-by-domain.txt&quot; rel=&quot;noopener&quot;&gt;See the full list here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Only use domains that are yours, or that are reserved for this purpose. If you don&#39;t have a domain of your own, you can use either &lt;code&gt;test&lt;/code&gt; or &lt;code&gt;localhost&lt;/code&gt; (&lt;code&gt;mysite.localhost&lt;/code&gt;). &lt;code&gt;test&lt;/code&gt; doesn&#39;t have special treatment in browsers, but &lt;code&gt;localhost&lt;/code&gt; does: Chrome and Edge support &lt;code&gt;http://&amp;lt;name&amp;gt;.localhost&lt;/code&gt; out of the box, and it will behave securely when localhost does. Try it out: run any site on localhost and access &lt;code&gt;http://&amp;lt;whatever name you like&amp;gt;.localhost:&amp;lt;your port&amp;gt;&lt;/code&gt; in Chrome or Edge. This may soon be possible in Firefox and &lt;a href=&quot;https://bugs.webkit.org/show_bug.cgi?id=160504&quot; rel=&quot;noopener&quot;&gt;Safari&lt;/a&gt; as well. The reason you can do this (have subdomains like &lt;code&gt;mysite.localhost&lt;/code&gt;) is because &lt;code&gt;localhost&lt;/code&gt; is not just a hostname: it&#39;s also a full TLD, like &lt;code&gt;com&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;learn-more&quot;&gt;Learn more &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/when-to-use-local-https/#learn-more&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/Security/Secure_Contexts&quot; rel=&quot;noopener&quot;&gt;Secure contexts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.w3.org/TR/secure-contexts/#localhost&quot; rel=&quot;noopener&quot;&gt;localhost as a secure context&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.chromestatus.com/feature/6269417340010496&quot; rel=&quot;noopener&quot;&gt;localhost as a secure context in Chrome&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;With many thanks for contributions and feedback to all reviewers—especially Ryan Sleevi,
Filippo Valsorda, Milica Mihajlija, Rowan Merewood and Jake Archibald. 🙌&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Hero image by &lt;a href=&quot;https://unsplash.com/@moses_lee&quot; rel=&quot;noopener&quot;&gt;@moses_lee&lt;/a&gt; on &lt;a href=&quot;https://unsplash.com/photos/Q2Xy_hYzrgg&quot; rel=&quot;noopener&quot;&gt;Unsplash&lt;/a&gt;, edited.&lt;/em&gt;&lt;/p&gt;
</content>
    <author>
      <name>Maud Nalpas</name>
    </author>
  </entry>
  
  <entry>
    <title>Referer and Referrer-Policy best practices</title>
    <link href="https://web.dev/referrer-best-practices/"/>
    <updated>2020-07-30T00:00:00Z</updated>
    <id>https://web.dev/referrer-best-practices/</id>
    <content type="html" mode="escaped">&lt;h2 id=&quot;summary&quot;&gt;Summary &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#summary&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Unexpected cross-origin information leakage hinders web users&#39; privacy. A protective referrer
policy can help.&lt;/li&gt;
&lt;li&gt;Consider setting a referrer policy of &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt;. It retains much of the
referrer&#39;s usefulness, while mitigating the risk of leaking data cross-origins.&lt;/li&gt;
&lt;li&gt;Don&#39;t use referrers for Cross-Site Request Forgery (CSRF) protection. Use &lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#token-based-mitigation&quot; rel=&quot;noopener&quot;&gt;CSRF
tokens&lt;/a&gt;
instead, and other headers as an extra layer of security.&lt;/li&gt;
&lt;/ul&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; Before we start:  - If you&#39;re unsure of the difference between &amp;quot;site&amp;quot; and &amp;quot;origin&amp;quot;, check out &lt;a href=&quot;https://web.dev/same-site-same-origin/&quot;&gt;Understanding &amp;quot;same-site&amp;quot; and &amp;quot;same-origin&amp;quot;&lt;/a&gt;. - The &lt;code&gt;Referer&lt;/code&gt; header is missing an R, due to an original misspelling in the spec. The &lt;code&gt;Referrer-Policy&lt;/code&gt; header and &lt;code&gt;referrer&lt;/code&gt; in JavaScript and the DOM are spelled correctly. &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;referer-and-referrer-policy-101&quot;&gt;Referer and Referrer-Policy 101 &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#referer-and-referrer-policy-101&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;HTTP requests may include the optional &lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Referer&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;Referer&lt;/code&gt;
header&lt;/a&gt;, which indicates the
origin or web page URL the request was made from. The &lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-Policy&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;Referrer-Policy&lt;/code&gt;
header&lt;/a&gt; defines what data
is made available in the &lt;code&gt;Referer&lt;/code&gt; header.&lt;/p&gt;
&lt;p&gt;In the example below, the &lt;code&gt;Referer&lt;/code&gt; header includes the complete URL of the page on &lt;code&gt;site-one&lt;/code&gt; from
which the request was made.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;HTTP request including a Referer header.&quot; decoding=&quot;async&quot; height=&quot;573&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/cXgqJfmD5OPdzqXl9RNt.jpg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;code&gt;Referer&lt;/code&gt; header might be present in different types of requests:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Navigation requests, when a user clicks a link&lt;/li&gt;
&lt;li&gt;Subresource requests, when a browser requests images, iframes, scripts, and other resources that a
page needs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For navigations and iframes, this data can also be accessed via JavaScript using
&lt;code&gt;document.referrer&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Referer&lt;/code&gt; value can be insightful. For example, an analytics service might use the value to
determine that 50% of the visitors on &lt;code&gt;site-two.example&lt;/code&gt; came from &lt;code&gt;social-network.example&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But when the full URL including the path and query string is sent in the &lt;code&gt;Referer&lt;/code&gt; &lt;strong&gt;across
origins&lt;/strong&gt;, this can be &lt;strong&gt;privacy-hindering&lt;/strong&gt; and pose &lt;strong&gt;security risks&lt;/strong&gt; as well. Take a look at
these URLs:&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;URLs with paths, mapped to different privacy and security risks.&quot; decoding=&quot;async&quot; height=&quot;370&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/oTUtfrwaGYYjlOJ6KRs6.jpg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;URLs #1 to #5 contain private information—sometimes even identifying or sensitive. Leaking these
silently across origins can compromise web users&#39; privacy.&lt;/p&gt;
&lt;p&gt;URL #6 is a &lt;a href=&quot;https://www.w3.org/TR/capability-urls/&quot; rel=&quot;noopener&quot;&gt;capability URL&lt;/a&gt;. You don&#39;t want it to fall in
the hands of anyone other than the intended user. If this were to happen, a malicious actor could
hijack this user&#39;s account.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In order to restrict what referrer data is made available for requests from your site, you can set
a referrer policy.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-policies-are-available-and-how-do-they-differ&quot;&gt;What policies are available and how do they differ? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#what-policies-are-available-and-how-do-they-differ&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can select one of eight policies. Depending on the policy, the data available from the &lt;code&gt;Referer&lt;/code&gt;
header (and &lt;code&gt;document.referrer&lt;/code&gt;) can be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No data (no &lt;code&gt;Referer&lt;/code&gt; header is present)&lt;/li&gt;
&lt;li&gt;Only the &lt;a href=&quot;https://web.dev/same-site-same-origin/#origin&quot;&gt;origin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The full URL: origin, path, and query string&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
  &lt;img alt=&quot;Data that can be contained in the Referer header and document.referrer.&quot; decoding=&quot;async&quot; height=&quot;255&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/UR1U0HRP0BOF1e0XnyWA.jpg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;Some policies are designed to behave differently depending on the &lt;strong&gt;context&lt;/strong&gt;: cross-origin or
same-origin request, security (whether the request destination is as secure as the origin), or both.
This is useful to limit the amount of information shared across origins or to less secure
origins—while maintaining the richness of the referrer within your own site.&lt;/p&gt;
&lt;p&gt;Here is an overview showing how referrer policies restrict the URL data available from the Referer
header and &lt;code&gt;document.referrer&lt;/code&gt;:&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;Different referrer policies and their behaviour, depending on the security and cross-origin context.&quot; decoding=&quot;async&quot; height=&quot;537&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/BIHWDY60CI317O7IzmQs.jpg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;MDN provides a &lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-Policy#Directives&quot; rel=&quot;noopener&quot;&gt;full list of policies and behavior
examples&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Things to note:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All policies that take the scheme (HTTPS vs. HTTP) into account (&lt;code&gt;strict-origin&lt;/code&gt;,
&lt;code&gt;no-referrer-when-downgrade&lt;/code&gt; and &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt;) treat requests from an HTTP
origin to another HTTP origin the same way as requests from an HTTPS origin to another HTTPS
origin—even if HTTP is less secure. That&#39;s because for these policies, what matters is whether a
security &lt;strong&gt;downgrade&lt;/strong&gt; takes place, i.e. if the request can expose data from an encrypted origin
to an unencrypted one. An HTTP → HTTP request is unencrypted all along, so there is no downgrade.
HTTPS → HTTP requests, on the contrary, present a downgrade.&lt;/li&gt;
&lt;li&gt;If a request is &lt;strong&gt;same-origin&lt;/strong&gt;, this means that the scheme (HTTPS or HTTP) is the same; hence
there is no security downgrade.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;default-referrer-policies-in-browsers&quot;&gt;Default referrer policies in browsers &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#default-referrer-policies-in-browsers&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;As of October 2021&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If no referrer policy is set, the browser&#39;s default policy will be used.&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;
  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Browser&lt;/th&gt;
        &lt;th&gt;Default &lt;code&gt;Referrer-Policy&lt;/code&gt; / Behavior&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Chrome&lt;/td&gt;
        &lt;td&gt;
          The default is &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt;.
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Firefox&lt;/td&gt;
        &lt;td&gt;
        The default is &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt;.&lt;br /&gt;
        Starting from &lt;a href=&quot;https://blog.mozilla.org/security/2021/10/05/firefox-93-features-an-improved-smartblock-and-new-referrer-tracking-protections/&quot;&gt;version 93&lt;/a&gt;, for Strict Tracking Protection and Private Browsing users: the less restrictive referrer policies &lt;code&gt;no-referrer-when-downgrade&lt;/code&gt;, &lt;code&gt;origin-when-cross-origin&lt;/code&gt;, and &lt;code&gt;unsafe-url&lt;/code&gt; are ignored for cross-site requests, meaning that the referrer is always trimmed for cross-site requests, regardless of the website&#39;s policy.
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Edge&lt;/td&gt;
        &lt;td&gt;
          The default is &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt;.
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Safari&lt;/td&gt;
        &lt;td&gt;
          The default is similar to &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt;, with some specificities. See
          &lt;a href=&quot;https://webkit.org/blog/9661/preventing-tracking-prevention-tracking/&quot;&gt;Preventing Tracking Prevention Tracking&lt;/a&gt; for details.
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
&lt;/div&gt;
&lt;h2 id=&quot;setting-your-referrer-policy-best-practices&quot;&gt;Setting your referrer policy: best practices &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#setting-your-referrer-policy-best-practices&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;aside class=&quot;aside flow bg-state-good-bg color-state-good-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 24 24&quot; height=&quot;24&quot; width=&quot;24&quot; fill=&quot;currentColor&quot; role=&quot;img&quot; aria-label=&quot;Check&quot;&gt;   &lt;path d=&quot;M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Objective&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; Explicitly set a privacy-enhancing policy, such as &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt;(or stricter). &lt;/div&gt;&lt;/aside&gt;
&lt;p&gt;There are different ways to set referrer policies for your site:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As an HTTP header&lt;/li&gt;
&lt;li&gt;Within your
&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-Policy#Integration_with_HTML&quot; rel=&quot;noopener&quot;&gt;HTML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;From JavaScript on a &lt;a href=&quot;https://javascript.info/fetch-api#referrer-referrerpolicy&quot; rel=&quot;noopener&quot;&gt;per-request
basis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can set different policies for different pages, requests or elements.&lt;/p&gt;
&lt;p&gt;The HTTP header and the meta element are both page-level. The precedence order when determining an
element&#39;s effective policy is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Element-level policy&lt;/li&gt;
&lt;li&gt;Page-level policy&lt;/li&gt;
&lt;li&gt;Browser default&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;index.html&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;referrer&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;strict-origin-when-cross-origin&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;...&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;referrerpolicy&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;no-referrer-when-downgrade&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The image will be requested with a &lt;code&gt;no-referrer-when-downgrade&lt;/code&gt; policy, while all other subresource
requests from this page will follow the &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt; policy.&lt;/p&gt;
&lt;h2 id=&quot;how-to-see-the-referrer-policy&quot;&gt;How to see the referrer policy? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#how-to-see-the-referrer-policy&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://securityheaders.com/&quot; rel=&quot;noopener&quot;&gt;securityheaders.com&lt;/a&gt; is handy to determine the policy a specific site
or page is using.&lt;/p&gt;
&lt;p&gt;You can also use the developer tools of Chrome, Edge, or Firefox to see the referrer policy used for
a specific request. At the time of this writing, Safari doesn&#39;t show the &lt;code&gt;Referrer-Policy&lt;/code&gt; header
but does show the &lt;code&gt;Referer&lt;/code&gt; that was sent.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A screenshot of the Network panel of Chrome DevTools, showing Referer and Referrer-Policy.&quot; decoding=&quot;async&quot; height=&quot;416&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/8Qlu6ZzSVgL2f9iYIplJ.jpg?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;
    Chrome DevTools, &lt;b&gt;Network&lt;/b&gt; panel with a request selected.
  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;which-policy-should-you-set-for-your-website&quot;&gt;Which policy should you set for your website? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#which-policy-should-you-set-for-your-website&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Summary: Explicitly set a privacy-enhancing policy such as &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt; (or
stricter).&lt;/p&gt;
&lt;h3 id=&quot;why-explicitly&quot;&gt;Why &amp;quot;explicitly&amp;quot;? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#why-explicitly&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If no referrer policy is set, the browser&#39;s default policy will be used—in fact, websites often
defer to the browser&#39;s default. But this is not ideal, because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Browser default policies are either &lt;code&gt;no-referrer-when-downgrade&lt;/code&gt;,
&lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt;, or stricter—depending on the browser and mode
(private/incognito). So your website won&#39;t behave predictably across browsers.&lt;/li&gt;
&lt;li&gt;Browsers are adopting stricter defaults such as &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt; and mechanisms
such as &lt;a href=&quot;https://github.com/privacycg/proposals/issues/13&quot; rel=&quot;noopener&quot;&gt;referrer trimming&lt;/a&gt; for cross-origin
requests. Explicitly opting into a privacy-enhancing policy before browser defaults change gives
you control and helps you run tests as you see fit.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;why-strict-origin-when-cross-origin-or-stricter&quot;&gt;Why &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt; (or stricter)? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#why-strict-origin-when-cross-origin-or-stricter&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You need a policy that is secure, privacy-enhancing, and useful—what &amp;quot;useful&amp;quot; means depends on what
you want from the referrer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Secure&lt;/strong&gt;: if your website uses HTTPS (&lt;a href=&quot;https://web.dev/why-https-matters/&quot;&gt;if not, make it a
priority&lt;/a&gt;), you don&#39;t want your website&#39;s URLs to leak in
non-HTTPS requests. Since anyone on the network can see these, this would expose your users to
person-in-the-middle-attacks. The policies &lt;code&gt;no-referrer-when-downgrade&lt;/code&gt;,
&lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt;, &lt;code&gt;no-referrer&lt;/code&gt; and &lt;code&gt;strict-origin&lt;/code&gt; solve this problem.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Privacy-enhancing&lt;/strong&gt;: for a cross-origin request, &lt;code&gt;no-referrer-when-downgrade&lt;/code&gt; shares the full
URL—this is not privacy-enhancing. &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt; and &lt;code&gt;strict-origin&lt;/code&gt; only
share the origin, and &lt;code&gt;no-referrer&lt;/code&gt; shares nothing at all. This leaves you with
&lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt;, &lt;code&gt;strict-origin&lt;/code&gt;, and &lt;code&gt;no-referrer&lt;/code&gt; as privacy-enhancing
options.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Useful&lt;/strong&gt;: &lt;code&gt;no-referrer&lt;/code&gt; and &lt;code&gt;strict-origin&lt;/code&gt; never share the full URL, even for same-origin
requests—so if you need this, &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt; is a better option.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of this means that &lt;strong&gt;&lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt;&lt;/strong&gt; is generally a sensible choice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example: Setting a &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt; policy:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;index.html&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;referrer&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;strict-origin-when-cross-origin&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Or server-side, for example in Express:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; helmet &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;helmet&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;helmet&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;referrerPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;policy&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;strict-origin-when-cross-origin&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h3 id=&quot;what-if-strict-origin-when-cross-origin-or-stricter-doesnt-accommodate-all-your-use-cases&quot;&gt;What if &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt; (or stricter) doesn&#39;t accommodate all your use cases? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#what-if-strict-origin-when-cross-origin-or-stricter-doesnt-accommodate-all-your-use-cases&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In this case, take a &lt;strong&gt;progressive approach&lt;/strong&gt;: set a protective policy like
&lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt; for your website and if need be, a more permissive policy for
specific requests or HTML elements.&lt;/p&gt;
&lt;h3 id=&quot;example-element-level-policy&quot;&gt;Example: element-level policy &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#example-element-level-policy&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;index.html&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- document-level policy: strict-origin-when-cross-origin --&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;referrer&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;strict-origin-when-cross-origin&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;      &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- policy on this &amp;lt;a&gt; element: no-referrer-when-downgrade --&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;mark class=&quot;highlight-line highlight-line-active&quot;&gt;      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;…&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;…&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;referrerpolicy&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;no-referrer-when-downgrade&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/mark&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Note that Safari/WebKit may cap &lt;code&gt;document.referrer&lt;/code&gt; or the &lt;code&gt;Referer&lt;/code&gt; header for
&lt;a href=&quot;https://web.dev/same-site-same-origin/#same-site-cross-site&quot;&gt;cross-site&lt;/a&gt; requests.
See &lt;a href=&quot;https://webkit.org/blog/10218/full-third-party-cookie-blocking-and-more/&quot; rel=&quot;noopener&quot;&gt;details&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;example-request-level-policy&quot;&gt;Example: request-level policy &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#example-request-level-policy&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;script.js&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;referrerPolicy&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;no-referrer-when-downgrade&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h3 id=&quot;what-else-should-you-consider&quot;&gt;What else should you consider? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#what-else-should-you-consider&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Your policy should depend on your website and use cases—this is up to you, your team, and your
company. If some URLs contain identifying or sensitive data, set a protective policy.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-warn-bg color-state-warn-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block color-state-warn-text&quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;currentColor&quot; role=&quot;img&quot; aria-label=&quot;Warning sign&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;   &lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M23 21L12 2 1 21h22zm-12-3v-2h2v2h-2zm0-4h2v-4h-2v4z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Warning&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; Data that might not look sensitive to you can be sensitive for your users, or is simply not data they want or expect to silently leak cross-origin. &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;using-the-referrer-from-incoming-requests-best-practices&quot;&gt;Using the referrer from incoming requests: best practices &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#using-the-referrer-from-incoming-requests-best-practices&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;what-to-do-if-your-sites-functionality-uses-the-referrer-url-of-incoming-requests&quot;&gt;What to do if your site&#39;s functionality uses the referrer URL of incoming requests? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#what-to-do-if-your-sites-functionality-uses-the-referrer-url-of-incoming-requests&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;h4 id=&quot;protect-users-data&quot;&gt;Protect users&#39; data &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#protect-users-data&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;Referer&lt;/code&gt; may contain private, personal, or identifying data—so make sure you treat it as such.&lt;/p&gt;
&lt;h4 id=&quot;keep-in-mind-that-the-referer-you-receive-may-change&quot;&gt;Keep in mind that the &lt;code&gt;Referer&lt;/code&gt; you receive may change &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#keep-in-mind-that-the-referer-you-receive-may-change&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Using the referrer from incoming cross-origin requests has a few limitations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you have no control over the request emitter&#39;s implementation, you can&#39;t make assumptions about
the &lt;code&gt;Referer&lt;/code&gt; header (and &lt;code&gt;document.referrer&lt;/code&gt;) you receive. The request emitter may decide anytime
to switch to a &lt;code&gt;no-referrer&lt;/code&gt; policy, or more generally to a stricter policy than what they used
before—meaning you&#39;ll get less data via the &lt;code&gt;Referer&lt;/code&gt; than you used to.&lt;/li&gt;
&lt;li&gt;Browsers are increasingly using the Referrer-Policy &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt; by default.
This means that you may now receive only the origin (instead of full referrer URL) in incoming
cross-origin requests, if the site that sends these has no policy set.&lt;/li&gt;
&lt;li&gt;Browsers may change the way they manage &lt;code&gt;Referer&lt;/code&gt;; for example, in the future, they may decide to
always trim referrers to origins in cross-origin subresource requests, in order to protect user
privacy.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Referer&lt;/code&gt; header (and &lt;code&gt;document.referrer&lt;/code&gt;) may contain more data than you need, for example a
full URL when you only want to know if the request is cross-origin.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;alternatives-to-referer&quot;&gt;Alternatives to &lt;code&gt;Referer&lt;/code&gt; &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#alternatives-to-referer&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;You may need to consider alternatives if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An essential functionality of your site uses the referrer URL of incoming cross-origin requests;&lt;/li&gt;
&lt;li&gt;And/or if your site is not receiving anymore the part of the referrer URL it needs in a
cross-origin request. This happens when the request emitter changed their policy or when they have
no policy set and the browser default&#39;s policy changed (like in &lt;a href=&quot;https://developers.google.com/web/updates/2020/07/referrer-policy-new-chrome-default&quot; rel=&quot;noopener&quot;&gt;Chrome
85&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To define alternatives, analyze first what part of the referrer you&#39;re using.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you only need the origin (&lt;code&gt;https://site-one.example&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you&#39;re using the referrer in a script that has top-level access to the page,
&lt;code&gt;window.location.origin&lt;/code&gt; is an alternative.&lt;/li&gt;
&lt;li&gt;If available, headers like
&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Origin&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;Origin&lt;/code&gt;&lt;/a&gt; and
&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Sec-Fetch-Site&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;Sec-Fetch-Site&lt;/code&gt;&lt;/a&gt; give
you the &lt;code&gt;Origin&lt;/code&gt; or describe whether the request is cross-origin, which may be exactly what you need.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;If you need other elements of the URL (path, query parameters…):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Request parameters may address your use case and this saves you the work of parsing the
referrer.&lt;/li&gt;
&lt;li&gt;If you&#39;re using the referrer in a script that has top-level access to the page,
&lt;code&gt;window.location.pathname&lt;/code&gt; may be an alternative. Extract only the path section of the URL and
pass it on as an argument, so any potentially sensitive information in the URL parameters isn&#39;t
passed on.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;If you can&#39;t use these alternatives:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Check if your systems can be changed to expect the request emitter (&lt;code&gt;site-one.example&lt;/code&gt;) to
explicitly set the information you need in a configuration of some sort. Pro: more explicit, more
privacy-preserving for &lt;code&gt;site-one.example&lt;/code&gt; users, more future-proof. Con: potentially more work
from your side or for your system&#39;s users.&lt;/li&gt;
&lt;li&gt;Check whether the site that emits the requests may agree to set a per-element or per-request
Referrer-Policy of &lt;code&gt;no-referrer-when-downgrade&lt;/code&gt;. Con: potentially less privacy-preserving for
&lt;code&gt;site-one.example&lt;/code&gt; users, potentially not supported in all browsers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;cross-site-request-forgery-csrf-protection&quot;&gt;Cross-Site Request Forgery (CSRF) protection &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#cross-site-request-forgery-csrf-protection&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Note that a request emitter can always decide not to send the referrer by setting a &lt;code&gt;no-referrer&lt;/code&gt;
policy (and a malicious actor could even spoof the referrer).&lt;/p&gt;
&lt;p&gt;Use &lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#token-based-mitigation&quot; rel=&quot;noopener&quot;&gt;CSRF
tokens&lt;/a&gt;
as your primary protection. For extra protection, use
&lt;a href=&quot;https://web.dev/samesite-cookie-recipes/#%22unsafe%22-requests-across-sites&quot;&gt;SameSite&lt;/a&gt;—and instead
of &lt;code&gt;Referer&lt;/code&gt;, use headers such as
&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Origin&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;Origin&lt;/code&gt;&lt;/a&gt; (available on POST and
CORS requests) and
&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Sec-Fetch-Site&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;Sec-Fetch-Site&lt;/code&gt;&lt;/a&gt; (if
available).&lt;/p&gt;
&lt;h3 id=&quot;logging&quot;&gt;Logging &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#logging&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Make sure to protect users&#39; personal or sensitive data that may be in the &lt;code&gt;Referer&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you&#39;re only using the origin, check if the
&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Origin&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;Origin&lt;/code&gt;&lt;/a&gt; header could be an
alternative. This may give you the information that you need for debugging purposes in a simpler way
and without needing to parse the referrer.&lt;/p&gt;
&lt;h3 id=&quot;payments&quot;&gt;Payments &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#payments&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Payment providers may rely on the &lt;code&gt;Referer&lt;/code&gt; header of incoming requests for security checks.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The user clicks a &lt;strong&gt;Buy&lt;/strong&gt; button on &lt;code&gt;online-shop.example/cart/checkout&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;online-shop.example&lt;/code&gt; redirects to &lt;code&gt;payment-provider.example&lt;/code&gt; to manage the transaction.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;payment-provider.example&lt;/code&gt; checks the &lt;code&gt;Referer&lt;/code&gt; of this request against a list of allowed
&lt;code&gt;Referer&lt;/code&gt; values set up by the merchants. If it doesn&#39;t match any entry in the list,
&lt;code&gt;payment-provider.example&lt;/code&gt; rejects the request. If it does match, the user can proceed to the
transaction.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;best-practices-for-payment-flow-security-checks&quot;&gt;Best practices for payment flow security checks &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#best-practices-for-payment-flow-security-checks&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Summary: as a payment provider, you can use the &lt;code&gt;Referer&lt;/code&gt; as a basic check
against naive attacks—but you should absolutely have another, more
reliable verification method in place.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Referer&lt;/code&gt; header alone isn&#39;t a reliable basis for a check: the requesting site, whether they&#39;re
a legitimate merchant or not, can set a &lt;code&gt;no-referrer&lt;/code&gt; policy which will make the &lt;code&gt;Referer&lt;/code&gt;
information unavailable to the payment provider. However, as a payment provider, looking at the
&lt;code&gt;Referer&lt;/code&gt; may help you catch naive attackers who did not set a &lt;code&gt;no-referrer&lt;/code&gt; policy. So you can
decide to use the &lt;code&gt;Referer&lt;/code&gt; as a first basic check. If you do so:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Do not expect the &lt;code&gt;Referer&lt;/code&gt; to always be present; and if it&#39;s present, only check against the
piece of data it will include at the minimum: the origin&lt;/strong&gt;. When setting the list of allowed
&lt;code&gt;Referer&lt;/code&gt; values, make sure that no path is included, but only the origin. Example: the allowed
&lt;code&gt;Referer&lt;/code&gt; values for &lt;code&gt;online-shop.example&lt;/code&gt; should be &lt;code&gt;online-shop.example&lt;/code&gt;, not
&lt;code&gt;online-shop.example/cart/checkout&lt;/code&gt;. Why? Because by expecting either no &lt;code&gt;Referer&lt;/code&gt; at all or a
&lt;code&gt;Referer&lt;/code&gt; value that is the origin of the requesting website, you prevent unexpected errors since
you&#39;re &lt;strong&gt;not making assumptions about the &lt;code&gt;Referrer-Policy&lt;/code&gt;&lt;/strong&gt; your merchant has set or about the
browser&#39;s behavior if the merchant has no policy set. Both the site and the browser could strip
the &lt;code&gt;Referer&lt;/code&gt; sent in the incoming request to only the origin or not send the &lt;code&gt;Referer&lt;/code&gt; at all.&lt;/li&gt;
&lt;li&gt;If the &lt;code&gt;Referer&lt;/code&gt; is absent or if it&#39;s present and your basic &lt;code&gt;Referer&lt;/code&gt; origin check was
successful: you can move onto your other, more reliable verification method (see below).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What is a more reliable verification method?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One reliable verification method is to let the requester &lt;strong&gt;hash the request parameters&lt;/strong&gt; together
with a unique key. As a payment provider, you can then &lt;strong&gt;calculate the same hash on your side&lt;/strong&gt; and
only accept the request if it matches your calculation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What happens to the &lt;code&gt;Referer&lt;/code&gt; when an HTTP merchant site with no referrer policy redirects to an
HTTPS payment provider?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;No &lt;code&gt;Referer&lt;/code&gt; will be visible in the request to the HTTPS payment provider, because &lt;a href=&quot;https://web.dev/referrer-best-practices/#default-referrer-policies-in-browsers&quot;&gt;most
browsers&lt;/a&gt; use &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt; or
&lt;code&gt;no-referrer-when-downgrade&lt;/code&gt; by default when a website has no policy set. Also note that &lt;a href=&quot;https://developers.google.com/web/updates/2020/07/referrer-policy-new-chrome-default&quot; rel=&quot;noopener&quot;&gt;Chrome&#39;s
change to a new default
policy&lt;/a&gt; won&#39;t
change this behaviour.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt;  If your website uses HTTP, &lt;a href=&quot;https://web.dev/why-https-matters/&quot;&gt;migrate to HTTPS&lt;/a&gt;.  &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A protective referrer policy is a great way to give your users more privacy.&lt;/p&gt;
&lt;p&gt;To learn more about different techniques to protect your users, check out web.dev&#39;s &lt;a href=&quot;https://web.dev/secure/&quot;&gt;Safe and
secure&lt;/a&gt; collection!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;With many thanks for contributions and feedback to all reviewers - especially Kaustubha Govind,
David Van Cleve, Mike West, Sam Dutton, Rowan Merewood, Jxck and Kayce Basques.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;resources&quot;&gt;Resources &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/referrer-best-practices/#resources&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/same-site-same-origin/&quot;&gt;Understanding &amp;quot;same-site&amp;quot; and &amp;quot;same-origin&amp;quot;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://scotthelme.co.uk/a-new-security-header-referrer-policy/&quot; rel=&quot;noopener&quot;&gt;A new security header: Referrer Policy
(2017)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-Policy&quot; rel=&quot;noopener&quot;&gt;Referrer-Policy on
MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/Security/Referer_header:_privacy_and_security_concerns&quot; rel=&quot;noopener&quot;&gt;Referer header: privacy and security concerns on
MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://groups.google.com/a/chromium.org/d/msg/blink-dev/aBtuQUga1Tk/n4BLwof4DgAJ&quot; rel=&quot;noopener&quot;&gt;Chrome change: Blink intent to
implement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/lqFuqwZDDR8&quot; rel=&quot;noopener&quot;&gt;Chrome change: Blink intent to
ship&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.chromestatus.com/feature/6251880185331712&quot; rel=&quot;noopener&quot;&gt;Chrome change: status entry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.chromium.org/2020/07/chrome-85-upload-streaming-human.html&quot; rel=&quot;noopener&quot;&gt;Chrome change: 85 beta
blogpost&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/privacycg/proposals/issues/13&quot; rel=&quot;noopener&quot;&gt;Referrer trimming GitHub thread: what different browsers
do&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-delivery&quot; rel=&quot;noopener&quot;&gt;Referrer-Policy Spec&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    <author>
      <name>Maud Nalpas</name>
    </author>
  </entry>
</feed>
