HTTP Security Headers: An Easy Way to Harden Your Web Applications

Modern browsers support many HTTP headers that can improve web application security to protect against clickjacking, cross-site scripting, and other common attacks. This article provides an overview of HTTP security headers, as presented by Invicti security researcher Sven Morgenroth in a recent interview on Security Weekly.

HTTP Security Headers and How They Work

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.

Invicti checks if HSTS is enabled and correctly configured.


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 script-src, style-src, and 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 object-src.

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:

X-Frame-Options: deny

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 header was introduced to protect against JavaScript injection attacks through cross-site scripting. The usual syntax was:

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:


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, 

With the 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:

X-Content-Type-Options: nosniff

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:

Referrer-Policy: origin-when-cross-origin

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:

Cache-Control: no-store

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:

Clear-Site-Data: "*"

This will clear all browsing data related to the site. The cache, cookies, and 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.

Zbigniew Banach

About the Author

Zbigniew Banach - Senior Technical Content Writer

Cybersecurity writer at Invicti Security. Drawing on years of experience with security, software development, content creation, journalism, and technical translation, he does his best to bring web application security and cybersecurity in general to a wider audience.