OWASP Secure Headers Project

The OWASP Secure Headers Project describes HTTP response headers that your application can use to increase the security of your application. Once set, these HTTP response headers can restrict modern browsers from running into easily preventable vulnerabilities. The OWASP Secure Headers Project intends to raise awareness and use of these headers.

Introduction

HTTP headers are well-known and also despised. Seeking a balance between usability and security, developers implement functionality through the headers that can make applications more versatile or secure. But in practice how are the headers being implemented? What sites follow the best implementation practices? Big companies, small, all or none?

Description

We aim to publish reports on header usage stats, developments and changes, code libraries that make these headers easily accessible to developers on a range of platforms, and data sets concerning the general usage of these headers.

The OWASP Secure Headers Project is migrating to this new OWASP website. For now you can still access the old website here https://wiki.owasp.org/index.php/OWASP_Secure_Headers_Project.

Contributors

Licensing

OWASP Secure Headers is free to use. It is licensed under the Apache 2.0 License.


Response Headers

Working draft

Active

Almost deprecated

Deprecated

HTTP Strict Transport Security

HTTP Strict Transport Security (also named HSTS) is a web security policy mechanism which helps to protect websites against protocol downgrade attacks and cookie hijacking. It allows web servers to declare that web browsers (or other complying user agents) should only interact with it using secure HTTPS connections, and never via the insecure HTTP protocol. HSTS is an IETF standards track protocol and is specified in RFC 6797. A server implements an HSTS policy by supplying a header (Strict-Transport-Security) over an HTTPS connection (HSTS headers over HTTP are ignored).

Values

Value Description
max-age=SECONDS The time, in seconds, that the browser should remember that this site is only to be accessed using HTTPS.
includeSubDomains If this optional parameter is specified, this rule applies to all of the site’s subdomains as well.

Example

Strict-Transport-Security: max-age=31536000 ; includeSubDomains

References

X-Frame-Options

The X-Frame-Options response header (also named XFO) improves the protection of web applications against clickjacking. It instructs the browser whether the content can be displayed within frames. The CSP frame-ancestors directive obsoletes the X-Frame-Options header. If a resource has both policies, the CSP frame-ancestors policy will be enforced and the X-Frame-Options policy will be ignored.

Values

Value Description
deny No rendering within a frame.
sameorigin No rendering if origin mismatch.
allow-from: DOMAIN Allows rendering if framed by frame loaded from DOMAIN.

Example

X-Frame-Options: deny

References

X-Content-Type-Options

Setting this header will prevent the browser from interpreting files as a different MIME type to what is specified in the Content-Type HTTP header (e.g. treating text/plain as text/css).

Values

Value Description
nosniff Will prevent the browser from MIME-sniffing a response away from the declared content-type.

Example

X-Content-Type-Options: nosniff

References

Content-Security-Policy

A Content Security Policy (also named CSP) requires careful tuning and precise definition of the policy. If enabled, CSP has significant impact on the way browsers render pages (e.g., inline JavaScript is disabled by default and must be explicitly allowed in the policy). CSP prevents a wide range of attacks, including cross-site scripting and other cross-site injections.

Values

Directive Description
base-uri Define the base URI for relative URIs.
default-src Define loading policy for all resources type in case a resource type’s dedicated directive is not defined (fallback).
script-src Define which scripts the protected resource can execute.
object-src Define from where the protected resource can load plugins.
style-src Define which styles (CSS) can be applied to the protected resource.
img-src Define from where the protected resource can load images.
media-src Define from where the protected resource can load video and audio.
frame-src (Deprecated and replaced by child-src) Define from where the protected resource can embed frames.
child-src Define from where the protected resource can embed frames.
frame-ancestors Define from where the protected resource can be embedded in frames.
font-src Define from where the protected resource can load fonts.
connect-src Define which URIs the protected resource can load using script interfaces.
manifest-src Define from where the protected resource can load manifests.
form-action Define which URIs can be used as the action of HTML form elements.
sandbox Specifies an HTML sandbox policy that the user agent applies to the protected resource.
script-nonce Define script execution by requiring the presence of the specified nonce on script elements.
plugin-types Define the set of plugins that can be invoked by the protected resource by limiting the types of resources that can be embedded.
reflected-xss Instruct the user agent to activate or deactivate any heuristics used to filter or block reflected cross-site scripting attacks, equivalent to the effects of the non-standard X-XSS-Protection header.
block-all-mixed-content Prevent the user agent from loading mixed content.
upgrade-insecure-requests Instruct the user agent to download insecure HTTP resources using HTTPS.
referrer (Deprecated) Define information the user agent can send in the Referer header.
report-uri (Deprecated and replaced by report-to) Specifies a URI to which the user agent sends reports about policy violation.
report-to Specifies a group (defined in the Report-To header) to which the user agent sends reports about policy violation.

Example

Content-Security-Policy: script-src 'self'

References

X-Permitted-Cross-Domain-Policies

A cross-domain policy file is an XML document that grants a web client, such as Adobe Flash Player or Adobe Acrobat (though not necessarily limited to these), permission to handle data across domains. When clients request content hosted on a particular source domain and that content makes requests directed towards a domain other than its own, the remote domain needs to host a cross-domain policy file that grants access to the source domain, allowing the client to continue the transaction. Normally a meta-policy is declared in the master policy file, but for those who can’t write to the root directory, they can also declare a meta-policy using the X-Permitted-Cross-Domain-Policies HTTP response header.

Values

Value Description
none No policy files are allowed anywhere on the target server, including this master policy file.
master-only Only this master policy file is allowed.
by-content-type [HTTP/HTTPS only] Only policy files served with Content-Type: text/x-cross-domain-policy are allowed.
by-ftp-filename [FTP only] Only policy files whose file names are crossdomain.xml (i.e. URLs ending in /crossdomain.xml) are allowed.
all All policy files on this target domain are allowed.

Example

X-Permitted-Cross-Domain-Policies: none

References

Referrer-Policy

The Referrer-Policy HTTP header governs which referrer information, sent in the Referer header, should be included with requests made.

Values

