OWASP Secure Headers Project

=Main=



{| style="padding: 0;margin:0;margin-top:10px;text-align:left;" |-
 * valign="top" style="border-right: 1px dotted gray;padding-right:25px;" |

OWASP Secure Headers Project
OWASP Secure Headers Project involves setting headers from the server is easy and often doesn't require any code changes. Once set, they can restrict modern browsers from running into easily preventable vulnerabilities. OWASP Secure Headers Project intends to raise awareness and use of these headers.

Introduction
HTTP headers are well known and also despised. Seeking the balance between usability and security developers implement functionality through the headers that can make your more versatile or secure application. But in practice how the headers are 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. Data sets concerning the general usage of these headers.

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


 * valign="top" style="padding-left:25px;width:200px;border-right: 1px dotted gray;padding-right:25px;" |

Project Leader
Ricardo Iramar

Project Contributors
Jim Manico

Alexandre Menezes

Related Projects

 * OWASP Application Security Verification Standard Project
 * OWASP Top Ten Project

Quick Links

 * Project GitHub Organization
 * Docker Hub Organization
 * Demo [develop preview]
 * hsecscan A security scanner for HTTP response headers
 * Project Email List


 * valign="top" style="padding-left:25px;width:200px;" |

News and Events

 * [20 Oct 2017] OWASP Secure Headers Project on OWASP Top 10 RC2 (https://github.com/OWASP/Top10/blob/master/2017/OWASP%20Top%2010%202017%20RC2%20Final.pdf)
 * [14 Mar 2017] Docker Hub Organization (https://hub.docker.com/r/oshp)
 * [15 Oct 2016] RoadSec Curitiba 2016 Presentation (http://roadsec.com.br/curitiba2016/)
 * [20/21 Set 2016] Mind The Sec 2016 Presentation (http://mindthesec.com.br/ricardo-iramar-dos-santos)
 * [05 Sep 2016] Project Github Organization (https://github.com/oshp/)
 * [01 Sep 2016] Included X-Permitted-Cross-Domain-Policies header and Compatibility Matrix tab
 * [14 Dec 2015] Reborn from the ashes

Classifications

 * }

=Headers=

The following contains a list of HTTP response headers related to security.

Response Headers

 * HTTP Strict Transport Security (HSTS)
 * Public Key Pinning Extension for HTTP (HPKP)
 * X-Frame-Options
 * X-XSS-Protection
 * X-Content-Type-Options
 * Content-Security-Policy
 * X-Permitted-Cross-Domain-Policies
 * Referrer-Policy
 * Expect-CT

HTTP Strict Transport Security (HSTS)
HTTP Strict Transport Security (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).

Public Key Pinning Extension for HTTP (HPKP)
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.

Before implement HPKP please read this https://groups.google.com/a/chromium.org/forum/m/#!msg/blink-dev/he9tr7p3rZ8/eNMwKPmUBAAJ.

X-Frame-Options
X-Frame-Options response header improve the protection of web applications against Clickjacking. It declares a policy communicated from a host to the client browser on whether the browser must not display the transmitted content in frames of other web pages.

X-XSS-Protection
This header enables the Cross-site scripting (XSS) filter in your browser.

X-Content-Type-Options
Setting this header will prevent the browser from interpreting files as something else than declared by the content type in the HTTP headers.

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

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

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

Browser Support
NS = Not Supported

+ = Specified version and above

Google
$ 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.google.com -o /dev/null HTTP/1.1 302 Found Cache-Control: private Content-Type: text/html; charset=UTF-8 Location: https://www.google.com.br/?gfe_rd=cr&ei=pNhBV6yTAvSp8wf3lInoCg Content-Length: 263 Date: Sun, 22 May 2016 16:04:52 GMT Alternate-Protocol: 443:quic Alt-Svc: quic=":443"; ma=2592000; v="34,33,32,31,30,29,28,27,26,25"

HTTP/1.1 200 OK Date: Sun, 22 May 2016 16:04:52 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=UTF-8 P3P: CP="This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info." Server: gws X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN Set-Cookie: NID=79=BdHGSU63HWlvH35tKMhNOYIN8VCnB0huHol7Yl-29r0jEE2HY1n6Nts9BJH_JZ-Cps57guAUTLSyTO6caM9WzOPJYDfsRt8qMZ4tt4rGdfN0pURn1j-xRW-zxwx9-mkb; expires=Mon, 21-Nov-2016 16:04:52 GMT; path=/; domain=.google.com.br; HttpOnly Alternate-Protocol: 443:quic Alt-Svc: quic=":443"; ma=2592000; v="34,33,32,31,30,29,28,27,26,25" Accept-Ranges: none Vary: Accept-Encoding Transfer-Encoding: chunked

Facebook
$ 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.facebook.com -o /dev/null HTTP/1.1 200 OK Strict-Transport-Security: max-age=15552000; preload Expires: Sat, 01 Jan 2000 00:00:00 GMT Cache-Control: private, no-cache, no-store, must-revalidate 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: chrome-extension://lifbcibllhkdhoafpjfnlhfpfgnpldfl;style-src * 'unsafe-inline' data:;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: 127.0.0.1:*; Pragma: no-cache public-key-pins-report-only: max-age=500; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E="; pin-sha256="q4PO2G2cbkZhZ82+JgmRUyGMoAeozA+BSXVXQWB8XWQ="; report-uri="http://reports.fb.com/hpkp/" X-Content-Type-Options: nosniff X-XSS-Protection: 0 X-Frame-Options: DENY Vary: Accept-Encoding Content-Type: text/html X-FB-Debug: 7zpjoR0dVod3whuapaNzLVQnAg077KxpFx7VJO2nLT0AX3jD3IquGAFK+o5E1UARnZhloBpGmOaMns7AE7lllA== Date: Sun, 22 May 2016 16:05:38 GMT Transfer-Encoding: chunked Connection: keep-alive

Twitter
$ 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.twitter.com -o /dev/null HTTP/1.1 301 Moved Permanently content-length: 0 date: Sun, 22 May 2016 16:06:04 GMT location: https://twitter.com/ server: tsa_d set-cookie: guest_id=v1%3A146393316440053116; Domain=.twitter.com; Path=/; Expires=Tue, 22-May-2018 16:06:04 UTC strict-transport-security: max-age=631138519 x-connection-hash: fcf0a8e18ecc1a28f22e30285de55fe0 x-response-time: 121

HTTP/1.1 200 OK cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0 content-length: 255393 content-security-policy: script-src https://connect.facebook.net https://cm.g.doubleclick.net https://ssl.google-analytics.com https://graph.facebook.com 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 'nonce-grHpCTpdmetRD4mMTtwgmA==' https://www.google.com https://t.tellapart.com https://platform.twitter.com https://www.google-analytics.com '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://twitter.com https://*.twimg.com https://ton.twitter.com blob: 'self'; connect-src https://graph.facebook.com https://*.giphy.com https://*.twimg.com https://pay.twitter.com https://analytics.twitter.com https://media.riffsy.com https://upload.twitter.com https://api.mapbox.com 'self'; 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://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 'self' https://donate.twitter.com; img-src https://graph.facebook.com https://*.giphy.com https://twitter.com https://*.twimg.com data: 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://stats.g.doubleclick.net https://*.tiles.mapbox.com https://www.google-analytics.com blob: 'self'; 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: Sun, 22 May 2016 16:06:05 GMT expires: Tue, 31 Mar 1981 05:00:00 GMT last-modified: Sun, 22 May 2016 16:06:04 GMT pragma: no-cache server: tsa_d set-cookie: fm=0; Expires=Sun, 22 May 2016 16:05:54 GMT; Path=/; Domain=.twitter.com; Secure; HTTPOnly set-cookie: _twitter_sess=BAh7CSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%250ASGFzaHsABjoKQHVzZWR7ADoPY3JlYXRlZF9hdGwrCKtcN9lUAToMY3NyZl9p%250AZCIlOGVhNjNkOTRjZWQ4ZDg4YzQ0MTFiMzc5MzM3MjRjMTI6B2lkIiVmYTRl%250AZmZjMGM1MzNkN2Y0YWUyODAwZTcwOGI2NmRmYg%253D%253D--7ff51585db5754a6c35882f921ea30fa98ef7d9f; Path=/; Domain=.twitter.com; Secure; HTTPOnly set-cookie: guest_id=v1%3A146393316461963429; Domain=.twitter.com; Path=/; Expires=Tue, 22-May-2018 16:06:04 UTC status: 200 OK strict-transport-security: max-age=631138519 x-connection-hash: 8f6fcd1089ed5b7edb3f837fb0a42d28 x-content-type-options: nosniff x-frame-options: SAMEORIGIN x-response-time: 495 x-transaction: cbe2aac34e0865e5 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 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 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/ Connection: close

HTTP/1.1 200 OK Server: GitHub.com Date: Sun, 22 May 2016 16:06:43 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=Thu, 22 May 2036 16:06:43 -0000; secure; HttpOnly Set-Cookie: _gh_sess=eyJzZXNzaW9uX2lkIjoiMThjNGQxMDg2ZGIzMTMzNzliZmE5Zjk2NmM2Y2NjNDUiLCJfY3NyZl90b2tlbiI6Ill1aWJraDVFZDZhUFBzNTU0MnJyTWh1Qkk5UC9tRGN0eFZaWlMvYXd1aHM9In0%3D--088e76dc9d04769096885e47245d5257cccdd05d; path=/; secure; HttpOnly X-Request-Id: 4a657bc2248311cfded00c09766a48f1 X-Runtime: 0.010857 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 api.github.com www.google-analytics.com github-cloud.s3.amazonaws.com wss://live.github.com; font-src assets-cdn.github.com; form-action 'self' github.com gist.github.com; frame-ancestors 'none'; frame-src render.githubusercontent.com; img-src 'self' data: assets-cdn.github.com identicons.github.com www.google-analytics.com collector.githubapp.com *.gravatar.com *.wp.com *.githubusercontent.com; media-src 'none'; object-src assets-cdn.github.com; plugin-types application/x-shockwave-flash; 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=5184000; 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 Vary: Accept-Encoding X-Served-By: d41662224d8c44f09604b862e979767a X-GitHub-Request-Id: B36F2320:987D:E88A2AC:5741D913

=Best Practices=

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.

Response Headers

 * HTTP Strict Transport Security (HSTS)
 * Public Key Pinning Extension for HTTP (HPKP)
 * X-Frame-Options
 * X-XSS-Protection
 * X-Content-Type-Options
 * Content-Security-Policy
 * X-Permitted-Cross-Domain-Policies
 * Referrer-Policy

HTTP Strict Transport Security (HSTS)

 * Apache
 * Edit your apache configuration file and add the following to your VirtualHost.


 * nginx
 * Edit your nginx configuration file and add the following snippet.


 * lighttpd
 * Edit your lighttpd configuration file and add the following snippet.


 * IIS
 * Visit https://scotthelme.co.uk/hardening-your-http-response-headers/#strict-transport-security

Public Key Pinning Extension for HTTP (HPKP)

 * Apache
 * Edit your apache configuration file and add the following to your VirtualHost.


 * nginx
 * Edit your nginx configuration file and add the following snippet.


 * lighttpd
 * Edit your lighttpd configuration file and add the following snippet.


 * IIS
 * Visit https://scotthelme.co.uk/hardening-your-http-response-headers/#public-key-pinning

X-Frame-Options

 * Apache
 * Add this line below into your site's configuration to configure Apache to send X-Frame-Options header for all pages.


 * nginx
 * Add snippet below into configuration file to send X-Frame-Options header.


 * lighttpd
 * Add snippet below into configuration file to send X-Frame-Options header.


 * IIS
 * Visit https://scotthelme.co.uk/hardening-your-http-response-headers/#x-frame-options

X-XSS-Protection
Add appropriate snippet into configuration file.


 * Apache


 * nginx


 * lighttpd


 * IIS
 * Visit https://scotthelme.co.uk/hardening-your-http-response-headers/#x-xss-protection

X-Content-Type-Options
Add appropriate snippet into configuration file.


 * Apache


 * nginx


 * lighttpd


 * IIS
 * Visit https://scotthelme.co.uk/hardening-your-http-response-headers/#x-content-type-options

Content-Security-Policy
Add appropriate snippet into configuration file.


 * Apache


 * nginx


 * lighttpd


 * IIS
 * Visit https://scotthelme.co.uk/hardening-your-http-response-headers/#content-security-policy

X-Permitted-Cross-Domain-Policies
Add appropriate snippet into configuration file.


 * Apache


 * nginx


 * lighttpd


 * IIS
 * [update needed]

Referrer-Policy

 * Apache
 * [update needed]


 * nginx
 * [update needed]


 * lighttpd
 * [update needed]


 * IIS
 * [update needed]

=FAQs=


 * What is HTTP header?
 * HTTP header fields are part of HTTP message defined in RFC 2616 that consists of requests from client to server and responses from server to client that define parameters for the communication process including: language, compression support, security and a lot of resources.


 * Is there a standard for HTTP headers?
 * A core set of fields is standardized by the Internet Engineering Task Force (IETF) in RFCs 7230, 7231, 7232, 7233, 7234, and 7235. The permanent registry of header fields and repository of provisional registrations are maintained by the IANA. Additional field names and permissible values may be defined by each application. Non-standard header fields were conventionally marked by prefixing the field name with X- but this convention was deprecated in June 2012 because of the inconveniences it caused when non-standard fields became standard. An earlier restriction on use of Downgraded- was lifted in March 2013.


 * Why I need worry about that?
 * Like other initiatives supported by OWASP, this project have the objetive to help all community to conceive, develop, acquire, operate and maintain applications that can be trusted as provide useful information about the use relative of secure http headers by applications and platforms supported.


 * Where can apply secure features presented by this project?
 * The effectiveness provides by secure http headers demands that application or some component of infrastructure indicate proper header and correspondent value as like use of some client that implement that feature.


 * When I consider apply this improvements?
 * The short response it's right now. However we believe in approach more responsible. So we recommend conducting a planning and preliminary study, as well the incremental inclusion of insurance headers.


 * Headers like: Public Key Pinning Extension for HTTP (HPKP), HTTP Strict Transport Security (HSTS) and Content Security Policy (CSP) need a special attention in order not to cause any incident. Some real cases about to use of secure headers can be seen:


 * - Secure websites shun HTTP Public Key Pinning
 * - HTTP Public Key Pinning: You’re doing it wrong!
 * - CSP On Reporting and Filtering
 * - Content Security Policy (CSP)


 * Who can be responsible to apply secure features?
 * The responsability to provides more secure environment it's a effort that envolve developers, system administrators, vendors of web browsers and end user.


 * Like this the success of secure headers strategy depends of proper client, in general a web browser, and web application or some infrastructure component configured appropriately.


 * How can I apply secure http headers?
 * The use of secure headers can occur directly through of handling http response headers or using some framework, in addition to conducting appropriate configuration in web server.


 * The OWASP: Secure Headers project provides a list of resources and examples to help understand, analyze and configure secure headers.


 * What's the costs relative to apply this actions?
 * There's no costs in to use secure headers. However some effort to configure and manage properly configuration will be necessary.

= Acknowledgements =

Contributors
OWASP Secure Headers Project is developed by a worldwide team of volunteers. The primary contributors to date have been:


 * Ricardo Iramar
 * Jim Manico
 * Alexandre Menezes

= Road Map and Getting Involved =

Involvement in the development and promotion of OWASP Secure Headers Project is actively encouraged! You do not have to be a security expert in order to contribute. If you want to help send an email to [mailto:ricardo.iramar@owasp.org ricardo.iramar@owasp.org].

To Do

 * Perform public to scan websites and view stats regarding these headers. Automated scanning of the top 1m sites on the web; filtering of said sites to view stats across industries and countries; published database dumps for public consumption/tools; scanning of individual sites; comparing multiple scanned sites.
 * Consistent reports regarding this secure headers, their usage, any changes to existing headers.
 * Reorganize "Best Practices" tab and include a section for related security best practices around headers (e.g. "Remove Server Header" and "Remove X-Powered-By Header".
 * Create a parser to grab the headers from https://scans.io and populate the MySQL database.

Doing

 * Producing open source, easily implemented, well documented code libraries that enable these headers for a variety of platforms. We'll prioritize creating and publicizing Node.JS, PHP, Ruby, and Java, but will eventually reach out towards edge cases like Go, Python and others. The key is to make this accessible as possible to developers.
 * Including how to set properly secure headers on IIS.
 * Improve constantly hsecscan tool to detect bad practices and provide link to the best practices above.

Done

 * Creating secure best practices implementations including how to set properly secure headers on the most common platforms (eg. Apache, NGINX and Lighttpd).
 * Divide the "Tools_and_Libraries" tab into two differents tab (Scanners and Libraries).
 * Include link to attack pages.
 * Include Top Websites Examples tab.
 * Move the Best Practices to another tab.
 * Include a new tab only for browser versions compatibility.
 * Include X-Permitted-Cross-Domain-Policies under Headers and Best Practices tab.