Required HTTP headers

Our customers at Fastly love to manipulate HTTP headers. Picking the right combination of headlines is one of the best things you can do to secure your site and make a significant contribution to its performance.

Most developers are aware of important and relevant HTTP headers. The most famous are Content-Type and Content-Length , which are almost universal headers. But recently, headers such as Content-Security-Policy and Strict-Transport-Security have begun to be used to increase security, and for better performance - Link rel=preload . Despite widespread support in browsers, few use them.

In the previous article, we looked at unnecessary headers. Now we will understand what headers really should be configured for your site.

homework


There are several services on the Internet that will analyze your website and advise which titles to add. I looked at Mozilla's securityheaders.io and Observatory to supplement my own knowledge and data from the Fastly network.

What headers should be on your site


So, what main headers should be in the responses of your servers? Most are responsible for improving security:

Content-Security-Policy . Acts like a firewall in the browser. If your site is compromised, it helps limit damage by preventing connections to unapproved hosts. Very important headline. If you do not have it, you need to enable it.

Referrer-Policy . Sets the level of detail to include in the Referer header when leaving the page. Helps prevent data leaks to sites where links go. Highly recommended.

Strict-Transport-Security . Prevents any attempt to connect to the site via normal HTTP. Helps to stop MiTM-attacks and increases the security of the site. Also highly recommended.

X-XSS-Protection . Prevents some forms of cross-site scripting attacks, preventing the execution of a script if some markup from a document in the same form is present in the request. For example, if you load a page with the address /index.html?foo=<script>alert('foo');</script> , and in the source code of the page there is <script>alert('foo');</script> , the script is blocked. Nowadays, the title is largely replaced by CSP.

X-Content-Type-Options . Set the nosniff value to prevent browsers from running content that is similar to JavaScript, for which the correct content type is not set. Prevents MIME blending attacks, and recently Chrome is used to activate site isolation . Over time, it becomes less important due to the improved behavior of browsers by default, but is still still among the best practices.

CORS . Cross-Origin Resource Sharing headers allow you to download a script URL from another source. This is an optional title. Headers of this type are resolving, not prohibiting, so their absence gives the maximum level of security.

Others are designed for performance:

Timing-Allow-Origin . Gives monitoring tools access to query timing data. This is in many respects valuable information, it allows you to greatly improve the quality of analytics like Google Analytics or Speedcurve.

Link rel = preload . It tells the browser about the critical resources that should be downloaded, even if there is no immediate need for them. Use header for fonts and important CSS.

Server-timing . Provides timing information from the server, which complements the Navigation Timing API and Resource Timing API with more detailed information on the execution time of tasks on the server (for example, “how much time we spent in MySQL”). Great for monitoring performance data in combination with RUM Beacon tools.

Let's take a closer look at some of them.

Content Security Policy: Keep it within


Although Content-Security-Policy is one of the most important headlines, it is also one of the most verbose. The largest CSP header I found in HTTPArchive was 10 KB. Ten kilobytes . For a single header value. Worse: while response bodies can be streamed, headers are buffered by most servers and proxy servers and transmitted only after completion. Compressing HTTP / 2 helps a little to remember them between requests, but this does not mean that the 10 KB header is normal.

In addition, filling out the entire first packet of your answer, you can force the browser to make two hits to the server just to start receiving content . So think not only about removing unnecessary headers, but also about maximally optimizing existing ones.

Referrer-Policy


Since time immemorial (that is, in the web world since about the end of the 90s), browsers send (and incorrectly write ) the Referer header. For most of its history, it was one of the most important ways to track user movement between pages in analytics tools, as well as understand the origin of incoming traffic. However, the latter is associated with significant privacy concerns. If I click the link in the email from the email client, the site can determine my email domain. Worse, knowing the full URL from which you came, including the query arguments, may reveal the terms of your last search query or personal data, such as an email address.

You can choose several strategies from the available Referrer-Policy options, but my usual advice is “origin-when-cross-origin”, which includes a referer for all normal requests, but truncates the value only to the domain if the link goes from one domain to another . Links within your own site include a full referrer.

Server-Timing measurement on CDN edge server


Server-Timing has many nice features, and one of them is that you can add several instances to your answer - and all of them will be combined in the browser or the RUM tool. That is, if a request goes through several stages of server processing — as happens in a CDN — each stage adds its own time metrics, and they do not conflict with each other. Here's how to add Fastly metrics to a header using VCL in the Fastly service configuration:

 add resp.http.Server-Timing = fastly_info.state {", fastly;desc="Edge time";dur="} time.elapsed.msec; 

This number includes the time spent waiting for the backend, so in the normal case, all your server time metrics will be less than the Fastly number. However, if we issue a document from the Fastly cache, you will see the original time metrics from the moment the page was generated, but the Fastly number will confirm that the total loss of time is actually very small.

Server time metrics are available through the performance object in JavaScript and displayed in the Chrome Devtools network panel:



Currently, visualization of indicators at a rudimentary level. But they are working hard on this, so the user interface is likely to improve significantly in the future.

Add all the correct headers


Fastly is a good place to add all the security and performance headers. Below is what they look like together. Add this code at the stage of delivery of the request flow, changing the values ​​to those that are suitable for your website ( try not to copy-paste without checking that the values ​​are suitable for your website):

 set resp.http.Content-Security-Policy = "default-src 'self'; frame-ancestors 'self'"; set resp.http.Referer-Policy = "origin-when-cross-origin"; set resp.http.Strict-Transport-Security = "max-age=86400"; # Increase when working well in prod (a year is a common final value) set resp.http.X-XSS-Protection = "1; mode=block"; set resp.http.X-Content-Type-Options = "nosniff"; if (req.http.Origin) { # Consider checking this against an allowlist set resp.http.Access-Control-Allow-Origin = req.http.Origin; set resp.http.Access-Control-Allow-Methods = "GET,HEAD,POST,OPTIONS"; } add resp.http.Server-Timing = fastly_info.state {", fastly;desc="Edge time";dur="} time.elapsed.msec; set resp.http.Timing-Allow-Origin = "*"; set resp.http.Link = "</fonts/myfont.otf>; rel=preload; as=font"; 

The following article will look at some of the most exotic headlines that are beginning to standardize and implement in browsers.

Source: https://habr.com/ru/post/413205/


All Articles