Value Description
no-referrer The Referer header will be omitted entirely. No referrer information is sent along with requests.
no-referrer-when-downgrade This is the user agent’s default behavior if no policy is specified. The origin is sent as referrer to a-priori as-much-secure destination (HTTPS → HTTPS), but isn’t sent to a less secure destination (HTTPS → HTTP).
origin Only send the origin of the document as the referrer in all cases. (e.g. the document https://example.com/page.html will send the referrer https://example.com/.)
origin-when-cross-origin Send a full URL when performing a same-origin request, but only send the origin of the document for other cases.
same-origin A referrer will be sent for same-site origins, but cross-origin requests will contain no referrer information.
strict-origin Only send the origin of the document as the referrer to a-priori as-much-secure destination (HTTPS → HTTPS), but don’t send it to a less secure destination (HTTPS → HTTP).
strict-origin-when-cross-origin Send a full URL when performing a same-origin request, only send the origin of the document to a-priori as-much-secure destination (HTTPS → HTTPS), and send no header to a less secure destination (HTTPS → HTTP).
unsafe-url Send a full URL (stripped from parameters) when performing a a same-origin or cross-origin request.

Example

Referrer-Policy: no-referrer

References

Clear-Site-Data

The Clear-Site-Data header clears browsing data (cookies, storage, cache) associated with the requesting website. It allows web developers to have more control over the data stored locally by a browser for their origins (source Mozilla MDN). This header is useful for example, during a logout process, in order to ensure that all stored content on the client side like cookies, storage and cache are removed.

Values

Value Description
"cache" Indicates that the server wishes to remove locally cached data for the origin of the response URL.
"cookies" Indicates that the server wishes to remove all cookies for the origin of the response URL. HTTP authentication credentials are also cleared out. This affects the entire registered domain, including subdomains.
"storage" Indicates that the server wishes to remove all DOM storage for the origin of the response URL.
"executionContexts" Indicates that the server wishes to reload all browsing contexts for the origin of the response. Currently, this value is only supported by a small subset of browsers.
"*" Indicates that the server wishes to clear all types of data for the origin of the response. If more data types are added in future versions of this header, they will also be covered by it.

Example

Clear-Site-Data: "cache","cookies","storage"

References

Cross-Origin-Embedder-Policy

This response header (also named COEP) prevents a document from loading any cross-origin resources that don’t explicitly grant the document permission (source Mozilla MDN).

Values

Value Description
unsafe-none Allows the document to fetch cross-origin resources without giving explicit permission through the CORS protocol or the Cross-Origin-Resource-Policy header (it is the default value).
require-corp A document can only load resources from the same origin, or resources explicitly marked as loadable from another origin.

Example

Cross-Origin-Embedder-Policy: require-corp

References

Cross-Origin-Opener-Policy

This response header (also named COOP) allows you to ensure a top-level document does not share a browsing context group with cross-origin documents. COOP will process-isolate your document and potential attackers can’t access to your global object if they were opening it in a popup, preventing a set of cross-origin attacks dubbed XS-Leaks (source Mozilla MDN).

Values

Value Description
unsafe-none Allows the document to be added to its opener’s browsing context group unless the opener itself has a COOP of same-origin or same-origin-allow-popups (it is the default value).
same-origin-allow-popups Retains references to newly opened windows or tabs which either don’t set COOP or which opt out of isolation by setting a COOP of unsafe-none.
same-origin Isolates the browsing context exclusively to same-origin documents. Cross-origin documents are not loaded in the same browsing context.

Example

Cross-Origin-Opener-Policy: same-origin

References

Cross-Origin-Resource-Policy

This response header (also named CORP) allows to define a policy that lets web sites and applications opt in to protection against certain requests from other origins (such as those issued with elements like <script> and <img>), to mitigate speculative side-channel attacks, like Spectre, as well as Cross-Site Script Inclusion (XSSI) attacks (source Mozilla MDN).

Values

Value Description
same-site Only requests from the same Site can read the resource.
same-origin Only requests from the same Origin (i.e. scheme + host + port) can read the resource.
cross-origin Requests from any Origin (both same-site and cross-site) can read the resource. Browsers are using this policy when an CORP header is not specified.

Example

Cross-Origin-Resource-Policy: same-origin

References

Cache-Control

This header holds directives (instructions) for caching in both requests and responses. If a given directive is in a request, it does not mean this directive is in the response (source Mozilla MDN). Specify the capability of a resource to be cached is important to prevent exposure of information via the cache.

The headers named Expires and Pragma can be used in addition to the Cache-Control header. Pragma header can be used for backwards compatibility with the HTTP/1.0 caches. However, Cache-Control is the recommanded way to define the caching policy.

Values applicable for HTTP responses

Value Description
must-revalidate Indicates that once a resource becomes stale, caches do not use their stale copy without successful validation on the origin server.
no-cache The response may be stored by any cache, even if the response is normally non-cacheable. However, the stored response MUST always go through validation with the origin server first before using it.
no-store The response may not be stored in any cache.
no-transform An intermediate cache or proxy cannot edit the response body, Content-Encoding, Content-Range, or Content-Type.
public The response may be stored by any cache, even if the response is normally non-cacheable.
private The response may be stored only by a browser’s cache, even if the response is normally non-cacheable.
proxy-revalidate Like must-revalidate, but only for shared caches (e.g., proxies). Ignored by private caches.
max-age=<seconds> The maximum amount of time a resource is considered fresh. Unlike Expires, this directive is relative to the time of the request.
s-maxage=<seconds> Overrides max-age or the Expires header, but only for shared caches (e.g., proxies). Ignored by private caches.

Extended values

The following directives are not part of the core HTTP caching standards document. Therefore, check this table for their support.

Value Description
immutable Indicates that the response body will not change over time.
stale-while-revalidate=<seconds> Indicates the client can accept a stale response, while asynchronously checking in the background for a fresh one. The seconds value indicates how long the client can accept a stale response.
stale-if-error=<seconds> Indicates the client can accept a stale response if the check for a fresh one fails. The seconds value indicates how long the client can accept the stale response after the initial expiration.

Example

No caching allowed, clear any previously cached resources and include support for HTTP/1.0 caches:

Cache-Control: no-store, max-age=0
Pragma: no-cache

Caching allowed with a cache duration of one week:

Cache-Control: public, max-age=604800

References

Permissions Policy

Working draft.

The Permissions-Policy header replaces the existing Feature-Policy header for controlling delegation of permissions and powerful features. The header uses a structured syntax, and allows sites to more tightly restrict which origins can be granted access to features (source Chrome platform status).

Values

Value Description
accelerometer Controls whether the current document is allowed to gather information about the acceleration of the device through the Accelerometer interface.
ambient-light-sensor Controls whether the current document is allowed to gather information about the amount of light in the environment around the device through the AmbientLightSensor interface.
autoplay Controls whether the current document is allowed to autoplay media requested through the HTMLMediaElement interface.
battery Controls whether the use of the Battery Status API is allowed.
camera Controls whether the current document is allowed to use video input devices.
display-capture Controls whether or not the current document is permitted to use the getDisplayMedia() method to capture screen contents.
document-domain Controls whether the current document is allowed to set document.domain.
encrypted-media Controls whether the current document is allowed to use the Encrypted Media Extensions API (EME).
execution-while-not-rendered Controls whether tasks should execute in frames while they’re not being rendered (e.g. if an iframe is hidden or display: none).
execution-while-out-of-viewport Controls whether tasks should execute in frames while they’re outside of the visible viewport.
fullscreen Controls whether the current document is allowed to use Element.requestFullScreen().
geolocation Controls whether the current document is allowed to use the Geolocation Interface.
gyroscope Controls whether the current document is allowed to gather information about the orientation of the device through the Gyroscope interface.
layout-animations Controls whether the current document is allowed to show layout animations.
legacy-image-formats Controls whether the current document is allowed to display images in legacy formats.
magnetometer Controls whether the current document is allowed to gather information about the orientation of the device through the Magnetometer interface.
microphone Controls whether the current document is allowed to use audio input devices.
midi Controls whether the current document is allowed to use the Web MIDI API.
navigation-override Controls the availability of mechanisms that enables the page author to take control over the behavior of spatial navigation, or to cancel it outright.
oversized-images Controls whether the current document is allowed to download and display large images.
payment Controls whether the current document is allowed to use the Payment Request API.
picture-in-picture Controls whether the current document is allowed to play a video in a Picture-in-Picture mode via the corresponding API.
publickey-credentials-get Controls whether the current document is allowed to use the Web Authentication API to retrieve already stored public-key credentials, i.e. via navigator.credentials.get({publicKey: ..., ...}).
sync-xhr Controls whether the current document is allowed to make synchronous XMLHttpRequest requests.
usb Controls whether the current document is allowed to use the WebUSB API.
vr Controls whether the current document is allowed to use the WebVR API.
wake-lock Controls whether the current document is allowed to use Wake Lock API to indicate that device should not enter power-saving mode.
screen-wake-lock Controls whether the current document is allowed to use Screen Wake Lock API to indicate that device should not turn off or dim the screen.
web-share Controls whether or not the current document is allowed to use the Navigator.share() of Web Share API to share text, links, images, and other content to arbitrary destinations of user’s choice, e.g. mobile apps.
xr-spatial-tracking Controls whether or not the current document is allowed to use the WebXR Device API to interact with a WebXR session.

Example

Permissions-Policy: accelerometer=(),autoplay=(),camera=(),display-capture=(),document-domain=(),encrypted-media=(),fullscreen=(),geolocation=(),gyroscope=(),magnetometer=(),microphone=(),midi=(),payment=(),picture-in-picture=(),publickey-credentials-get=(),screen-wake-lock=(),sync-xhr=(self),usb=(),web-share=(),xr-spatial-tracking=()

Remarks

Usage of all possible values from the table above raised the following error on Chrome 90.0.4430.212 and Edge 90.0.818.62:

Error with Permissions-Policy header: Unrecognized feature: 'ambient-light-sensor'.
Error with Permissions-Policy header: Unrecognized feature: 'battery'.
Error with Permissions-Policy header: Unrecognized feature: 'execution-while-not-rendered'.
Error with Permissions-Policy header: Unrecognized feature: 'execution-while-out-of-viewport'.
Error with Permissions-Policy header: Unrecognized feature: 'layout-animations'.
Error with Permissions-Policy header: Unrecognized feature: 'legacy-image-formats'.
Error with Permissions-Policy header: Unrecognized feature: 'navigation-override'.
Error with Permissions-Policy header: Unrecognized feature: 'oversized-images'.
Error with Permissions-Policy header: Unrecognized feature: 'vr'.
Error with Permissions-Policy header: Unrecognized feature: 'wake-lock'.

References

Feature-Policy

Almost deprecated.

⚠️ Warning: This header was split into Permissions-Policy and Document-Policy and will be considered deprecated once all impacted features are moved off of feature policy.

The Feature-Policy header is an experimental feature that allows developers to selectively enable and disable use of various browser features and APIs.
The two most well supported values are microphone and camera. For all the other ones, please consult this page.

Values

Value Description
accelerometer Controls access to accelerometer sensors on the device.
ambient-light-sensor Controls access to ambient light sensors on the device.
autoplay Controls access to autoplay through play() and the autoplay attribute.
battery Controls access to the BatteryManager API.
camera Controls access to video input devices.
display-capture Controls access to capturing the display output.
document-domain Controls access to setting document.domain.
encrypted-media Controls whether requestMediaKeySystemAccess() is allowed.
fullscreen Controls whether requestFullscreen() is allowed.
geolocation Controls access to the Geolocation interface.
gyroscope Controls access to gyroscope sensors on the device.
magnetometer Controls access to magnetometer sensors on the device.
microphone Controls access to audio input devices.
midi Controls access to requestMIDIAccess() method.
navigation-override Controls access to override of the spatial navigation API.
payment Controls access to the PaymentRequest interface.
picture-in-picture Controls access to picture-in-picture.
speaker Controls access to audio output devices.
usb Controls access to USB devices.
vibrate (deprecated) Controls access to the vibrate() method.
vr (deprecated) Controls access to VR displays.

Some experimental features are not present in this list, please check the references below for a complete list.

Example

Feature-Policy: vibrate 'none'; geolocation 'none'

References

Expect-CT

Almost deprecated.

⚠️ Warning: This header will likely become obsolete in June 2021. Since May 2018 new certificates are expected to support SCTs by default. Certificates before March 2018 were allowed to have a lifetime of 39 months, those will all be expired in June 2021.

The Expect-CT header is used by a server to indicate that browsers should evaluate connections to the host for Certificate Transparency compliance.
In Chrome 61 (Aug 2017) Chrome enabled its enforcement via SCT by default (source). You can still use this header to specify an report-uri.

This header comes from the (now expired) internet draft Expect-CT Extension for HTTP.

Values

Value Description
report-uri (Optional) Indicates the URL to which the browser should report Expect-CT failures.
enforce (Optional) A valueless directive that, if present, signals to the browser that compliance to the CT Policy should be enforced (rather than report-only) and that the browser should refuse future connections that violate its CT Policy. When both the enforce and report-uri directives are present, the configuration is referred to as an “enforce-and-report” configuration, signalling to the browser both that compliance to the CT Policy should be enforced and that violations should be reported.
max-age Specifies the number of seconds after the response is received the browser should remember and enforce certificate transparency compliance.

Example

Expect-CT: max-age=86400, enforce, report-uri="https://foo.example/report"

References

Public-Key-Pins

Deprecated.

⚠️ Warning: This header has been deprecated by all major browsers and is no longer recommended. Avoid using it, and update existing code if possible;

HTTP Public Key Pinning (HPKP) is a security mechanism which allows HTTPS websites to resist impersonation by attackers using mis-issued or otherwise fraudulent certificates. (For example, sometimes attackers can compromise certificate authorities, and then can mis-issue certificates for a web origin.).

The HTTPS web server serves a list of public key hashes, and on subsequent connections clients expect that server to use one or more of those public keys in its certificate chain. Deploying HPKP safely will require operational and organizational maturity due to the risk that hosts may make themselves unavailable by pinning to a set of public key hashes that becomes invalid. With care, host operators can greatly reduce the risk of man-in-the-middle (MITM) attacks and other false authentication problems for their users without incurring undue risk.

Deprecation Reason

Criticism and concern revolved around malicious or human error scenarios known as HPKP Suicide and Ransom PKP. In such scenarios, a website owner would have their ability to publish new contents to their domain severely hampered by either losing access to their own keys or having new keys announced by a malicious attacker.

Values

Value Description
pin-sha256="<sha256>" The quoted string is the Base64 encoded Subject Public Key Information (SPKI) fingerprint. It is possible to specify multiple pins for different public keys. Some browsers might allow other hashing algorithms than SHA-256 in the future.
max-age=SECONDS The time, in seconds, that the browser should remember that this site is only to be accessed using one of the pinned keys.
includeSubDomains If this optional parameter is specified, this rule applies to all of the site’s subdomains as well.
report-uri="<URL>" If this optional parameter is specified, pin validation failures are reported to the given URL.

Example

Public-Key-Pins: pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; report-uri="http://example.com/pkp-report"; max-age=10000; includeSubDomains

References

X-XSS-Protection

Deprecated.

⚠️ Warning: 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. Please use Content-Security-Policy instead.

This header enables the cross-site scripting (XSS) filter in your browser.

Values

Value Description
0 Filter disabled.
1 Filter enabled. If a cross-site scripting attack is detected, in order to stop the attack, the browser will sanitize the page.
1; mode=block Filter enabled. Rather than sanitize the page, when a XSS attack is detected, the browser will prevent rendering of the page.
1; report=http://[YOURDOMAIN]/your_report_URI Filter enabled. The browser will sanitize the page and report the violation. This is a Chromium function utilizing CSP violation reports to send details to a URI of your choice.

Example

X-XSS-Protection: 0

References


Browser Support

A reference is provided, for each header, to a site always providing up-to-date information.

Feature Reference
HTTP Strict Transport Security (HSTS) https://caniuse.com/stricttransportsecurity
X-Frame-Options https://caniuse.com/x-frame-options
X-Content-Type-Options https://caniuse.com/mdn-http_headers_x-content-type-options
Content-Security-Policy https://caniuse.com/?search=content-security-policy
X-Permitted-Cross-Domain-Policies https://www.adobe.com/devnet-docs/acrobatetk/tools/AppSec/xdomain.html
Referrer-Policy https://caniuse.com/referrer-policy
Feature-Policy https://caniuse.com/feature-policy
HTTP Public-Key-Pins (HPKP) https://caniuse.com/publickeypinning
Expect-CT https://caniuse.com/mdn-http_headers_expect-ct
X-XSS-Protection https://caniuse.com/mdn-http_headers_x-xss-protection
Clear-Site-Data https://caniuse.com/?search=Clear-Site-Data
Cross-Origin-Embedder-Policy (COEP) https://caniuse.com/mdn-http_headers_cross-origin-embedder-policy
Cross-Origin-Opener-Policy (COOP) https://caniuse.com/mdn-http_headers_cross-origin-opener-policy
Cross-Origin-Resource-Policy (CORP) https://caniuse.com/mdn-http_headers_cross-origin-resource-policy
Permissions Policy https://caniuse.com/permissions-policy
Cache-Control https://caniuse.com/mdn-http_headers_cache-control
Pragma https://caniuse.com/mdn-http_headers_pragma

Technical Resources

This section covers a list of tools to analyze, develop and administrate HTTP secure headers to help achieve more secure and trustworthy web systems.

Analysis Tools

hsecscan

A security scanner for HTTP response headers.

Github: https://github.com/riramar/hsecscan

headers

Python script to get some response headers from Alexa top sites file and store in a MySQL database.

Github: https://github.com/oshp/headers/

SecurityHeaders.com

There are services out there that will analyse the HTTP response headers of other sites but I also wanted to add a rating system to the results. The HTTP response headers that this site analyses provide huge levels of protection and it’s important that sites deploy them. Hopefully, by providing an easy mechanism to assess them, and further information on how to deploy missing headers, we can drive up the usage of security based headers across the web.

Site: https://securityheaders.com/

Mozilla Observatory

A Mozilla project designed to help developers, system administrators, and security professionals configure their sites safely and securely.

Site: https://observatory.mozilla.org/

GitHub: https://github.com/mozilla/http-observatory/

GitHub: https://github.com/mozilla/http-observatory-website/

Recx Security Analyser

Chrome extension that allows the inspection of security aspects of a site’s HTTP headers, cookies and other key security settings.

Site: https://chrome.google.com/webstore/detail/recx-security-analyser/ljafjhbjenhgcgnikniijchkngljgjda

KickOff

While each project you launch may have a different feature set, they often share many of the same performance, SEO and security requirements. This tool aims to automate the process of checking your list of requirements shortly before launch or directly after a deployment.

Site: https://github.com/frickelbruder/kickoff

testssl.sh

Easy to use shell script which tests not only SSL/TLS encryption but also checks common headers and analyzes those. Output is screen, JSON, CSV and HTML.

Site: https://github.com/drwetter/testssl.sh

DrHEADer

DrHEADer helps with the audit of security headers received in response to a single request or a list of requests.

Site: https://github.com/Santandersecurityresearch/DrHeader

API-Security

This is a Python based API-Security framework containing ApiSecurityHeader.py script which will check the above mentioned Security response headers are present and contains the required value.

Site: https://github.com/AmitKulkarni9/API-Security

Venom Test Suites

Test suites for Venom checking the presence and the value for the different response headers proposed by the OWASP Secure Headers Project.

GitHub: https://gist.github.com/righettod/f63548ebd96bed82269dcc3dfea27056

Development Libraries

secureheaders (Ruby)

Security related headers all in one gem.

Github: https://github.com/twitter/secureheaders

Spring Security (Java)

Spring Security’s support for adding various security headers to the response.

Site: https://docs.spring.io/spring-security/site/docs/current/reference/html/headers.html

SecureHeaders (PHP)

A PHP class aiming to make the use of browser security features more accessible.

Site: https://github.com/aidantwoods/SecureHeaders

rack-secure_headers (Rack)

Security related HTTP headers for Rack applications.

Site: https://github.com/frodsan/rack-secure_headers

helmet and hood (Node.js + express)

Site: https://github.com/helmetjs/helmet Site: https://github.com/seanmonstar/hood

blankie (hapi)

A CSP plugin for hapi.

Site: https://github.com/nlf/blankie

NWebsec (ASP.NET)

NWebsec consists of several security libraries for ASP.NET applications.

Site: https://docs.nwebsec.com

django-csp + commonware; django-security (Python)

django-csp + commonware; django-security.

Site: https://github.com/mozilla/django-csp
Site: https://github.com/jsocol/commonware/
Site: https://github.com/sdelements/django-security

Secure (Python)

Secure is a lightweight package that adds optional security headers and cookie attributes for Python web frameworks.

Site: https://github.com/cakinney/secure

secureheader (Go)

Package secureheader adds some HTTP header fields widely considered to improve safety of HTTP requests.

Site: https://github.com/kr/secureheader

secure_headers (Elixir)

This Plug will automatically apply several security headers to the Plug.Conn response. By design SecureHeaders will attempt to apply the most strict security policy. Although, security headers are configurable and are validated to avoid misconfiguration.

Site: https://github.com/anotherhale/secure_headers

dropwizard-web-security (Dropwizard)

A bundle for applying default web security functionality to a dropwizard application.

Site: https://github.com/palantir/dropwizard-web-security

ember-cli-content-security-policy (Ember.js)

This addon makes it easy to use Content Security Policy (CSP) in your project. It can be deployed either via a Content-Security-Policy header sent from the Ember CLI Express server, or as a meta tag in the index.html file.

Site: https://github.com/rwjblue/ember-cli-content-security-policy/

Operation Tools

http_hardening

Puppet module to enable, configure and manage secure http headers on web servers.

Supported Web Servers:

  • Apache HTTP Server
  • NGINX
  • Lighttpd

Github: https://github.com/amenezes/http_hardening
Puppet Forge: https://forge.puppet.com/amenezes/http_hardening


Top Websites Examples

HTTP response headers from the top websites in the world.

Command used to extract the headers:

curl -L -A "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36" -s -D - https://www.example.com -o /dev/null

Google

$ curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36" -s -D - https://www.google.com -o /dev/null

HTTP/1.1 302 Found
Location: https://www.google.com.br/?gws_rd=cr&dcr=0&ei=rtcKWpnkNYaawATUn6agCg
Cache-Control: private
Content-Type: text/html; charset=UTF-8
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Date: Tue, 14 Nov 2017 11:46:54 GMT
Server: gws
Content-Length: 273
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Set-Cookie: NID=117=GENZIllQGZFmhCBmap1YThta_hUvvZ9Xm517XXWpF9eCKNqW6_luvZm1b_ai7BN4lAA2pP2Z22BveHqjUrqZxpY38NKSYLKWFGrVh6tGAHcbNw6OHQ_F77bNJWV0BZOZ; expires=Wed, 16-May-2018 11:46:54 GMT; path=/; domain=.google.com; HttpOnly
Alt-Svc: quic=":443"; ma=2592000; v="41,39,38,37,35"

HTTP/1.1 200 OK
Date: Tue, 14 Nov 2017 11:46:55 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=UTF-8
Strict-Transport-Security: max-age=3600
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Set-Cookie: 1P_JAR=2017-11-14-11; expires=Thu, 14-Dec-2017 11:46:55 GMT; path=/; domain=.google.com.br
Set-Cookie: NID=117=fR73jhascV3B9fbiVfYdvGlilR_tgYNhela9rXdCavJiJoYpkNSTq0NtFqNSV8im602zM7Of-S1GUr_ncSuT3p6tzlw3e6_9ccqPttSuniTHWZEgBtUL1VXTgXBdjKMe; expires=Wed, 16-May-2018 11:46:55 GMT; path=/; domain=.google.com.br; HttpOnly
Alt-Svc: quic=":443"; ma=2592000; v="41,39,38,37,35"
Accept-Ranges: none
Vary: Accept-Encoding
Transfer-Encoding: chunked

Facebook

$ curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36" -s -D - https://www.facebook.com -o /dev/null

HTTP/1.1 200 OK
X-XSS-Protection: 0
Pragma: no-cache
content-security-policy: default-src * data: blob:;script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' fbstatic-a.akamaihd.net fbcdn-static-b-a.akamaihd.net *.atlassolutions.com blob: data: 'self';style-src data: blob: 'unsafe-inline' *;connect-src *.facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* *.akamaihd.net wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;
Cache-Control: private, no-cache, no-store, must-revalidate
X-Frame-Options: DENY
expect-ct: max-age=10, report-uri="http://reports.fb.com/expectct/"
Strict-Transport-Security: max-age=15552000; preload
X-Content-Type-Options: nosniff
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Set-Cookie: fr=0Bf96eRMD0zCulvzh..BaCtgp.jl.AAA.0.0.BaCtgp.AWVGQojt; expires=Mon, 12-Feb-2018 11:48:57 GMT; Max-Age=7776000; path=/; domain=.facebook.com; secure; httponly
Set-Cookie: sb=KdgKWqMf8J84KfUg99AxaG1B; expires=Thu, 14-Nov-2019 11:48:57 GMT; Max-Age=63072000; path=/; domain=.facebook.com; secure; httponly
Vary: Accept-Encoding
Content-Type: text/html; charset=UTF-8
X-FB-Debug: llncdeFRYCCoWkXqx2VCdUGtdHZvjsr6OA7JNrtEe18ZuZAqcKCH4km9SSkNTHIcuXmzwRMzyBQt0Uz7T6ltQg==
Date: Tue, 14 Nov 2017 11:48:57 GMT
Transfer-Encoding: chunked
Connection: keep-alive

Twitter

$ curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36" -s -D - https://www.twitter.com -o /dev/null

HTTP/1.1 301 Moved Permanently
content-length: 0
date: Tue, 14 Nov 2017 11:50:11 GMT
location: https://twitter.com/
server: tsa_d
set-cookie: personalization_id="v1_nyz+ctxxDiBbh4s6VjzQIg=="; Expires=Thu, 14 Nov 2019 11:50:11 UTC; Path=/; Domain=.twitter.com
set-cookie: guest_id=v1%3A151066021116455299; Expires=Thu, 14 Nov 2019 11:50:11 UTC; Path=/; Domain=.twitter.com
strict-transport-security: max-age=631138519
x-connection-hash: d9a9eea848268dae67e7743d5bfd2dd5
x-response-time: 135

HTTP/1.1 200 OK
cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
content-length: 345977
content-security-policy: script-src https://connect.facebook.net https://cm.g.doubleclick.net https://ssl.google-analytics.com https://graph.facebook.com 'nonce-f/+1f61E6Z0qq8p+L4UIQw==' https://twitter.com 'unsafe-eval' https://*.twimg.com https://api.twitter.com https://analytics.twitter.com https://publish.twitter.com https://ton.twitter.com https://syndication.twitter.com https://www.google.com https://t.tellapart.com https://platform.twitter.com https://www.google-analytics.com blob: 'self'; frame-ancestors 'self'; font-src https://twitter.com https://*.twimg.com data: https://ton.twitter.com https://fonts.gstatic.com https://maxcdn.bootstrapcdn.com https://netdna.bootstrapcdn.com 'self'; media-src https://rmpdhdsnappytv-vh.akamaihd.net https://prod-video-eu-central-1.pscp.tv https://v.cdn.vine.co https://dwo3ckksxlb0v.cloudfront.net https://twitter.com https://amp.twimg.com https://smmdhdsnappytv-vh.akamaihd.net https://*.twimg.com https://prod-video-eu-west-1.pscp.tv https://rmmdhdsnappytv-vh.akamaihd.net https://prod-video-us-west-2.pscp.tv https://prod-video-us-west-1.pscp.tv https://prod-video-ap-northeast-1.pscp.tv https://smdhdsnappytv-vh.akamaihd.net https://ton.twitter.com https://rmdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://smpdhdsnappytv-vh.akamaihd.net https://prod-video-sa-east-1.pscp.tv https://mdhdsnappytv-vh.akamaihd.net https://prod-video-ap-southeast-2.pscp.tv https://mtc.cdn.vine.co https://dev-video-us-west-2.pscp.tv https://prod-video-us-east-1.pscp.tv blob: 'self' https://prod-video-ap-southeast-1.pscp.tv https://mpdhdsnappytv-vh.akamaihd.net https://dev-video-eu-west-1.pscp.tv; connect-src https://rmpdhdsnappytv-vh.akamaihd.net https://prod-video-eu-central-1.pscp.tv https://graph.facebook.com https://*.giphy.com https://dwo3ckksxlb0v.cloudfront.net https://vmaprel.snappytv.com https://smmdhdsnappytv-vh.akamaihd.net https://*.twimg.com https://embed.pscp.tv https://api.twitter.com https://prod-video-eu-west-1.pscp.tv https://rmmdhdsnappytv-vh.akamaihd.net https://prod-video-us-west-2.pscp.tv https://pay.twitter.com https://prod-video-us-west-1.pscp.tv https://analytics.twitter.com https://vmap.snappytv.com https://*.twprobe.net https://prod-video-ap-northeast-1.pscp.tv https://smdhdsnappytv-vh.akamaihd.net https://syndication.twitter.com https://sentry.io https://rmdhdsnappytv-vh.akamaihd.net https://media.riffsy.com https://mmdhdsnappytv-vh.akamaihd.net https://embed.periscope.tv https://smpdhdsnappytv-vh.akamaihd.net https://prod-video-sa-east-1.pscp.tv https://vmapstage.snappytv.com https://upload.twitter.com https://proxsee.pscp.tv https://mdhdsnappytv-vh.akamaihd.net https://prod-video-ap-southeast-2.pscp.tv https://dev-video-us-west-2.pscp.tv https://prod-video-us-east-1.pscp.tv 'self' https://vmap.grabyo.com https://prod-video-ap-southeast-1.pscp.tv https://mpdhdsnappytv-vh.akamaihd.net https://dev-video-eu-west-1.pscp.tv; style-src https://fonts.googleapis.com https://twitter.com https://*.twimg.com https://translate.googleapis.com https://ton.twitter.com 'unsafe-inline' https://platform.twitter.com https://maxcdn.bootstrapcdn.com https://netdna.bootstrapcdn.com 'self'; object-src https://twitter.com https://pbs.twimg.com; default-src 'self'; frame-src https://staticxx.facebook.com https://twitter.com https://*.twimg.com https://5415703.fls.doubleclick.net https://player.vimeo.com https://pay.twitter.com https://www.facebook.com https://ton.twitter.com https://syndication.twitter.com https://vine.co twitter: https://www.youtube.com https://platform.twitter.com https://upload.twitter.com https://s-static.ak.facebook.com https://4337974.fls.doubleclick.net https://8122179.fls.doubleclick.net 'self' https://donate.twitter.com; img-src https://prod-video-eu-central-1.pscp.tv https://prod-profile.pscp.tv https://graph.facebook.com https://prod-thumbnail.pscp.tv https://*.giphy.com https://twitter.com https://*.twimg.com https://ad.doubleclick.net https://prod-video-eu-west-1.pscp.tv data: https://prod-video-us-west-2.pscp.tv https://prod-video-us-west-1.pscp.tv https://prod-video-ap-northeast-1.pscp.tv https://lumiere-a.akamaihd.net https://fbcdn-profile-a.akamaihd.net https://www.facebook.com https://ton.twitter.com https://*.fbcdn.net https://syndication.twitter.com https://media.riffsy.com https://www.google.com https://prod-profile.periscope.tv https://prod-video-sa-east-1.pscp.tv https://stats.g.doubleclick.net https://platform.twitter.com https://prod-video-ap-southeast-2.pscp.tv https://api.mapbox.com https://www.google-analytics.com https://dev-video-us-west-2.pscp.tv https://prod-video-us-east-1.pscp.tv blob: https://prod-thumbnail-small.pscp.tv https://prod-thumbnail-small.periscope.tv 'self' https://prod-thumbnail.periscope.tv https://prod-video-ap-southeast-1.pscp.tv https://dev-video-eu-west-1.pscp.tv; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVZXO2LGOQ%3D%3D%3D%3D%3D%3D&ro=false;
content-type: text/html;charset=utf-8
date: Tue, 14 Nov 2017 11:50:11 GMT
expires: Tue, 31 Mar 1981 05:00:00 GMT
last-modified: Tue, 14 Nov 2017 11:50:11 GMT
pragma: no-cache
server: tsa_d
set-cookie: fm=0; Expires=Tue, 14 Nov 2017 11:50:02 UTC; Path=/; Domain=.twitter.com; Secure; HTTPOnly
set-cookie: _twitter_sess=BAh7CSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%250ASGFzaHsABjoKQHVzZWR7ADoPY3JlYXRlZF9hdGwrCMOCXbpfAToMY3NyZl9p%250AZCIlOTk3MjYzYzc1NDhkOTA1ZTlhZTIyNGE2Zjk5Nzg0NTk6B2lkIiU0ODIw%250AZWRkNjc4Njg2M2IzYmI3ZTA3N2YxMTA4YzE5Nw%253D%253D--7abf7eef950088f9f728686ce29881ef501487dd; Path=/; Domain=.twitter.com; Secure; HTTPOnly
set-cookie: personalization_id="v1_rrHzrB5h0Qs1Oz4uhOjFJg=="; Expires=Thu, 14 Nov 2019 11:50:11 UTC; Path=/; Domain=.twitter.com
set-cookie: guest_id=v1%3A151066021139105511; Expires=Thu, 14 Nov 2019 11:50:11 UTC; Path=/; Domain=.twitter.com
set-cookie: ct0=ba98c8a6cb4c664151a98c8bd9eb4b4d; Expires=Tue, 14 Nov 2017 17:50:11 UTC; Path=/; Domain=.twitter.com; Secure
status: 200 OK
strict-transport-security: max-age=631138519
x-connection-hash: 769f9dcd87b9274776136b99b3181a44
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-response-time: 359
x-transaction: 007d216900cbc2ad
x-twitter-response-tags: BouncerCompliant
x-ua-compatible: IE=edge,chrome=1
x-xss-protection: 1; mode=block

Github

$ curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36" -s -D - https://www.github.com -o /dev/null
HTTP/1.1 301 Moved Permanently
Content-length: 0
Location: https://github.com/

HTTP/1.1 200 OK
Server: GitHub.com
Date: Tue, 14 Nov 2017 11:51:27 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Status: 200 OK
Cache-Control: no-cache
Vary: X-PJAX
X-UA-Compatible: IE=Edge,chrome=1
Set-Cookie: logged_in=no; domain=.github.com; path=/; expires=Sat, 14 Nov 2037 11:51:27 -0000; secure; HttpOnly
Set-Cookie: _gh_sess=eyJzZXNzaW9uX2lkIjoiODI5ZGZjZDhlZDFlMjBjZTBhMTljMjk5ZDU1ZDBlODgiLCJsYXN0X3JlYWRfZnJvbV9yZXBsaWNhcyI6MTUxMDY2MDI4NzMxNywiX2NzcmZfdG9rZW4iOiIvTjkya2RHLzJJN2dtbU12eWQ3UGJDeTJ0aU1tZHJrci8wVzlpMi9yajFZPSJ9--5920790d2e11e8d4a32177a14ac25fae6e8f9789; path=/; secure; HttpOnly
X-Request-Id: b31804a05047fd1326fe28cf3d6f33aa
X-Runtime: 0.036845
Expect-CT: max-age=2592000, report-uri="https://api.github.com/_private/browser/errors"
Content-Security-Policy: default-src 'none'; base-uri 'self'; block-all-mixed-content; child-src render.githubusercontent.com; connect-src 'self' uploads.github.com status.github.com collector.githubapp.com api.github.com www.google-analytics.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com wss://live.github.com; font-src assets-cdn.github.com; form-action 'self' github.com gist.github.com; frame-ancestors 'none'; img-src 'self' data: assets-cdn.github.com identicons.github.com collector.githubapp.com github-cloud.s3.amazonaws.com *.githubusercontent.com; media-src 'none'; script-src assets-cdn.github.com; style-src 'unsafe-inline' assets-cdn.github.com
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
Public-Key-Pins: max-age=0; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho="; pin-sha256="k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws="; pin-sha256="K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q="; pin-sha256="IQBnNBEiFuhj+8x6X8XLgh01V9Ic5/V3IRQLNFFc7v4="; pin-sha256="iie1VXtL7HzAMF+/PVPR9xzT80kQxdZeJ+zduCB3uj0="; pin-sha256="LvRiGEjRqfzurezaWuj8Wie2gyHMrW5Q06LspMnox7A="; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: deny
X-XSS-Protection: 1; mode=block
X-Runtime-rack: 0.043225
X-GitHub-Request-Id: 9AB0:25783:6A523:B814E:5A0AD8BE

Best Practices

Configuration proposal

Please note the best practices below suggest methods to change webserver configuration to add headers. Security headers can also be successfully added to your application at the software level as well in almost every web language. Many web frameworks add some of these headers automatically.

The following section propose a configuration for the actively supported and working draft security headers.

Proposed values

⚠️ The Pragma header is only specified for backwards compatibility with the HTTP/1.0 caches.

Header name Proposed value
HTTP Strict Transport Security (HSTS) max-age=31536000 ; includeSubDomains
X-Frame-Options deny
X-Content-Type-Options nosniff
Content-Security-Policy default-src 'self'; object-src 'none'; child-src 'self'; frame-ancestors 'none'; upgrade-insecure-requests; block-all-mixed-content
X-Permitted-Cross-Domain-Policies none
Referrer-Policy no-referrer
Clear-Site-Data "cache","cookies","storage"
Cross-Origin-Embedder-Policy (COEP) require-corp
Cross-Origin-Opener-Policy (COOP) same-origin
Cross-Origin-Resource-Policy (CORP) same-origin
Permissions-Policy accelerometer=(),autoplay=(),camera=(),display-capture=(),document-domain=(),encrypted-media=(),fullscreen=(),geolocation=(),gyroscope=(),magnetometer=(),microphone=(),midi=(),payment=(),picture-in-picture=(),publickey-credentials-get=(),screen-wake-lock=(),sync-xhr=(self),usb=(),web-share=(),xr-spatial-tracking=()
Cache-Control no-store, max-age=0
Pragma no-cache

Web server syntax

This section indicate the syntax to use to set a HTTP header according to the web server targeted.

Web server name Syntax
Apache Header always set [HEADER_NAME] [PROPOSED_VALUE]
Nginx add_header [HEADER_NAME] [PROPOSED_VALUE] always;
Lighttpd setenv.add-response-header = ("[HEADER_NAME]" => "[PROPOSED_VALUE]")
IIS Refer to this documentation.

Quickly check security HTTP headers for applications exposed on the Internet

The online tool securityheaders.com can be used to achieve that objective.

It returns the grade in the following HTTP response headers:

  • x-score: Contains a Base64 encoded JSON object with the grade letter and its associated color name.
  • x-grade: Contains the grade letter.
$ curl -v "https://securityheaders.com/?hide=on&followRedirects=on&q=https://mozilla.org"
> Trying 104.21.70.128:443...
> Connected to securityheaders.com (104.21.70.128) port 443
> ...
< HTTP/2 200
< date: Tue, 02 Mar 2021 17:29:23 GMT
< content-type: text/html; charset=UTF-8
< vary: Accept-Encoding
< x-score: eyJzY29yZSI6IkEiLCAiY29sb3VyIjoiZ3JlZW4ifQ==
< x-grade: A
< ...

Content of the x-score header value:

$ echo eyJzY29yZSI6IkEiLCAiY29sb3VyIjoiZ3JlZW4ifQ== | base64 -d
{"score":"A", "colour":"green"}

Quickly check security HTTP headers for applications exposed internally

The portable cross-platform tool Venom with the dedicated test suites aligned with the OWASP Secure Headers Project can be used to achieve that objective.

Use the following set of commands:

# Get Venom binary file from 
# https://github.com/ovh/venom/releases
# Get the YAML test suites from
# https://gist.github.com/righettod/f63548ebd96bed82269dcc3dfea27056
# Demonstration about usage available on
# https://gist.github.com/righettod/f63548ebd96bed82269dcc3dfea27056#gistcomment-3630811
$ venom run --var="target_site=https://mozilla.org" --var="logout_url=/logout" venom_security_headers_tests_suite.yml
• HTTP security response headers test suites (venom_security_headers_tests_suite.yml)
    • Strict-Transport-Security SUCCESS
    • X-Frame-Options SUCCESS
    • X-Content-Type-Options SUCCESS
    • Content-Security-Policy FAILURE
    • X-Permitted-Cross-Domain-Policies SUCCESS
    • Referrer-Policy SUCCESS
    • Clear-Site-Data SUCCESS
    • Cross-Origin-Embedder-Policy SUCCESS
    • Cross-Origin-Opener-Policy SUCCESS
    • Cross-Origin-Resource-Policy SUCCESS
    • Permissions-Policy SUCCESS    
    • Cache-Control SUCCESS    
    • Feature-Policy SUCCESS
        [info] This header was split into Permissions-Policy and Document-Policy and will be considered deprecated once all impacted features are moved off of feature policy. (venom_security_headers_tests_suite.yml:152)
    • Public-Key-Pins SUCCESS
        [info] This header has been deprecated by all major browsers and is no longer recommended. Avoid using it, and update existing code if possible! (venom_security_headers_tests_suite.yml:164)
    • Expect-CT SUCCESS
        [info] This header will likely become obsolete in June 2021. Since May 2018 new certificates are expected to support SCTs by default. Certificates before March 2018 were allowed to have a lifetime of 39 months, those will all be expired in June 2021. (venom_security_headers_tests_suite.yml:175)
    • X-Xss-Protection SUCCESS
        [info] The X-XSS-Protection header has been deprecated by modern browsers and its use can introduce additional security issues on the client side. (venom_security_headers_tests_suite.yml:189)
    • SecurityHeaders-Rating SKIPPED

Miscellaneous

This section provide extra useful information about HTTP Security headers.

Request headers

Fetch metadata request header

A fetch metadata request header is an HTTP request header that provides additional information about the context from which the request originated. This allows the server to make decisions about whether a request should be allowed based on where the request came from and how the resource will be used .

These headers are prefixed with Sec-, and hence have forbidden header names. As such, they cannot be modified from JavaScript.

Source Mozilla MDN.

These headers can be leveraged to add protection measures against XS-Leaks attacks.

Sec-Fetch-Dest

The Sec-Fetch-Dest fetch metadata request header indicates the request’s destination. That is the initiator of the original fetch request, which is where (and how) the fetched data will be used.

Possible values are detailled here.

Source Mozilla MDN.

Sec-Fetch-Mode

The Sec-Fetch-Mode fetch metadata request header indicates the mode of the request: cors, no-cors, same-origin, navigate or websocket.

Broadly speaking, this allows a server to distinguish between: requests originating from a user navigating between HTML pages, and requests to load images and other resources.

Possible values are detailled here.

Source Mozilla MDN.

Sec-Fetch-User

The Sec-Fetch-User fetch metadata request header is only sent for requests initiated by user activation, and its value will always be ?1.

Source Mozilla MDN.

Sec-Fetch-Site

The Sec-Fetch-Site fetch metadata request header indicates the relationship between a request initiator’s origin and the origin of the requested resource.

In other words, this header tells a server whether a request for a resource is coming from the same origin, the same site, a different site, or is a “user initiated” request. The server can then use this information to decide if the request should be allowed.

Possible values are detailled here.

Source Mozilla MDN.

Explanation about Site vs Origin can be found here.

Example

GET /www-project-secure-headers/
Host: owasp.org
User-Agent: Chrome/91.0.4472.124
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: cross-site
Sec-Fetch-User: ?1

References