OWASP Secure Headers Project
Introduction
π― The OWASP Secure Headers Project (also called OSHP) 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?
Description
π The OWASP Secure Headers Project aim to provide elements about the following aspects regarding HTTP security headers:
- Guidance about the recommended HTTP security headers that can be leveraged.
- Guidance about the HTTP headers that should be removed.
- Tools to validate an HTTP security header configuration.
- Code libraries that can be leveraged to configure recommended HTTP security headers.
- Statistics about usage of the recommended HTTP security headers.
π All the tools provided by the OSHP are gathered under this GitHub organization.
πΊ A presentation of the project is available on the following locations:
- OWASP Spotlight Youtube playlists.
- Application Security Podcast Youtube playlists.
- NoLimitSecu Podcast (French).
Migration
π The OWASP Secure Headers Project was migrated from the old website to the GitHub OWASP organization.
π¦ The following projects are now archived, they are initiatives that are now replaced by new projects:
Security headers usage statistics
π We provide statistics, updated every month, about HTTP response security headers usage mentioned by the OWASP Secure Headers Project:
- They are available through this GitHub project.
Security headers usage validator
β We provide a venom tests suite to validate an HTTP security response header configuration against OWASP Secure Headers Project recommendation:
- It is available through this GitHub project.
π§ͺ We also provide a online mock endpoint returning an HTTP response, for which, all HTTP response headers recommended by the OSHP will be set:
- It is automatically deployed on
https://oshp-validator-mock.onrender.com
- Technical details about this endpoint are here.
Security headers reference files
π As mentioned in previous sections, we provide the collection of HTTP response security headers to add as well as HTTP response headers to remove, both in table form.
π‘ Additionally, we provide this information as two JSON files to enable automation in the context of a provisioning workflow:
- Collection of HTTP response security headers to add.
- Collection of HTTP response headers to remove.
π‘ These json files are automatically updated.
Technical references health dashboard
π We automatically generate and monitor this dashboard to identify any dead project referenced in the Technical Resources tab.
Discussions, information and roadmap
π¬ We use the GitHub discussions feature for discussions about the project as well as spreading global information about it.
π©βπ» The work on the OSHP projects and associated components is tracked using the GitHub project feature.
Notification of update
π‘ This atom web feed can be used to be notified when an update is pushed on the OSHP websiteβs repository.
Create a link to the OSHP site
π This is documented into the Case Studies tab.
Contributors
π Contributors to OSHP, before the migration of the project to GitHub:
π Visit this page for updated information about the contributors since the migration of the project to GitHub.
Licensing
π This project content is free to use. It is licensed under the Apache 2.0 License.
Response Headers
π¦ Header lifecycle flow:
π Working draft
β Active
- Strict-Transport-Security
- X-Frame-Options
- X-Content-Type-Options
- Content-Security-Policy
- X-Permitted-Cross-Domain-Policies
- Referrer-Policy
- Clear-Site-Data
- Cross-Origin-Embedder-Policy
- Cross-Origin-Opener-Policy
- Cross-Origin-Resource-Policy
- Cache-Control
β° Almost deprecated
None
β Deprecated
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 standard 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).
π Important note about the behavior of the header over a HTTP connection (source Mozilla MDN):
- The
Strict-Transport-Security
header is ignored by the browser when your site has only been accessed using HTTP. - Once your site is accessed over HTTPS with no certificate errors, the browser knows your site is HTTPS capable and will honor the
Strict-Transport-Security
header.
π‘ If you need to let the access open, via HTTP, to the web server but want to ensure that Strict-Transport-Security
header is taken into account for your site then you can use the preload directive.
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. |
preload |
If this optional parameter is specified, its instruct the browser to always access the site using HTTPS because the site is included into Strict-Transport-Security preload list. |
Example
Strict-Transport-Security: max-age=31536000
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Strict-Transport-Security: max-age=31536000 ; includeSubDomains ; preload
References
- https://tools.ietf.org/html/rfc6797
- https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Strict_Transport_Security_Cheat_Sheet.html
- https://owasp.org/www-project-web-security-testing-guide/stable/4-Web_Application_Security_Testing/02-Configuration_and_Deployment_Management_Testing/07-Test_HTTP_Strict_Transport_Security.html
- https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
- https://www.chromium.org/hsts
- https://hstspreload.org/
- https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security
- https://raymii.org/s/tutorials/HTTP_Strict_Transport_Security_for_Apache_NGINX_and_Lighttpd.html
- https://blogs.windows.com/msedgedev/2015/06/09/http-strict-transport-security-comes-to-internet-explorer-11-on-windows-8-1-and-windows-7/
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 Content-Security-Policy (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 (not supported by modern browsers). |
Example
X-Frame-Options: deny
References
- https://tools.ietf.org/html/rfc7034
- https://tools.ietf.org/html/draft-ietf-websec-x-frame-options-01
- https://tools.ietf.org/html/draft-ietf-websec-frame-options-00
- https://developer.mozilla.org/en-US/docs/Web/HTTP/X-Frame-Options
- https://portswigger.net/web-security/clickjacking
- https://blogs.msdn.microsoft.com/ieinternals/2010/03/30/combating-clickjacking-with-x-frame-options/
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors
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
- https://msdn.microsoft.com/en-us/library/gg622941%28v=vs.85%29.aspx
- https://blogs.msdn.microsoft.com/ie/2008/09/02/ie8-security-part-vi-beta-2-update/
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
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
- https://www.w3.org/TR/CSP/
- https://developer.mozilla.org/en-US/docs/Web/Security/CSP
- https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html
- https://scotthelme.co.uk/content-security-policy-an-introduction/
- https://report-uri.io
- https://content-security-policy.com
- https://report-uri.com/home/generate
- https://csp-evaluator.withgoogle.com/
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
- https://www.adobe.com/devnet-docs/acrobatetk/tools/AppSec/xdomain.html
- https://danielnixon.org/http-security-headers/
- https://rorsecurity.info/portfolio/new-http-headers-for-more-security
- https://github.com/twitter/secureheaders/issues/88
- https://gf.dev/cross-domain-policy-test
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 same-origin or cross-origin request. |
Example
Referrer-Policy: no-referrer
References
- https://www.w3.org/TR/referrer-policy/
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
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
- https://w3c.github.io/webappsec-clear-site-data/
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data
- https://www.chromestatus.com/feature/4713262029471744
- https://github.com/w3c/webappsec-clear-site-data
- https://github.com/w3c/webappsec-clear-site-data/tree/master/demo
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).
π‘ To fully understand where CORP and COEP work:
- CORP applies on the loaded resource side (resource owner).
- COEP applies on the βloaderβ of the resource side (consumer of the resource).
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
- https://fetch.spec.whatwg.org/#cross-origin-resource-policy-header
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy
- https://caniuse.com/mdn-http_headers_cross-origin-resource-policy
- https://web.dev/articles/why-coop-coep#corp
- https://web.dev/articles/cross-origin-isolation-guide
- https://resourcepolicy.fyi/
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).
π‘ To fully understand where CORP and COEP work:
- CORP applies on the loaded resource side (resource owner).
- COEP applies on the βloaderβ of the resource side (consumer of the resource).
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
- https://html.spec.whatwg.org/multipage/origin.html#coep
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy
- https://caniuse.com/mdn-http_headers_cross-origin-embedder-policy
- https://web.dev/articles/why-coop-coep#coep
- https://web.dev/articles/cross-origin-isolation-guide
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
- https://html.spec.whatwg.org/multipage/origin.html#cross-origin-opener-policies
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy
- https://caniuse.com/mdn-http_headers_cross-origin-opener-policy
- https://web.dev/articles/why-coop-coep#coop
- https://web.dev/articles/cross-origin-isolation-guide
- https://github.com/xsleaks/xsleaks
- https://portswigger.net/daily-swig/xs-leak
- https://portswigger.net/research/xs-leak-detecting-ids-using-portal
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 recommended 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
- https://redbot.org
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Pragma
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching
- https://datatracker.ietf.org/doc/html/rfc7234
- https://cwe.mitre.org/data/definitions/524.html
- https://cwe.mitre.org/data/definitions/525.html
- https://portswigger.net/web-security/web-cache-poisoning
- https://portswigger.net/research/practical-web-cache-poisoning
- https://portswigger.net/research/web-cache-entanglement
- https://portswigger.net/web-security/web-cache-deception
- https://portswigger.net/research/gotta-cache-em-all
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
π§ As the specification is still under development, it is better to consult this page to obtain the current list of supported directives.
Example
Permissions-Policy: accelerometer=(),ambient-light-sensor=(),autoplay=(),battery=(),camera=(),display-capture=(),document-domain=(),encrypted-media=(),fullscreen=(),gamepad=(),geolocation=(),gyroscope=(),layout-animations=(self),legacy-image-formats=(self),magnetometer=(),microphone=(),midi=(),oversized-images=(self),payment=(),picture-in-picture=(),publickey-credentials-get=(),speaker-selection=(),sync-xhr=(self),unoptimized-images=(self),unsized-media=(self),usb=(),screen-wake-lock=(),web-share=(),xr-spatial-tracking=()
References
- https://github.com/w3c/webappsec-permissions-policy/blob/main/permissions-policy-explainer.md
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy#directives
- https://caniuse.com/permissions-policy
- https://www.w3.org/TR/permissions-policy-1/
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy
- https://www.chromestatus.com/feature/5745992911552512
- https://www.permissionspolicy.com/
Feature-Policy
Deprecated: Replaced by the header Permissions-Policy.
Feature Policy allows web developers to selectively enable, disable, and modify the behavior of certain features and APIs in the browser. It is similar to Content Security Policy but controls features instead of security behavior (Source Mozilla MDN).
Values
Refer to this page to obtains the list of supported directives.
Example
Feature-Policy: vibrate 'none'; geolocation 'none'
References
- https://w3c.github.io/webappsec-feature-policy/
- https://scotthelme.co.uk/a-new-security-header-feature-policy/
- https://github.com/w3c/webappsec-feature-policy/blob/master/features.md
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy
- https://caniuse.com/feature-policy
Expect-CT
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
- https://datatracker.ietf.org/doc/html/rfc9163
- https://scotthelme.co.uk/a-new-security-header-expect-ct/
- https://www.chromestatus.com/feature/5677171733430272
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
- https://tools.ietf.org/html/rfc7469
- https://owasp.org/www-community/controls/Certificate_and_Public_Key_Pinning#HTTP_pinning
- https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning
- https://developer.mozilla.org/en-US/docs/Web/Security/Public_Key_Pinning
- https://raymii.org/s/articles/HTTP_Public_Key_Pinning_Extension_HPKP.html
- https://labs.detectify.com/2016/07/05/what-hpkp-is-but-isnt/
- https://blog.qualys.com/ssllabs/2016/09/06/is-http-public-key-pinning-dead
- https://scotthelme.co.uk/im-giving-up-on-hpkp/
- https://groups.google.com/a/chromium.org/forum/m/#!msg/blink-dev/he9tr7p3rZ8/eNMwKPmUBAAJ
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 useContent-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
- https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
- https://www.chromestatus.com/feature/5021976655560704
- https://bugzilla.mozilla.org/show_bug.cgi?id=528661
- https://blogs.windows.com/windowsexperience/2018/07/25/announcing-windows-10-insider-preview-build-17723-and-build-18204/
- https://github.com/zaproxy/zaproxy/issues/5849
- https://scotthelme.co.uk/security-headers-updates/#removing-the-x-xss-protection-header
- https://portswigger.net/daily-swig/google-chromes-xss-auditor-goes-back-to-filter-mode
- https://owasp.org/www-community/attacks/xss/
- https://www.virtuesecurity.com/blog/understanding-xss-auditor/
- https://www.veracode.com/blog/2014/03/guidelines-for-setting-security-headers
- http://zinoui.com/blog/security-http-headers#x-xss-protection
Pragma
Deprecated.
The Pragma
HTTP/1.0 general header is an implementation-specific header that may have various effects along the request-response chain.
This header serves for backwards compatibility with the HTTP/1.0 caches that do not have a Cache-Control HTTP/1.1 header (source Mozilla MDN).
Values
Value | Description |
---|---|
no-cache |
Same as Cache-Control: no-cache . Forces caches to submit the request to the origin server for validation before a cached copy is released. |
Example
Pragma: no-cache
References
Browser Support
π A reference is provided, for each header, to a site always providing up-to-date information.
Best Practices
- Configuration proposal
- Prevent information disclosure via HTTP headers
- Prevent exposure to cross-site scripting when hosting uploaded files
- Prevent CORS misconfiguration issues
- Prevent information disclosure via the browser local cached files
- Prevent CSP bypasses
Configuration proposal
Please note the best practices below suggest methods to change web server 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 proposes a configuration for the actively supported and working draft security headers.
π‘ Additional information about HTTP security headers on OpenCRE.
π The headers proposed below can be applied both in the context of a classic web application and in that of a web API.
π© The header Clear-Site-Data
will cause the browser to take additional processing time for the HTTP response, so, set it to the logout function when possible.
π¬ For the header Permissions-Policy
, as it is currently only supported by Chromium based browsers, the proposed value was generated with this site and tested against the version 128.0.6606.0
of Chromium to only specify supported features.
π‘ Content of the table below is also provided, as JSON, via this file (automatically updated).
Header name | Proposed value |
---|---|
Strict-Transport-Security | max-age=31536000; includeSubDomains |
X-Frame-Options | deny |
X-Content-Type-Options | nosniff |
Content-Security-Policy | default-src 'self'; form-action 'self'; object-src 'none'; 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 | require-corp |
Cross-Origin-Opener-Policy | same-origin |
Cross-Origin-Resource-Policy | same-origin |
Permissions-Policy | accelerometer=(), autoplay=(), camera=(), cross-origin-isolated=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), unload=() |
Cache-Control | no-store, max-age=0 |
Prevent information disclosure via HTTP headers
This section provides a collection of HTTP response headers to remove, when possible, from any HTTP response to prevent any disclosure of technical information about environment. The following list of headers can be used to configure a reverse proxy or a web application firewall to handle removal operation of the mentioned headers.
π‘ Additional information about technical information disclosure in HTTP header on OpenCRE.
π‘ When an HTTP response header is known by the analytics site WebTechSurvey, then, a reference link is added to its usage statistics page. Otherwise, a reference link regarding the documentation of the header is provided.
π© The response header Content-Type
can sometimes discloses the web framework used. It is the case for the following ones:
- Spring Boot Actuator REST API:
Content-Type: application/vnd.spring-boot.actuator.v3+json
.
π‘ Content of the table below is also provided, as JSON, via this file (automatically updated).
Header name | Header value example | Description |
---|---|---|
Server | Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips |
Contain information about the server handling the request. |
Liferay-Portal | Liferay Digital Experience Platform 7.2.10 GA1 |
Contain the version of the Liferay software in use. |
X-Turbo-Charged-By | LiteSpeed/5.4.12 Enterprise |
Contain information about the server handling the request. |
X-Powered-By | PHP/5.3.3 |
Contain information about hosting environments or other frameworks in use. |
X-Server-Powered-By | Engintron |
Contain information about hosting environments or other frameworks in use. |
X-Powered-CMS | Bitrix Site Manager (DEMO) |
Contain the information about the CMS that generated the HTTP response. |
SourceMap | https://mysite.com/js/mylib.js.map |
Links generated code to a source map file, enabling the browser to reconstruct the original source and present the reconstructed original in the debugger. |
X-SourceMap | https://mysite.com/js/mylib.js.map |
Links generated code to a source map file, enabling the browser to reconstruct the original source and present the reconstructed original in the debugger. |
X-AspNetMvc-Version | 5.2 |
Contain the version of the ASP .Net MVC framework in use. |
X-AspNet-Version | 4.0.30319 |
Contain the version of the ASP .Net framework in use. |
X-SourceFiles | =?UTF-8?B?QzpcVXNlcnN?= |
Contain information needed by the .Net SDK debugger during debugging operation on a project. |
X-Redirect-By | TYPO3 Shortcut/Mountpoint |
Specifies the component that is responsible for a particular redirect (source Wikipedia). |
X-Generator | Drupal 8 |
Contain the information about the CMS that generated the HTTP response. |
X-Generated-By | Smartsite version 7.11.1.3 |
Contain the information about the CMS that generated the HTTP response. |
X-CMS | Thinq CMS 1.7.0.0 |
Contain the information about the CMS that generated the HTTP response. |
X-Powered-By-Plesk | PleskLin or PleskWin |
Indicate that the platform is based on the Plesk software in addition to the underlying operating system. |
X-Php-Version | 7.4 |
Indicate the version of PHP technology used. |
Powered-By | PrestaShop |
Indicate the name of the framework or platform used. |
X-Content-Encoded-By | Joomla! 2.5 |
Indicate the name of the framework or platform used. |
Product | Z-BlogPHP 1.7.2 |
Indicate the name of the framework or platform used. |
X-CF-Powered-By | CF-Joomla 0.1.5 |
Indicate the name of the framework or platform used. |
X-Framework | JP/4.01 |
Indicate the name of the framework or platform used. |
Host-Header | owasp.org |
Indicate which virtual host of the web server the response is coming from. |
Pega-Host | srv-pega11 |
Indicate the internal host name of the server that handled the request in the context of usage of a software from the PEGA company. |
X-Atmosphere-first-request | true |
Indicate that the java framework Atmosphere is used. |
X-Atmosphere-tracking-id | 7852fcbf-f8a9-4667-9dcc-a0b5b162499c |
Indicate that the java framework Atmosphere is used. |
X-Atmosphere-error | Websocket protocol not supported |
Indicate that the java framework Atmosphere is used. |
X-Mod-Pagespeed | 1.13.35.2-0 |
Indicate the presence of the Apache module mod_pagespeed in the call flow. |
X-Page-Speed | 1.13.35.2-0 |
Indicate the presence of the Nginx module mod_pagespeed in the call flow. |
X-Varnish-Backend | pb01 |
Indicate the name of the backend server from which the Varnish instance will accelerate the content. |
X-Varnish-Server | proxy01 |
Indicate the name of the Varnish server instance that provided the accelerated content. |
X-Envoy-Upstream-Service-Time | 42 |
Indicate the presence of the proxy software Envoy in the call flow. |
X-Envoy-Attempt-Count | 1 |
Indicate the presence of the proxy software Envoy in the call flow. |
X-Envoy-External-Address | 124.128.159.165 |
Indicate the presence of the proxy software Envoy in the call flow. |
X-Envoy-Internal | true |
Indicate the presence of the proxy software Envoy in the call flow. |
X-Envoy-Original-Dst-Host | 10.195.16.237:8888 |
Indicate the presence of the proxy software Envoy in the call flow. |
X-B3-ParentSpanId | dea3f6d0324583db |
Indicate the presence of the software Zipkin that is a distributed tracing system. |
X-B3-Sampled | 0 |
Indicate the presence of the software Zipkin that is a distributed tracing system. |
X-B3-SpanId | 244753d494e83353 |
Indicate the presence of the software Zipkin that is a distributed tracing system. |
X-B3-TraceId | 11bef07b0f5c0468 |
Indicate the presence of the software Zipkin that is a distributed tracing system. |
K-Proxy-Request | activator |
Indicate the presence of the software Knative that is an Open-Source Enterprise-level solution to build Serverless and Event Driven Applications in Kubernetes environments. |
X-Old-Content-Length | 135 |
Indicate the presence of the software WebSEAL that is a high performance, multithreaded web server by IBM. |
$wsep | empty value |
Indicate the presence of the software WebSphere Application Server that is a JavaEE application server by IBM. |
X-Nextjs-Matched-Path | /blog |
Indicate that the web framework Next.js is used. |
X-Nextjs-Page | /articles |
Indicate that the web framework Next.js is used. |
X-Nextjs-Cache | REVALIDATED |
Indicate that the web framework Next.js is used. |
X-Nextjs-Redirect | /home |
Indicate that the web framework Next.js is used. |
X-OneAgent-JS-Injection | true |
Indicate that the Dynatrace analytics and automation platform is used. |
X-ruxit-JS-Agent | true |
Indicate that the Dynatrace analytics and automation platform is used. |
X-dtHealthCheck | Technical diagnostic data |
Indicate that the Dynatrace analytics and automation platform is used. |
X-dtAgentId | 95b3121c36 |
Indicate that the Dynatrace analytics and automation platform is used. |
X-dtInjectedServlet | com.company.ReportServlet |
Indicate that the Dynatrace analytics and automation platform is used. |
X-Litespeed-Cache-Control | no-cache |
Indicate the presence of the LiteSpeed web server. |
X-LiteSpeed-Purge | /phpinfo.php |
Indicate the presence of the LiteSpeed web server. |
X-LiteSpeed-Tag | pubtag1,pubtag2 |
Indicate the presence of the LiteSpeed web server. |
X-LiteSpeed-Vary | value=ismobile |
Indicate the presence of the LiteSpeed web server. |
X-LiteSpeed-Cache | hit,litemage |
Indicate the presence of the LiteSpeed web server. |
X-Umbraco-Version | 4.7 |
Indicate the usage of the Umbraco CMS software as well as its version. |
OracleCommerceCloud-Version | 23.08.01 |
Indicate the usage of the Oracle Commerce software as well as its version. |
X-BEServer | EXSRV01 |
Indicate the internal host name of the server that handled the request in the context of usage of the Microsoft Exchange software. |
X-DiagInfo | EXSRV01 |
Indicate the internal host name of the server that handled the request in the context of usage of the Microsoft Exchange software. |
X-FEServer | EXSRV01 |
Indicate the internal host name of the server that handled the request in the context of usage of the Microsoft Exchange software. |
X-CalculatedBETarget | exsrv01.mydomain.com |
Indicate the internal host name of the server that handled the request in the context of usage of the Microsoft Exchange software. |
X-OWA-Version | 15.2.1258.27 |
Indicate the version of the Microsoft Exchange software in use. |
X-Cocoon-Version | 2.1.13 |
Indicate that the web framework Apache Cocoon is used as well as the version used. |
X-Kubernetes-PF-FlowSchema-UI | cf931e2d-5a5e-4c12-892c-9bafa71f30dc |
Indicate that the web application issuing the HTTP response is deployed on a Kubernetes cluster. |
X-Kubernetes-PF-PriorityLevel-UID | 78b3face-e1cf-4fc6-a27e-08eb7f0f5b23 |
Indicate that the web application issuing the HTTP response is deployed on a Kubernetes cluster. |
X-Jitsi-Release | 5082 |
Indicate the version of Jitsi software in use. |
X-Joomla-Version | 3.9.25 |
Indicate that the CMS Joomla is used as well as the version used. |
X-Backside-Transport | OK OK |
Indicate the presence of the products IBM WebSphere DataPower in the call flow. |
Prevent exposure to cross-site scripting when hosting uploaded files
This section describes, how the HTTP response header named Content-Disposition, can be used to prevent exposure to cross-site scripting when hosting uploaded files and opening them in the same web browsing context than the application.
It can happen a case in which an application allows a user to upload a file and then allow this file to be accessed by other users. If such feature allows uploading of HTML files (also apply for SVG file) then it can be used, as a vector, to store an HTML file containing JavaScript code. Therefore, the feature become prone to stored cross-site scripting vulnerability.
To prevent this exposure, the HTTP response header named Content-Disposition, can be used with the following value to instruct browsers to download the file instead of open it in the same web browsing context than the application:
Content-Disposition: attachment; filename="myfile.html"
Prevent CORS misconfiguration issues
π An excellent tutorial about Cross-Origin Resource Sharing (called CORS) is provided on the Mozilla MDN. In addition, Julien Cretel provided a great blog post about CORS pitfalls.
This section proposes an approach to help preventing CORS misconfiguration issues using a simple idea: Provide the collection of CORS related HTTP response headers to use according to different contexts.
Key points to consider
- π‘ If the web framework/web server you are using provides CORS features then always leverage them instead of implements it manually:
- List of web framework/web server supporting CORS.
- CORS middleware for Go by Julien Cretel.
-
π© Whatever the context, when the request is a HTTP OPTIONS (preflight request) then the value provided by the following headers must be validated against expected values. If the validation failed then return an HTTP 403 without any CORS related HTTP response headers:
-
π© Validation of the
Origin
/Access-Control-Request-Method
/Access-Control-Request-Headers
request header value, against a list of allowed ones, must be performed using strict case sensitive string comparison to prevent, as much as possible, the presence of bypasses into the validation logic. If possible, does not use regular expression for the implementation of the validation, see here for an explanation of the source of this recommendation. -
π© CORS scope is the access control aspect, from a browser perspective (client side), regarding cross origins access to a resource. Thus, it does NOT replace the requirement to implements access control on the server side too. CORS and server-side access controls are complementary.
- π© Never take the value of the request header Origin to add it into the response header Access-Control-Allow-Origin (mirroring), see here for an explanation of the source of this recommendation. Indeed, always use a list of allowed origins when only a restricted collection of origins is expected to call your endpoints.
Contexts
Public without authentication
π¬ Context:
Your endpoints are expected to be consumed, by a browser, from any origins without any authentication.
π» Configuration proposal:
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Access-Control-Allow-Credentials: false
Public with authentication
π¬ Context:
Your endpoints are expected to be consumed, by a browser, from any origins with authentication.
π© The value *
, for the response header Access-Control-Allow-Origin
, cannot be used when the response header Access-Control-Allow-Credentials
is allowed (true
). Indeed, the browser raises the following error (tested on Chrome 118.x):
The value of the 'Access-Control-Allow-Origin' header in the response must not be
the wildcard '*' when the request's credentials mode is 'include'.
π It is explicitly mentioned, into the Mozilla MDN documentation, as the following:
When responding to a "credentialed request" request, the server must specify an origin in the value
of the Access-Control-Allow-Origin header, instead of specifying the "*" wildcard.
Therefore, refer to the restricted with authentication case for the configuration to use.
Restricted without authentication
π¬ Context:
Your endpoints are expected to be consumed, by a browser, from a specific collection of origins without any authentication.
π» Configuration proposal:
- If the value of the request header Origin is present into the list of allowed Origins then:
Access-Control-Allow-Origin: [Value_Taken_From_The_List_Of_Allowed_Origins]
Access-Control-Max-Age: 10
Access-Control-Allow-Credentials: false
- Otherwise return an HTTP 403 without any CORS related HTTP response headers.
Restricted with authentication
π¬ Context:
Your endpoints are expected to be consumed, by a browser, from a specific collection of origins with authentication.
π» Configuration proposal:
- If the value of the request header Origin is present into the list of allowed Origins then:
Access-Control-Allow-Origin: [Value_Taken_From_The_List_Of_Allowed_Origins]
Access-Control-Max-Age: 10
Access-Control-Allow-Credentials: true
- Otherwise return an HTTP 403 without any CORS related HTTP response headers.
Test CORS configuration
The tools nuclei can be used, via the template named cors-misconfig, to test a CORS configuration.
π» Command to use:
$ nuclei -silent -template-id cors-misconfig -u https://domain.com
[cors-misconfig:arbitrary-origin] [http] [info] https://domain.com [...]
References
- https://portswigger.net/web-security/cors
- https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
- https://jub0bs.com/posts/2023-02-08-fearless-cors/
- https://enable-cors.org/
- https://developer.mozilla.org/en-US/docs/Glossary/Origin
- https://cwe.mitre.org/data/definitions/942.html
- https://cwe.mitre.org/data/definitions/346.html
- OWASP WSTG - Testing Cross Origin Resource Sharing
- https://pkg.go.dev/github.com/jub0bs/cors
Prevent information disclosure via the browser local cached files
This section describes why it is important to specify a caching policy, via the Cache-Control HTTP response header, when sensitive information is managed by a web-based application.
Context
π¬ The application allows a user to access to documents containing information, considered sensitive, from a confidentiality perspective.
Letβs assume that the application returns the following HTTP response to a request, in which, no caching policy is defined:
HTTP/1.1 200 OK
accept-ranges: bytes
content-length: 433994
content-type: application/pdf
date: Sat, 30 Mar 2024 10:06:34 GMT
server: LiteSpeed
So, the browser will store a copy of the file (here a PDF one) into its cache storage for a certain amount of time.
π© Consequence: Any application running on the userβs computer, will be able to access to the file (at least if executed as the user identity or an administrator one) causing an exposure of the resource to non-expected entities.
πΊ This demonstration video show an example, of such information disclosure, via a file cached by the browser.
Configuration proposal
π» To prevent such issue, the following caching policy can be specified:
Cache-Control: no-store, max-age=0
π Where:
no-store
: Is used to indicate that the response may not be stored in any cache.max-age=0
: Is used to force the expiration of any cached version of the resources associated to the response.
π‘ The HTTP response header Clear-Site-Data can also be leveraged, in addition, to instruct the browser to remove any cached data related to the application.
Other vulnerabilities related to caching
π An excellent research and course content, about web cache poisoning, is provided by the PortSwigger team.
References
- https://redbot.org
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching
- https://caniuse.com/mdn-http_headers_cache-control
- https://cwe.mitre.org/data/definitions/525.html
- https://cwe.mitre.org/data/definitions/524.html
- OWASP WSTG - Testing for Browser Cache Weaknesses
- https://portswigger.net/kb/issues/00700100_cacheable-https-response
- https://portswigger.net/web-security/web-cache-poisoning
- https://portswigger.net/web-security/web-cache-deception
- https://portswigger.net/research/gotta-cache-em-all
Prevent CSP bypasses
This section describes some points, to keep in mind, during the creation of a Content-Security-Policy (called CSP) policy to prevent introducing bypasses.
π© Not every directives fallback to the default-src directive when it is not specified in the CSP policy.
Directive form-action
π It is the case for the form-action directive. Therefore, an html form can be used to bypass the CSP in place when the form-action
is not defined.
πΊ This demonstration video show an example.
π‘ Therefore, ensure to always specify the form-action
directive in a CSP policy to at least, the 'self'
value, to allow forms only on the current domain.
Directive frame-ancestors
π It is the case for the frame-ancestors directive. Therefore, IF it is not defined AND IF the header X-Frame-Options is not/incorrectly specified then the current domain can be embedded into a frame.
πΊ This demonstration video show an example.
π‘ Therefore, ensure to always specify the frame-ancestors
directive in a CSP policy to at least, the 'none'
value, to deny the current domain to be βframedβ.
Technical Resources
π This section provides a list of tools as well as documents to understand, analyze, develop and administer HTTP secure headers to help achieving more secure and trustworthy web systems.
- πΊ Presentations
- π Analysis Tools
- π©βπ» Development Libraries
Presentations
- Trap bad guys in your browser with HTTP security headers.
- How the Content-Security-Policy HTTP response header can save your romantic evening?
Analysis Tools
Tool | Description | Ref |
---|---|---|
hsecscan | A security scanner for HTTP response headers. | π©βπ» |
humble | A humble, and fast, security-oriented HTTP headers analyzer. | π©βπ» |
Mozilla Observatory | A Mozilla project designed to help developers, system administrators, and security professionals configure their sites safely and securely. | π / π©βπ» / π©βπ» |
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. | π©βπ» |
DrHEADer | DrHEADer helps with the audit of security headers received in response to a single request or a list of requests. | π©βπ» |
csp-evaluator | NPM module allowing developers and security experts to check if a Content Security Policy serves as a strong mitigation against XSS attacks. | π©βπ» |
Development Libraries
Java
Library | Description | Ref |
---|---|---|
Spring Security | Spring Securityβs support for adding various security headers to the response. | π |
DotNet
Library | Description | Ref |
---|---|---|
NWebsec | NWebsec consists of several security libraries for ASP.NET applications. | π |
NetEscapades.AspNetCore.SecurityHeaders | Small package to allow adding security headers to ASP.NET Core websites. | π©βπ» |
OwaspHeaders.Core | .NET Core middleware for injecting the OWASP recommended HTTP Headers for increased security | π©βπ» |
Ruby
Library | Description | Ref |
---|---|---|
secure_headers | Security related headers all in one gem. | π©βπ» |
PHP
Library | Description | Ref |
---|---|---|
SecureHeaders | A PHP class aiming to make the use of browser security features more accessible. | π©βπ» |
secure-headers | PHP Secure Headers for Laravel and non-Laravel projects. | π©βπ» |
NodeJS
Library | Description | Ref |
---|---|---|
helmet | Module to help secure Express apps with various HTTP headers. | π©βπ» |
ember-cli-content-security-policy | 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. | π©βπ» |
blankie | A CSP plugin for hapi. | π©βπ» |
Python
Library | Description | Ref |
---|---|---|
django-csp and django-security | Content Security Policy for Django. A collection of models, views, middlewares, and forms to help secure a Django project. | π©βπ» / π©βπ» |
Secweb | Secweb is a pack of security middlewares for fastApi and starlette server it includes CSP, HSTS, and many more. | π©βπ» |
secure | Lightweight library to add security headers to Django, Flask, FastAPI, and more. | π©βπ» |
Go
Library | Description | Ref |
---|---|---|
secure | HTTP middleware for Go that facilitates some quick security wins. | π©βπ» |
Rust
Library | Description | Ref |
---|---|---|
owasp-headers | Best-practice OWASP HTTP response headers for Rust. | π |
Code Snippets
π§Ύ The following code collection provides various code snippets to make working with HTTP security headers easier.
- Convert a Permissions-Policy back to Feature-Policy
- Test locally a Content-Security-Policy for weaknesses
- Generate configuration code using the OSHP headers reference files
- Quickly check security HTTP headers
- Syntax for adding HTTP response headers on different web servers
Convert a Permissions-Policy back to Feature-Policy
As the Permissions-Policy header is still in development and is not yet well supported, it can be interesting to use the two formats to increase the coverage of browsers according to their support level for Permissions-Policy and Feature-Policy policy headers.
The following python3 code snippet can be useful to achieve such conversion.
π Source for the conversion rules was this one.
π» Code snippet:
permissions_policy = 'fullscreen=(), geolocation=(self "https://game.com" "https://map.example.com"), gyroscope=(self), usb=*'
feature_policy_directives = []
# Collect directives
permissions_policy_directives = permissions_policy.split(",")
# Process each directive
for permissions_policy_directive in permissions_policy_directives:
# Remove leading and trailing spaces
directive = permissions_policy_directive.strip(" ")
# Remove all double quotes
directive = directive.replace("\"", "")
# Replace disabling expression () by the corresponding one in Feature-Policy
directive = directive.replace("()", "'none'")
# Quote keywords: self
directive = directive.replace("self", "'self'")
# Replace the equals affectation character by a space
directive = directive.replace("=", " ")
# Remove parenthesis
directive = directive.replace("(", "").replace(")", "")
# Add the current directive to the collection
feature_policy_directives.append(directive)
# Convert the collection of directives to a string with ; as directives separator
feature_policy = "; ".join(feature_policy_directives)
print(feature_policy)
π» Execution example:
$ python code.py
fullscreen 'none'; geolocation 'self' https://game.com https://map.example.com; gyroscope 'self'; usb *
Test locally a Content-Security-Policy for weaknesses
It can be interesting to validate locally a Content-Security-Policy for presence of weaknesses prior to apply it on deployed web applications.
The following JavaScript code snippet can be useful to achieve such validation by leveraging the csp-evaluator NPM module provided by Google.
π» Code snippet:
import {CspEvaluator} from "csp_evaluator/dist/evaluator.js";
import {CspParser} from "csp_evaluator/dist/parser.js";
const args = process.argv.slice(2)
if(args.length == 0){
console.error("[!] Missing CSP!");
}else{
const csp = args[0]
console.info(`[+] CSP to evaluate:\n${csp}`);
const parsed = new CspParser(csp).csp;
console.info(`[+] Evaluation results:`);
const results = new CspEvaluator(parsed).evaluate();
results.forEach(elt => {
let info = `[Directive '${elt.directive}' - Severity ${elt.severity}]: ${elt.description}`;
console.info(info);
});
}
π» Execution example:
$ node code.js "default-src 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests; block-all-mixed-content"
[+] CSP to evaluate:
default-src 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests; block-all-mixed-content
[+] Evaluation results:
[Directive 'default-src' - Severity 50]: 'self' can be problematic if you host JSONP, Angular or user uploaded files.
Generate configuration code using the OSHP headers reference files
The following bash code snippet, leveraging jq, can be used to generate configuration code using the OSHP headers reference files.
π» Code snippet and execution example:
# Generate the Nginx collection of instructions to add the recommended HTTP response headers
$ curl -sk https://owasp.org/www-project-secure-headers/ci/headers_add.json | jq -r '.headers[] | "add_header \(.name) \(.value);"'
add_header Cache-Control no-store, max-age=0;
add_header Clear-Site-Data "cache","cookies","storage";
add_header Cross-Origin-Embedder-Policy require-corp;
...
Quickly check security HTTP headers
The portable cross-platform tool Venom with the dedicated OSHP Validator test suites aligned with the OWASP Secure Headers Project can be used.
π» Use the following example set of commands:
$ venom run --var="target_site=https://mozilla.org" --var="logout_url=/logout" tests_suite.yml
β’ HTTP security response headers test suites
β’ 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.
β’ 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!
β’ 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.
β’ 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.
Syntax for adding HTTP response headers on different web servers
Apache
π» Directive:
Header always set [HEADER_NAME] [PROPOSED_VALUE]
π References:
Nginx
π» Directive:
add_header [HEADER_NAME] [PROPOSED_VALUE] always;
π References:
Lighttpd
π» Directive:
setenv.add-response-header = ("[HEADER_NAME]" => "[PROPOSED_VALUE]")
π References:
IIS
π» Directive:
<add name="[HEADER_NAME]" value="[PROPOSED_VALUE]" />
π References:
Miscellaneous
π‘ This section provides extra useful information about HTTP Security headers.
Request headers
Private Network Access request header
Description
The Private Network Access specification provides a feature allowing an application, located on a private address, to identify if the incoming HTTP request was sent from an application located on a public address.
π― The objective is to prevent attack, in which, a page hosted on a public network like, the Internet network, try to send a request to an application hosted on a private network:
π Source of the schema.
Example
π» Code of a page hosted on Internet on https://example.com/page.html
:
<!DOCTYPE html>
<html>
<header>
<title>Evil App</title>
</header>
<body>
<!--
We try to load an image from the router
deployed on the local private network.
-->
<img src="https://router.local/icon.svg">
</body>
</html>
π» Request sent by the browser when the page is loaded (tested on Chrome 116.x
):
OPTIONS /icon.svg HTTP/1.1
Host: router.local
User-Agent: Chrome/116.0.0.0 Safari/537.36
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en-GB;q=0.9,en;q=0.8
Access-Control-Request-Method: GET
Access-Control-Request-Private-Network: true
Connection: keep-alive
Origin: https://example.com
Referer: https://example.com
Sec-Fetch-Dest: image
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
π¬ The browser sent a CORS preflight request to notify the application, located on the private network, about the cross-network request that the application, located on the public network, want to perform.
π‘ Note the special request header: Access-Control-Request-Private-Network: true
π€ If the application on the private network, wants to allow the request, then it will return the following CORS headers that will make the preflight successful:
π‘ Note the special response header: Access-Control-Allow-Private-Network: true
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET
Access-Control-Allow-Private-Network: true
...
π To summarize, the application on the private network, uses its response to the preflight request to allow or not the real request to be performed:
- β Preflight succeed: The browser will send the real request (HTTP GET in our example).
- β Preflight fail: The browser will NOT send the real request.
References
- https://developer.chrome.com/blog/private-network-access-update
- https://wicg.github.io/private-network-access/
- https://github.com/WICG/private-network-access
- https://portswigger.net/daily-swig/chrome-to-bolster-csrf-protections-with-cors-preflight-checks-on-private-network-requests
- https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
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 detailed 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 detailed 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 detailed 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
- https://developer.mozilla.org/en-US/docs/Glossary/Fetch_metadata_request_header
- https://caniuse.com/mdn-http_headers_sec-fetch-dest
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Dest
- https://caniuse.com/mdn-http_headers_sec-fetch-mode
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Mode
- https://caniuse.com/mdn-http_headers_sec-fetch-user
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-User
- https://caniuse.com/mdn-http_headers_sec-fetch-site
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Site
- https://web.dev/same-site-same-origin/
- https://jub0bs.com/posts/2021-01-29-great-samesite-confusion/#are-site-and-origin-interchangeable
- https://portswigger.net/daily-swig/firefox-becomes-latest-browser-to-support-fetch-metadata-request-headers
- https://xsleaks.dev/docs/defenses/opt-in/fetch-metadata/
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/2 200
date: Sat, 15 Jan 2022 16:20:55 GMT
expires: -1
cache-control: private, max-age=0
content-type: text/html; charset=UTF-8
strict-transport-security: max-age=31536000
bfcache-opt-in: unload
p3p: CP="This is not a P3P policy! See g.co/p3phelp for more info."
server: gws
x-xss-protection: 0
x-frame-options: SAMEORIGIN
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
accept-ranges: none
vary: Accept-Encoding
$ 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/2 200
vary: Accept-Encoding
x-fb-rlafr: 0
document-policy: force-load-at-top
pragma: no-cache
cache-control: private, no-cache, no-store, must-revalidate
expires: Sat, 01 Jan 2000 00:00:00 GMT
x-content-type-options: nosniff
x-xss-protection: 0
content-security-policy-report-only: default-src data: blob: 'self' https://*.fbsbx.com 'unsafe-inline' *.facebook.com 'unsafe-eval' *.fbcdn.net;script-src *.facebook.com *.fbcdn.net 'unsafe-inline' 'unsafe-eval' blob: data: 'self';style-src *.fbcdn.net data: *.facebook.com 'unsafe-inline';connect-src *.facebook.com facebook.com *.fbcdn.net wss://*.facebook.com:* attachment.fbsbx.com blob: *.cdninstagram.com 'self' wss://gateway.facebook.com wss://edge-chat.facebook.com wss://snaptu-d.facebook.com wss://kaios-d-test.facebook.com/ wss://kaios-d.facebook.com/ *.fbsbx.com;font-src data: *.facebook.com *.fbcdn.net *.fbsbx.com;img-src *.fbcdn.net *.facebook.com data: https://*.fbsbx.com facebook.com *.cdninstagram.com fbsbx.com fbcdn.net blob: android-webview-video-poster:;media-src *.cdninstagram.com blob: *.fbcdn.net *.fbsbx.com www.facebook.com *.facebook.com data:;frame-src *.facebook.com *.fbsbx.com fbsbx.com data: *.fbcdn.net;worker-src blob: *.facebook.com data:;report-uri https://www.facebook.com/csp/reporting/?m=c&minimize=0;
content-security-policy: default-src data: blob: 'self' https://*.fbsbx.com 'unsafe-inline' *.facebook.com 'unsafe-eval' *.fbcdn.net;script-src *.facebook.com *.fbcdn.net 'unsafe-inline' 'unsafe-eval' blob: data: 'self';style-src *.fbcdn.net data: *.facebook.com 'unsafe-inline';connect-src *.facebook.com facebook.com *.fbcdn.net wss://*.facebook.com:* attachment.fbsbx.com blob: *.cdninstagram.com 'self' wss://gateway.facebook.com wss://edge-chat.facebook.com wss://snaptu-d.facebook.com wss://kaios-d-test.facebook.com/ wss://kaios-d.facebook.com/ *.fbsbx.com;font-src data: *.facebook.com *.fbcdn.net *.fbsbx.com;img-src *.fbcdn.net *.facebook.com data: https://*.fbsbx.com facebook.com *.cdninstagram.com fbsbx.com fbcdn.net blob: android-webview-video-poster:;media-src *.cdninstagram.com blob: *.fbcdn.net *.fbsbx.com www.facebook.com *.facebook.com data:;frame-src *.facebook.com *.fbsbx.com fbsbx.com data: *.fbcdn.net;worker-src blob: *.facebook.com data:;block-all-mixed-content;upgrade-insecure-requests;report-uri https://www.facebook.com/csp/reporting/?m=c&minimize=0;
x-frame-options: DENY
strict-transport-security: max-age=15552000; preload
content-type: text/html; charset="utf-8"
x-fb-debug: M4/CJ5A2DSyEA2LjHGF5BfVjsjpbSZ/6GcXpeTlWMQ5//gvXD216nkTu5ISGgMpJ0Y1pKYBEgwXHJCKjyUx+hw==
date: Sat, 15 Jan 2022 16:25:09 GMT
priority: u=3,i
alt-svc: h3=":443"; ma=3600, h3-29=":443"; ma=3600
$ 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/2 200
date: Sat, 15 Jan 2022 16:25:30 GMT
expiry: Tue, 31 Mar 1981 05:00:00 GMT
pragma: no-cache
server: tsa_f
content-type: text/html; charset=utf-8
x-powered-by: Express
cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
last-modified: Sat, 15 Jan 2022 16:25:30 GMT
x-frame-options: DENY
x-xss-protection: 0
x-content-type-options: nosniff
content-security-policy: connect-src 'self' blob: https://*.giphy.com https://*.pscp.tv https://*.video.pscp.tv https://*.twimg.com https://api.twitter.com https://api-stream.twitter.com https://ads-api.twitter.com https://aa.twitter.com https://caps.twitter.com https://media.riffsy.com https://pay.twitter.com https://sentry.io https://ton.twitter.com https://twitter.com https://upload.twitter.com https://www.google-analytics.com https://accounts.google.com/gsi/status https://accounts.google.com/gsi/log https://app.link https://api2.branch.io https://bnc.lt wss://*.pscp.tv https://vmap.snappytv.com https://vmapstage.snappytv.com https://vmaprel.snappytv.com https://vmap.grabyo.com https://dhdsnappytv-vh.akamaihd.net https://pdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://dwo3ckksxlb0v.cloudfront.net ; default-src 'self'; form-action 'self' https://twitter.com https://*.twitter.com; font-src 'self' https://*.twimg.com; frame-src 'self' https://twitter.com https://mobile.twitter.com https://pay.twitter.com https://cards-frame.twitter.com https://accounts.google.com/ https://recaptcha.net/recaptcha/ https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/; img-src 'self' blob: data: https://*.cdn.twitter.com https://ton.twitter.com https://*.twimg.com https://analytics.twitter.com https://cm.g.doubleclick.net https://www.google-analytics.com https://www.periscope.tv https://www.pscp.tv https://media.riffsy.com https://*.giphy.com https://*.pscp.tv https://*.periscope.tv https://prod-periscope-profile.s3-us-west-2.amazonaws.com https://platform-lookaside.fbsbx.com https://scontent.xx.fbcdn.net https://scontent-sea1-1.xx.fbcdn.net https://*.googleusercontent.com https://imgix.revue.co; manifest-src 'self'; media-src 'self' blob: https://twitter.com https://*.twimg.com https://*.vine.co https://*.pscp.tv https://*.video.pscp.tv https://*.giphy.com https://media.riffsy.com https://dhdsnappytv-vh.akamaihd.net https://pdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://dwo3ckksxlb0v.cloudfront.net; object-src 'none'; script-src 'self' 'unsafe-inline' https://*.twimg.com https://recaptcha.net/recaptcha/ https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ https://www.google-analytics.com https://twitter.com https://app.link https://accounts.google.com/gsi/client https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js 'nonce-NDFlMzM0YjgtOWZkZS00MWFjLWE3ODktYjYxYmVjYjExMjlk'; style-src 'self' 'unsafe-inline' https://accounts.google.com/gsi/style https://*.twimg.com; worker-src 'self' blob:; report-uri https://twitter.com/i/csp_report?a=O5RXE%3D%3D%3D&ro=false
strict-transport-security: max-age=631138519
cross-origin-opener-policy: same-origin-allow-popups
cross-origin-embedder-policy: unsafe-none
x-response-time: 141
x-connection-hash: d29168d08eb4439a1e87f5d5234656e361f15325b079c5aaa156ea87b583d000
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/2 200
server: GitHub.com
date: Sat, 15 Jan 2022 16:25:45 GMT
content-type: text/html; charset=utf-8
vary: X-PJAX, X-PJAX-Container, Accept-Language, Accept-Encoding, Accept, X-Requested-With
permissions-policy: interest-cohort=()
content-language: en-US
etag: W/"d4406bbb5b88163f272b94947d7b2fca"
cache-control: max-age=0, private, must-revalidate
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: origin-when-cross-origin, strict-origin-when-cross-origin
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 github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com objects-origin.githubusercontent.com www.githubstatus.com collector.githubapp.com api.github.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 cdn.optimizely.com logx.optimizely.com/v1/events translator.github.com wss://alive.github.com github.githubassets.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src render.githubusercontent.com viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: github.githubassets.com identicons.github.com collector.githubapp.com github-cloud.s3.amazonaws.com secured-user-images.githubusercontent.com/ *.githubusercontent.com customer-stories-feed.github.com spotlights-feed.github.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ github.githubassets.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; worker-src github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/
accept-ranges: bytes
x-github-request-id: 2B45:1FFB:1ED7F0B:203CC0F:61E2F58E
Case Studies
π This section list the entities referencing the OWASP Secure Headers Project.
π© Feel free to contact project leaders if your company or software (open source or not) was using the OSHP project.
π Google dork used to identity references was allintext:"OWASP Secure Headers Project" -site:owasp.org -site:github.com -site:youtube.com -site:twitter.com -site:linkedin.com
.
How to create a link to the OSHP site?
π Use the following absolute URL syntax to create a reference link to a specific location of the OSHP site. The presence of the index.html
file is mandatory otherwise any anchor specified is not effective:
https://owasp.org/www-project-secure-headers/index.html#[TAB-ID]_[HEADER-ID-INSIDE-TAB]
π‘ Where:
[TAB-ID]
: ID of the tab that can be obtained with the link to it.[HEADER-ID-INSIDE-TAB]
: Href value of the link to the section inside the tab.
π Example of reference link to the section about the header Clear-Site-Data in the Response Headers tab:
https://owasp.org/www-project-secure-headers/index.html#div-headers_clear-site-data
π Example of reference link to the section PHP in the Technical Resources tab:
https://owasp.org/www-project-secure-headers/index.html#div-technical_php
Companies and other legal entities
- Cloud.gov.
- Amazon AWS.
- Salesforce.
- Black Hills Information Security.
- Progress.
- Bloomreach.
- Tableau.
- 42Crunch.
- SAP.
- SecureAuth.
- Detectify.
- ImmuniWeb.
- Zoom.
- NexusGuard.
- VeraCode.
- Ivanti.
- Government Technology Agency of Singapore GovTech.
- HCL Volt MX.
- Missouri State Website.
- SAS.
- RedHat.