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.


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?


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.



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

Response Headers


Almost 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).


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.


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



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.


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.


X-Frame-Options: deny



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).


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


X-Content-Type-Options: nosniff



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.


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.


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



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.


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.


X-Permitted-Cross-Domain-Policies: none



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


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.


Referrer-Policy: no-referrer



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.


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.


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



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).


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.


Cross-Origin-Embedder-Policy: require-corp



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).


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.


Cross-Origin-Opener-Policy: same-origin



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).


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.


Cross-Origin-Resource-Policy: same-origin



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.

Permissions-Policy header usage is not recommended yet by OSHP because it is currently not supported by default by any major browser.


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.


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



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.


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.


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




⚠️ 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.


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.


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




⚠️ 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.


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.


X-XSS-Protection: 0


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 Header value handled by Adobe products and not the browser
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

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


A security scanner for HTTP response headers.

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


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

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


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


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


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 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


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

Security Header Injection Module (SHIM) (ASP.NET)

SHIM is a HTTP module that provides protection for many vulnerabilities by injecting security-specific HTTP headers into ASP.NET web applications.

Site: https://shim.codeplex.com/

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


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

Supported Web Servers:

  • Apache HTTP Server
  • 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


$ 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


$ 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* *.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


$ 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


$ 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 security headers.

Proposed values

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' data:; 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

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
> Connected to securityheaders.com ( 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
    • 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