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
attributerel="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.
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:
- Web Almanac 2022 Security: Preventing attacks using <meta>
- HTTP Security Response Headers Cheat Sheet
- HTML spec: 4.2.5.3 Pragma directives
- Content Security Policy Cheat Sheet
- Referer and Referrer-Policy best practices
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