I host my site on Netlify, which is a great service. It makes it really easy to add custom headers via either a
_headers file or the
netlify.toml config file.
A long time ago, I added some security-related headers to my site:
[[headers]] for = "/*" [headers.values] x-frame-options = "DENY" x-xss-protection = "1; mode=block"
I used the
/* pattern to add these headers to every request coming from Netlify, to make sure I'd covered all my bases. Nobody puts
Baby in the corner my website in an iframe!
Unneeded HTTP Headers
no-html-only-headerswarns against responding with HTTP headers that are not needed for non-HTML (or non-XML) resources
Interesting! It turns out that a lot of the security-related headers only need to be sent at the document level (HTML responses), not on responses containing images, fonts, scripts and so on. Sending these headers for non-HTML responses does nothing other than waste bytes and make our responses that little bit larger.
Ah, not that fast… Once you've set a header in Netlify with a general path pattern like
/* there doesn't seem to be an easy way to undo those headers later on.
Normally in this situation we'd use a more specific rule than
/*, but that's hard to do with HTML responses.
There's a big Netlify support thread about this where one piece of advice is to use a rule like
/*.html, but that's not much use as the majority of us like our visitors to access our pages using URLs like
https://wolstenhol.me/ rather than
I was getting ready to give up until I remembered that that support thread pre-dated Netlify Edge Functions…
Edge Functions are small scripts that run on 'the edge' – in this case Netlify's CDN infrastructure. They allow us to do the sort of things that you'd need to write Nginx or Apache config to do in the past, and they allow us to do that for static sites on free hosting like Netlify. They let us programmatically intercept network requests coming from our website and going to a user, and they let us modify them, which is exactly what we need to do here.
Let's use a Netlify Edge Function to remove those HTML-only security headers if our function catches a non-HTML response being sent to one of our visitors.
First of all, in our
netlify.toml file, let's configure Netlify to let it know about the function we are about to create:
[[edge_functions]] path = "/*" function = "strip-non-html-headers"
Read through the comments in the function, and let me know if you have any questions in the comments:
You can use a tool like curl (
curl -I https://example.com/your-file-name.jpg) or the Network tab in your browser's developer tools to validate that a header like
x-xss-protection is now missing from something like a font file or an image.
This is a great example of the power and flexibility that edge functions/edge workers give developers. Rather than wait for Netlify to add a 'override previously set headers' option to their configuration systems we can instead use some standard web APIs (the
Response interface that we are using in the Edge Function is part of the Fetch family of APIs) to programmatically alter the response of the CDN ourselves.