Adding recommended security headers is one of the easiest and fastest ways to improve the security level of a web application. You can find a great number of articles on the subject of security headers, but it is worth approaching them with some caution, because like everything in the world of IT and security, this area is also subject to constant change. In this article, I would like to take a closer look at the security headers that are currently recognized by the OWASP organization as the standard in this area, and mention those that should no longer be used for several years. But let's start from the beginning, that is, a reminder of what HTTP response headers are.
What are HTTP response headers?
HTTP communication involves sending a request to a server, which then generates and sends a response to that request. For example, to view this article, the browser makes an HTTP GET request and in response receives an HTML page with the content of the article and additional information in the HTTP response headers. By default, the HTTP header information is not presented by the browser, but is used by the browser, for example, to display the page correctly and to configure security when displaying this page.
To see the response headers in question, just use the developer tools of any browser. If you're using the Chrome browser, you need to go to the Chrome menu (three dots in the right corner) and then select More Tools > Developer Tools. You can see the response headers after selecting the request, under Response Headers.
The returned response headers have different roles, in this article we are interested in headers related to security configuration.
What security headers should be used and where to look for up-to-date information on this topic?
The current standard for security headers is set by the OWASP organization, and you can look for information on this topic in its many documents and projects such as the OWASP Secure Headers Project, OWASP ASVS and OWASP Cheat Sheet Series.
In this article, I will present, in my opinion, the most relevant security headers, the use of which will make it easy to significantly increase the security of a web application. These headers are on the recommended list according to the OWASP Secure Headers Project and OWASP ASVS, the standard for securing and testing web applications (version 4.0.3 current February 2022 chapter on configuration - V14 Configuration, in section V14.4 HTTP Security Headers).
Content-Type and X-Content-Type-Options headers
The Content-Type header is intended to inform the browser about the MIME type of the document returned in the HTTP response and its encoding, so that the browser can interpret and display it correctly. This header should be returned for every resource, that is, in every response to a request. In some cases, if the type does not match the returned document, the browser may try to guess the document type and interpret correctly to the guessed type ignoring the information sent in the Content-Type header.
A safeguard against such a problem is the X-Content-Type-Options header. Its configuration is simple because it can accept only one recommended value, i.e. X-Content-Type-Options: nosniff.
The purpose of the security is to avoid a situation where the browser will convert an inherently non-executable document type into an executable document as a result of guessing its content (MIME type).
HTTP Strict Transport Security header
The return of the HSTS header informs HSTS-supporting browsers (currently all modern browsers) that they can only connect using an encrypted connection, or HTTPS.
The header was created to ensure the use of the encrypted protocol even in the case of configuration problems and implementation errors (e.g., misdirects to the post-http address resulting from hardcoded addresses). On the browser's side is to ensure that a connection is never made using the unencrypted HTTP protocol. This is accomplished by automatically changing http to https.
In addition, the use of the header disables easy-to-accept certificate security warnings, e.g. invalid or invalid certificate, which are sometimes accepted without careful analysis.
The following configuration of the header setting it to two years (max-age) is recommended: Strict-Transport-Security: max-age=63072000; includeSubDomains; preload. The header should be configured for the main domain, and the domain should be added to the list of HSTS Preload domains, a list of domains using the HSTS header.
X-Frame-Options header or CSP frame-ancestors directive
The X-Frame-Options header protects against clickjacking, or clickjacking attacks. The header tells the browser whether the application can be displayed in a frame on another domain. Typically, in a Clickjacking attack, there is an invisible frame containing the vulnerable application in the place indicated to the user to click on another domain. By clicking on the link, the user unknowingly performs some action in the vulnerable application. To protect an application from this type of attack, set a header with the value X-Frame-Options: DENY (no frame allowed) or X-Frame-Options: SAMEORIGIN (the frame is from the same domain). The header is still used but is now being supplanted by the CSP header and the CSP frame-ancestors directive. A setting in the form of Content-Security-Policy: frame-ancestors 'none'; is practically equivalent to DENY, while a setting of Content-Security-Policy: frame-ancestors 'self'; options SAMEORIGIN (more information on the slight differences can be found here. If both headers are used, it is the CSP directive that will be used.
The X-XSS-Protection header and why we no longer use it
The X-XSS-Protection header was one of the recommended protections against Reflected XSS attacks until a few years ago. Browsers (with the exception of Firefox) had a built-in filter designed to catch Reflected XSS attacks by verifying that no HTML or JS fragments appear in the HTTP request, which later appear unchanged in the response. The header has a rather interesting history, as many times security researchers have shown that it can be used to introduce vulnerabilities where none existed, which doesn't speak too well of such security ☺. Due to the appearance of such problems with browsers' anti-XSS filters, over time browsers began to move away from this protection. Chrome and Edge withdrew the filters from their browsers several years ago.
Currently, browsers' support for the X-XSS-Protection header looks as follows(source):
As you can see, most popular browsers have withdrawn support for this header, the exceptions being Safari and IE. The caniuse.com service indicates that the header is supported by 6.87% of browsers. These are Safari and IE browsers or outdated versions of other browsers. What looking at the usage statistics presents itself as follows:
Despite the lack of support from most modern browsers, the header is still frequently used by web applications. Shodan for the query "x-xss-protection:1" country: "PL" returns more than 122 thousand results, and among the applications using the header with the filter enabled are, among others, popular banking applications. It also happens that I come across security test reports containing outdated recommendations for the use of this header. Therefore, if your test checklists still point to this header it is worth updating them.
In the section on the X-XSS-Protection header of the OWASP Cheat Sheet Series document, we have a recommendation to set it with the value X-XSS-Protection: 0, i.e. disabling browser filters. Such exclusion is beneficial for older versions of browsers that still support this header (in particular, it will be beneficial for users of old versions of browsers with XSS filter enabled by default).
Below is the exact wording of the recommendation:
" The X-XSS-Protection header has been deprecated by modern browsers and its use can introduce additional security issues on the client side. As such, it is recommended to set the header as X-XSS-Protection: 0 in order to disable the XSS Auditor, and not allow it to take the default behavior of the browser handling the response."
The authors of the document took the approach that as long as some users can still use browsers that support the X-XSS-Protection header, it is worth configuring the header to disable the operation of their anti-XSS filters to avoid possible vulnerabilities introduced by bugs in the implementation of such filters. Currently, this is the most sensible approach, in the future when all browsers drop support for this header it will be possible to abandon it.
If it is clear from the specifics of the application that users are using current versions of specific browsers that do not support the header (e.g. internal applications) it seems sensible to abandon it now.
Verification of header configuration
Verification in terms of security headers is simple, just display HTTP response headers, for example, using the browser's developer tools. Such a simple test can be performed, for example, while performing other tests. Verification of response headers is also performed by automatic scanners, e.g. OWASP ZAP, Burp Suite. If the application under test is accessible from the Internet, the Security Headers tool can be used to verify the headers. After entering the address of our application and performing a scan, we get an overall assessment of the correctness of the header configuration (in terms of completeness and header configuration). The tool tells us which headers are missing and with what value we should set them.
Example results of the scan one of the better configurations graded A, and then no header configuration resulting in a grade of F.
One simple way to increase the overall security level of a web application is to use security headers. It is important to remember to configure them properly in accordance with current recommendations in this regard. The security headers mentioned in the article are only a part of the headers that should be used in web applications. For full recommendations in this regard, I refer you to the aforementioned OWASP Secure Headers Project, OWASP ASVS and OWASP Cheat Sheet Series documents.