Sven Morgenroth on Security Weekly
Invicti security researcher Sven Morgenroth joined Paul Asadoorian on Paul’s Security Weekly #652 to describe and demonstrate various HTTP headers related to security. Watch the full interview below and read on for an overview of Sven’s presentation of HTTP security headers.
What are HTTP Security Headers?
HTTP security headers are a subset of HTTP headers and are exchanged between a web client (usually a browser) and a server to specify the security-related details of HTTP communication. Some HTTP headers that are indirectly related to privacy and security can also be considered HTTP security headers. By enabling suitable headers in web applications and web server settings, you can improve the resilience of your web application against many common attacks, including cross-site scripting (XSS) and clickjacking. See our whitepaper on HTTP security headers for a detailed discussion of available headers.
How HTTP Security Headers Can Improve Web Application Security
When we talk about web application security, especially on this blog, we usually mean finding exploitable vulnerabilities and fixing them in application code. HTTP security headers provide an extra layer of security by restricting behaviors that the browser and server allow once the web application is running. In many cases, implementing the right headers is a crucial aspect of a best-practice application setup – but how do you know which ones to use?
As with other web technologies, HTTP headers come and go depending on browser vendor support. Especially in the field of security, headers that were widely supported a few years ago can already be deprecated. At the same time, completely new proposals can gain universal support in a matter of months. Keeping up with all these changes is not easy. To help you decide what to implement, Invicti checks for the presence and correctness of many HTTP security headers and provides clear information and recommendations.
The Most Important HTTP Security Headers
Let’s dive into an overview of selected headers, starting with a few of the best-known HTTP response headers.
When enabled on the server, HTTP Strict Transport Security (HSTS) enforces the use of encrypted HTTPS connections instead of plain-text HTTP communication. A typical HSTS header might be:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
This would inform the visiting web browser that the current site (including subdomains) is HTTPS-only and the browser should access it over HTTPS for the next 2 years (the
max-age value in seconds). The
preload directive indicates that the site is present on a global list of HTTPS-only sites. Preloading is intended to speed up page loads and eliminate the risk of man-in-the-middle (MITM) attacks when a site is visited for the first time.
The Content Security Policy (CSP) header is the Swiss Army knife of HTTP security headers and the recommended way to protect your websites and applications against XSS attacks. It allows you to precisely control permitted content sources and many other parameters. A basic CSP header to allow only assets from the local origin is:
Content-Security-Policy: default-src 'self'
Other directives include
img-src to specify permitted sources for scripts, CSS stylesheets, and images. For example, specifying
script-src 'self' would only allow scripts from the local origin. You can also restrict plugin sources using
plugin-types (unsupported in Firefox) or
Invicti checks if the CSP header is present.
This header was first introduced in Microsoft Internet Explorer to provide protection against cross-site scripting attacks involving HTML iframes. To prevent the current page from being loaded into any iframes, you would use:
Other supported values are
sameorigin to allow loading into iframes with the same origin and
allow-from to indicate specific URLs. This header can usually be replaced by suitable CSP directives.
Invicti checks if the X-Frame-Options header is present.
Deprecated HTTP Security Headers
Some headers were introduced as temporary fixes for specific security issues. As web technology moves on, these become deprecated, often after just a few years of browser support. Here are just two examples of deprecated headers that were intended to address specific vulnerabilities.
As the name implies, the
X-XSS-Protection: 1; mode=block
This non-standard header was intended for browsers with XSS filters and provided control of the filtering functionality. In practice, it was relatively easy to bypass or abuse, and as modern browsers no longer use XSS filtering, the header is now deprecated.
Invicti checks if you have set X-XSS-Protection for your websites.
HTTP Public Key Pinning (HPKP) was introduced in Google Chrome and Firefox as a way to prevent certificate spoofing. It was a complicated mechanism where the server presented the web client with cryptographic hashes of valid certificate public keys for future communication. A typical header would be:
Public-Key-Pins: pin-sha256="cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs="; max-age=5184000
In practice, public key pinning proved too complicated to use. If incorrectly configured, the header could completely disable website access for the time specified in the
max‑age parameter (2 months in this example). The feature was deprecated in favor of certificate transparency logs – see the
Expect-CT header below.
Other Useful HTTP Security Headers
While not as crucial as CSP and HSTS, the headers below can also help you to harden your web application.
To prevent website certificate spoofing, the
Expect-CT header can be used to indicate that only new certificates added to Certificate Transparency logs should be accepted. A typical header would be:
Expect-CT: max-age=86400, enforce, report-uri="https://example.com/report"
enforce directive, clients are instructed to refuse connections that violate Certificate Transparency policy. The optional
report-uri directive indicates a location for reporting failures.
Invicti reports missing Expect-CT headers with a Best Practice severity level.
When present in server responses, this header forces web browsers to strictly follow the MIME types specified in
Content-Type headers. This protects websites from cross-site scripting attacks that abuse MIME sniffing capabilities to supply malicious code masquerading as a non-executable MIME type. The header has just one directive:
Invicti checks if Content-Type headers are set and X-Content-Type-Options: nosniff is present.
Fetch Metadata Headers
A new set of client-side headers allows the browser to inform the server about different HTTP request attributes. Four headers currently exist:
Sec-Fetch-Site: Indicates the intended relationship between the initiator and target origin.
Sec-Fetch-Mode: Indicates the intended request mode.
Sec-Fetch-User: Indicates if the request was triggered by the user.
Sec-Fetch-Dest: Indicates the intended request destination.
If supported by both the server and the browser, these headers can be used to inform the server about intended application behaviors to identify suspicious requests.
HTTP Headers to Improve Privacy and Security
The final items are not strictly HTTP security headers, but they can be used to improve both security and privacy.
Controls if and how much referrer information should be revealed to the web server. Typical usage would be:
With this header, the browser will only reveal complete referrer information (including the URL) for same-origin requests. For all other requests, only information about the origin is sent.
Invicti reports missing Referrer-Policy headers with a Best Practice severity level.
This header lets you control the caching of specific web pages. Although several directives are available, typical usage is:
This prevents any caching of the server response, which can be useful for ensuring that confidential data is not retained in any caches. Other directives are available for more precise control of caching.
To make sure that confidential information from a website is not stored by the browser after the user logs out, you can set the
Clear-Site-Data header, for example:
This will clear all browsing data related to the site. The
storage directives are available for more fine-grained control over what is cleared.
This experimental header allows you to deny access to specific browser features and APIs for the current page. This can be used to control application functionality but also to improve privacy and security. For example, to ensure that an application can’t use the microphone and camera APIs, you would send the following header:
Feature-Policy: microphone 'none'; camera 'none'
Many more directives are available – see the Feature-Policy documentation on MDN for a full list.
Keep Track of Your HTTP Security Headers with Invicti
HTTP security headers are often an easy way to improve web application security without changing the application itself, so it’s always a good idea to use the most current headers. However, because vendor support for HTTP headers can change so quickly, it’s hard to keep everything updated, especially if you’re working with hundreds of websites.
To help you keep up-to-date and stay secure, Invicti’s vulnerability checks include testing for recommended HTTP security headers. Invicti checks if the header is present and correctly configured, and provides clear recommendations to ensure that your web applications always have the best protection.