Security headers every modern website owner should consider
Web security topic is a slight tangent from mobile web performance, but I believe that security is an equally overlooked topic and deserves a mention. I hope you will learn one or two unexpected browser behaviors with security impact from this article and it will motivate you to learn more. You don’t have to treat this set of HTTP headers as a security checklist, the ultimate goal is to understand what tools are available to you and how to apply them.
Preventing man-in-the-middle attacks with Strict-Transport-Security
Web is rapidly moving to HTTPs which helps to ensure that connection between user and website is secure and cannot be intercepted. Google Chrome browser even started marking HTTP websites as insecure. Establishing secure connection has a small performance hit, but overall security and privacy benefits overweigh the performance downsides. A common practice, many websites adopted, is to redirect users trying to open the HTTP version of the website to HTTPs. It’s a great non-breaking transition step, but since the first connection is still insecure, it can be intercepted and modified by malicious actors.
Script-Transfer-Security header helps to reduce this attack vector by telling the browser “this website runs HTTPs, always use HTTPs by default”. After users visit a website, the browser will remember for the max-age that all requests to the website and subdomains (includeSubDomains) should be automatically upgraded to HTTPs. The very first visit to the website can still be intercepted and preload property aims to reduce even this tiny window of vulnerability. Preload property signals to the browser that the website should be included in the global list of HTTPs by default websites maintained by Google and used by other major browser vendors. Once websites are part of this list even the very first request will be automatically upgraded to HTTPs.
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Content-Security-Policy: swiss knife of web security
Content-Security-Policy: base-uri 'self'; frame-ancestors 'none'; default-src 'self' 'unsafe-inline'
Lesser known Referrer-Policy
Did you know that once a href link is clicked the website which opens has some access to the website context (origin, path, querystring) which opened it? This is how Google Analytics knows which websites are linking to your website. This is a useful feature for improving your SEO, but in some contexts can be a security or privacy risk. Now that you are aware of this, consider if it has impact for your website and design Referrer-Policy accordingly.
X-Frame-Options: CSP for older browsers
X-Frame-Options header is still widely suggested by automated security tools, but is made obsolete by CSP frame-src directive and should only be used for controlling iframe embedding in Internet Explorer 8.
Browsers are quite flexible and tolerant to developer and user mistakes. Sometimes too tolerant and smart to their own demise. How a file should be interpreted is controlled by Content-Type header, but browsers also assume that this header might be misconfigured and tries to predict content type from the file content. This prediction can sometimes be very dangerous and lead to malicious content being executed in the user’s browser. You should just verify that Content-Type header is correctly configured on the web server and disable browser content guessing (sniffing).
Web security foundation
There are more security oriented HTTP headers to research and consider, but this list should be a strong starting point and raise your security by over 9000 if you are not using any of these headers already. As mentioned in the introduction, it is a lot more important to know and understand why these headers exist than applying all of them blindly. There might be legitimate reasons for not using these headers or selecting more permissive configuration options. It is fine as long as you understand the trade-offs you are making between security and usability.