HTTP Security Headers Update


Back in November I posted a surprisingly popular first part in a series of articles on Hardening Website Security (link). Since then I have been analysing Content Security Report (CSP) violation false-positives and expanding my knowledge on the subject, and thought an update was due.

If you haven’t yet, I recommend reading the original article first here.

Feature Policy

Before we get back into the Content Security Policy, I thought it would be worthwhile adding another header to the list: Feature-Policy.

About the Feature Policy

The Feature Policy behaves much like a Content Security Policy, in that it is used for restricting or unrestricting functionality on a website. However, where a CSP is used to control security around resources, a feature policy is used to control… well… features.

Basically, the Feature Policy is used to communicate with the client’s web browser to let it know what features the website is going to use (if any), and what sources are allowable for it.


Let’s take “camera” for example. If your website doesn’t have any need to access the client’s webcam then setting this to ‘none‘ is like telling the browser: “We don’t want access to your camera, if you get a request then just block it.

Alternatively, if you do use the camera, then setting it to ‘self‘ tells the browser to expect this request if it comes through. This has the added benefit of exerting extra control when using third party libraries so you are saying “This website may need access to your camera, but if a request comes from anywhere else, block it.“.

You can find the full list of features in Chromium’s feature policy source code, but the main ones are:

  • accelerometer
  • autoplay
  • camera
  • encrypted-media
  • fullscreen
  • geolocation
  • gyroscope
  • magnetometer
  • microphone
  • midi
  • payment
  • speaker
  • vr

You can find descriptions for each of these on the Mozilla Developer Network.

All of these features are currently opt-in, so if you aren’t using any of them then you shouldn’t need to worry about setting a feature policy. However, for future-proofing sake, you may choose to explicitly define the policy anyway.

Content Security Policy

Most of the information from my original article still stands. However, I have tweaked my recommendations a little.


The Referrer Policy defines what information should be included in the “Referer” (sic) header when clicking internal and external links on your website. This is important for your users’ security as they don’t necessarily want the next website they visit to know exactly what page they viewed on your website.

The possible values for your Referrer-Policy are shown below.

Stops the “Referer” header from being set at all.

no-referrer-when-downgrade (default)
If the security protocol remains the same between this request and the next (so the current site is served over HTTP and the next site or page is as well, or HTTPS to HTTPS), or if the request is upgraded (HTTP to HTTPS), then the current URL is sent as the “Referer”. Otherwise it is omitted.

Only send the root URL as the referrer (so “” will set “” as the referrer).

Sends the full URL as the referrer if the next request is to the same root URL (i.e. “” to “”), otherwise only the root URL is sent.

Sets the referrer to the full URL of the current request on same root URL requests only. Any non-root requests have no referrer sent.

As with “origin”, except the security protocol must remain the same or upgraded between requests. If a request goes from, for example, “” to “” then no referrer will be set.

As with “origin-when-cross-origin”, but again if the security protocol is is downgraded then no referrer will be sent.

By default the full URL is set as the referrer unless the security is being downgraded. As mentioned before, this could be considered a violation of your visitor’s trust, so I would recommend changing it. It’s a question of weighing up how valuable the referrer information is to you internally, and how much you respect your visitor’s right to not be tracked throughout the web.

Generally speaking, “strict-origin-when-cross-origin” is a good catch-all as that protects against leaking data when a connection requests get downgraded, only provides your base URL as the referrer when going to another URL, and still provides you with internal referral information for analytics.


The HTML5 <base> head tag is used to specify the base URI for all subsequent relative URLS on the page. This can lead erroneous behaviour or niche attacks, and by not setting it at all any and all URLS are allows in the <base> tag. For example:

<!-- -->
  <base href="" target="_self">
  <!-- Will link to -->
  <a href="page2.html">Link</a>

Setting the “base-uri” CSP directive to “‘self’” limits its use to the current page’s URL only. Alternatively, and perhaps more preferably, setting it to “‘none’” will disable the ability to use the tag entirely.

Like the article? Share with your friends: