Security Headers using <meta>

by Saptak S published on

Various HTTP headers are sent between the user and the server of a website in the request-response cycle. Some of these HTTP response headers sent by the server to the browser help enhance the security and privacy of the website's users. These sets of headers are often commonly known as security headers. These can range anywhere from forcing the browser to always visit your website through https (Strict-Transport-Security) to preventing Cross Site Scripting and Clickjacking attacks on the website's user. You can check how well the security headers are set for your website using securityheaders.com.

These security headers (or any HTTP response headers) are usually set through the server configuration, i.e., nginx config, Apache config, or similar. However, in certain scenarios, like hosting a static website using GitHub Pages, the developers don't have a lot of control over the HTTP response headers. In such scenarios, the ability to add security headers declaratively through HTML itself can be helpful. The <meta> HTML tag helps in setting up two such security headers - Referrer Policy and Content Security Policy.

Referrer Policy using <meta name>

One of the most common ways a <meta> HTML tag is used is with a name and content attribute. The HTML standard allows the <meta> element to have name="referrer" that gets delivered as a Referrer-Policy header. The content attribute defines the value of the Referrer-Policy header. For example,

<meta name="referrer" content="no-referrer">

will create the HTTP response header: Referrer-Policy: no-referrer. This will ensure that any visitor of your website, if they click on a link in your website, the Referer information of the visitor is not shared with the link. So the visited link will not know which previous URL the user has clicked the link from and helps protect the privacy of the user. There are a few different Referrer-Policy values that allow varied levels of information to be shared in the Referer header to the navigating link or subresources.

There are a few other ways that HTML allows setting up Referrer-Policy on individual links -

  • referrerpolicy attribute
  • rel="noreferrer".

The referrerpolicy attribute can be used like this:

<a href="http://example.com" referrerpolicy="origin">

This means when the user clicks on this particular anchor tag, only the origin information of the current website is sent to https://example.com. The referrerpolicy attribute can also be set on elements like <img> or <iframe> to control their Referrer-Policy.

Adding rel="noreferrer" to an anchor tag ensures that no referrer information of the current webpage is sent to the visiting webpage.

Content Security Policy using http-equiv

Another way of using <meta> tags is using the http-equiv attribute instead of the name attribute. The http-equiv attribute is used by servers to create various HTTP response headers. One such header is the Content-Security-Policy. Content Security Policy (CSP) is used to determine whether a content being loaded in the page is from a trusted source or not. CSP is versatile in controlling all different kinds of content from which script gets loaded to what a form target can be set to through its various directives, and hence protects your users from a wide range of attacks such as clickjacking attacks and cross-site scripting attacks.

The way to add a CSP using http-equiv is:

<meta http-equiv="Content-Security-Policy" content="script-src 'self'; form-action 'none'">

The above line creates an equivalent HTTP response header

Content-Security-Policy: "script-src 'self'; form-action 'none';"

The script-src directive in the above example ensures that URLs loaded in <script> element are from the same origin as the current webpage, and disallows any inline-scripts or script URLs from other websites. The form-action directive ensures that no form submission is allowed from the current webpage. These both help in preventing cross-site scripting attacks.

Caution: One very important thing to note is using this method, report-uri, frame-ancestors, and sandbox directives cannot be set for a CSP. They are removed from the policy before the policy is enforced if they are added using <meta> tag.

Invalid security headers in <meta>

One of the issues with adding security headers using <meta> tag is developers often assume that any of the HTTP security response headers can be added through this method. This is not true and can often lead to a false sense of security since any invalid security header will be ignored by the browser. It is important to remember that even though http-equiv helps in defining HTTP response headers, it is an enumerated attribute. Hence, it can only help in delivering a fixed set of HTTP header and any other HTTP header that is set using this method will be ignored.

Table showing security headers used in meta tags as per Web Almanac 2022 security chapter. 3.11% websites in desktop and 2.60% websites in mobile use meta tag to set Referrer-Policy. 0.55% websites in desktop and 0.47% websites in mobile use meta tag to set CSP. 0.08% websites in desktop and 0.06% websites in mobile use meta tag to set not allowed security headers.

In Web Almanac 2022, it was seen that 0.08% of the websites visited over the desktop had an invalid security header. So in conclusion, delivering Referrer-Policy and Content-Security-Policy security headers using the <meta> element can be really useful and protect your user's security and privacy, but it is also important to be aware of the limitations of this method.

Further Reading:

About Saptak S

Saptak S. is a human rights centered web developer, focusing on usability, security, privacy and accessibility topics in web development. He works as a web development contractor. He is a contributor and maintainer of various different open source projects like The A11Y Project, OnionShare and Wagtail. He is also the author of the Security and Accessibility chapter of Web Almanac 2022. One can find him blogging at saptaks.blog.

Website/blog: saptaks.website
Mastodon: toots.dgplug.org/@saptaks