Security headers on Netlify
Clear the header findings on a Netlify site with no server of your own. Set security headers in a _headers file or in netlify.toml, cited to the Netlify docs.
Netlify reads custom response headers from two places: a file named _headers or the netlify.toml configuration file.
The _headers file is plain text in the publish directory. A path goes on one line with its headers indented under it.
_headers
/*
X-Content-Type-Options: nosniff In netlify.toml each rule is a [[headers]] table, with the path in for and the headers under [headers.values].
netlify.toml
[[headers]]
for = "/*"
[headers.values]
X-Content-Type-Options = "nosniff" The examples below use the _headers form. In netlify.toml the same name and value go under [headers.values]. If a build step writes the site, the _headers file has to end up in the folder Netlify deploys. Custom headers apply only to files Netlify serves itself. A proxied response gets none of them. Neither does a response from a function or an edge function, such as a server-rendered page, so that code has to send its own headers. Headers set either way apply to every build and every deploy context alike. Netlify ignores custom values for a short list of headers it sets itself. None of the six headers on this page is on that list.
Source: Netlify docs: custom headers
Strict-Transport-Security (HSTS)
Add Strict-Transport-Security under the path.
_headers
/*
Strict-Transport-Security: max-age=31536000; includeSubDomains Add includeSubDomains only when every subdomain answers over HTTPS.
Source: Netlify docs: custom headers
Content-Security-Policy (CSP)
Start with the report-only header under the path.
_headers
/*
Content-Security-Policy-Report-Only: default-src 'self' Once the reports show the policy breaks nothing, rename the header to Content-Security-Policy to enforce it.
_headers
/*
Content-Security-Policy: default-src 'self' Report-only mode shows what a policy would stop without stopping it. The CSP fix guide linked below builds a working policy that way before it is enforced.
Source: Netlify docs: custom headers
X-Frame-Options
Add X-Frame-Options under the path. Netlify uses this header for its own _headers example.
_headers
/*
X-Frame-Options: SAMEORIGIN SAMEORIGIN lets only your own pages frame the site. DENY refuses every frame.
Source: Netlify docs: custom headers
X-Content-Type-Options
Keep X-Content-Type-Options with the value nosniff under the path.
_headers
/*
X-Content-Type-Options: nosniff Source: Netlify docs: custom headers
Referrer-Policy
Add Referrer-Policy under the path.
_headers
/*
Referrer-Policy: strict-origin-when-cross-origin Source: Netlify docs: custom headers
Permissions-Policy
Add Permissions-Policy under the path.
_headers
/*
Permissions-Policy: camera=(), microphone=(), geolocation=() Each feature with an empty list () is switched off for every origin. Name the features the site does not use.
Source: Netlify docs: custom headers
How to check it
After the next deploy, read the headers the live site sends with curl -I https://www.example.com/ or in the network panel of your browser developer tools. The free check gives an A to F grade and shows how to fix the first two findings in a few seconds, with no sign-up. Run the free check.
More on each header: how to fix a missing HSTS header, how to fix a missing Content-Security-Policy header, how to fix a missing X-Frame-Options header and the security headers guide.
The same headers on other platforms: Vercel, WordPress and Webflow.