371 lines
18 KiB
Plaintext
371 lines
18 KiB
Plaintext
[[headers]]
|
|
= Security HTTP Response Headers
|
|
|
|
[NOTE]
|
|
====
|
|
This portion of the documentation discusses the general topic of Security HTTP Response Headers.
|
|
See the relevant sections for specific information on Security HTTP Response Headers in xref:servlet/exploits/headers.adoc#servlet-headers[servlet]- and xref:reactive/exploits/headers.adoc#webflux-headers[WebFlux]-based applications.
|
|
====
|
|
|
|
You can use https://owasp.org/www-project-secure-headers/#div-headers[HTTP response headers] in many ways to increase the security of web applications.
|
|
This section is dedicated to the various HTTP response headers for which Spring Security provides explicit support for.
|
|
If necessary, you can also configure Spring Security to provide <<headers-custom,custom headers>>.
|
|
|
|
[[headers-default]]
|
|
== Default Security Headers
|
|
|
|
[NOTE]
|
|
====
|
|
See the relevant sections for how to customize the defaults for both xref:servlet/exploits/headers.adoc#servlet-headers-default[servlet]- and xref:reactive/exploits/headers.adoc#webflux-headers-default[webflux]-based applications.
|
|
====
|
|
|
|
Spring Security provides a default set of security related HTTP response headers to provide secure defaults.
|
|
|
|
The default for Spring Security is to include the following headers:
|
|
|
|
.Default Security HTTP Response Headers
|
|
[source,http]
|
|
----
|
|
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
|
|
Pragma: no-cache
|
|
Expires: 0
|
|
X-Content-Type-Options: nosniff
|
|
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
|
|
X-Frame-Options: DENY
|
|
X-XSS-Protection: 0
|
|
----
|
|
|
|
[NOTE]
|
|
====
|
|
Strict-Transport-Security is added only on HTTPS requests
|
|
====
|
|
|
|
If the defaults do not meet your needs, you can easily remove, modify, or add headers from these defaults.
|
|
For additional details on each of these headers, see the corresponding sections:
|
|
|
|
* <<headers-cache-control,Cache Control>>
|
|
* <<headers-content-type-options,Content Type Options>>
|
|
* <<headers-hsts,HTTP Strict Transport Security>>
|
|
* <<headers-frame-options,X-Frame-Options>>
|
|
* <<headers-xss-protection,X-XSS-Protection>>
|
|
|
|
[[headers-cache-control]]
|
|
== Cache Control
|
|
|
|
[NOTE]
|
|
====
|
|
See to the relevant sections for how to customize the defaults for both xref:servlet/exploits/headers.adoc#servlet-headers-cache-control[servlet]- and xref:reactive/exploits/headers.adoc#webflux-headers-cache-control[webflux]-based applications.
|
|
====
|
|
|
|
Spring Security's default is to disable caching to protect the user's content.
|
|
|
|
If a user authenticates to view sensitive information and then logs out, we do not want a malicious user to be able to click the back button to view the sensitive information.
|
|
The cache control headers that are sent by default are:
|
|
|
|
.Default Cache Control HTTP Response Headers
|
|
[source]
|
|
----
|
|
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
|
|
Pragma: no-cache
|
|
Expires: 0
|
|
----
|
|
|
|
To be secure by default, Spring Security adds these headers by default.
|
|
However, if your application provides its own cache control headers, Spring Security backs out of the way.
|
|
This allows for applications to ensure that static resources (such as CSS and JavaScript) can be cached.
|
|
|
|
|
|
[[headers-content-type-options]]
|
|
== Content Type Options
|
|
|
|
[NOTE]
|
|
====
|
|
Refer to the relevant sections to see how to customize the defaults for both xref:servlet/exploits/headers.adoc#servlet-headers-content-type-options[servlet] and xref:reactive/exploits/headers.adoc#webflux-headers-content-type-options[webflux] based applications.
|
|
====
|
|
|
|
Historically, browsers, including Internet Explorer, would try to guess the content type of a request by using https://en.wikipedia.org/wiki/Content_sniffing[content sniffing].
|
|
This allowed browsers to improve the user experience by guessing the content type on resources that had not specified the content type.
|
|
For example, if a browser encountered a JavaScript file that did not have the content type specified, it would be able to guess the content type and then run it.
|
|
|
|
[NOTE]
|
|
====
|
|
There are many additional things one should do (such as only display the document in a distinct domain, ensure Content-Type header is set, sanitize the document, and others) when allowing content to be uploaded.
|
|
However, these measures are out of the scope of what Spring Security provides.
|
|
It is also important to point out that, when disabling content sniffing, you must specify the content type in order for things to work properly.
|
|
====
|
|
|
|
The problem with content sniffing is that this allowed malicious users to use polyglots (that is, a file that is valid as multiple content types) to perform XSS attacks.
|
|
For example, some sites may allow users to submit a valid postscript document to a website and view it.
|
|
A malicious user might create a http://webblaze.cs.berkeley.edu/papers/barth-caballero-song.pdf[postscript document that is also a valid JavaScript file] and perform an XSS attack with it.
|
|
|
|
By default, Spring Security disables content sniffing by adding the following header to HTTP responses:
|
|
|
|
.nosniff HTTP Response Header
|
|
[source,http]
|
|
----
|
|
X-Content-Type-Options: nosniff
|
|
----
|
|
|
|
[[headers-hsts]]
|
|
== HTTP Strict Transport Security (HSTS)
|
|
|
|
[NOTE]
|
|
====
|
|
Refer to the relevant sections to see how to customize the defaults for both xref:servlet/exploits/headers.adoc#servlet-headers-hsts[servlet] and xref:reactive/exploits/headers.adoc#webflux-headers-hsts[webflux] based applications.
|
|
====
|
|
|
|
When you type in your bank's website, do you enter `mybank.example.com` or do you enter `\https://mybank.example.com`?
|
|
If you omit the `https` protocol, you are potentially vulnerable to https://en.wikipedia.org/wiki/Man-in-the-middle_attack[Man-in-the-Middle attacks].
|
|
Even if the website performs a redirect to `\https://mybank.example.com`, a malicious user could intercept the initial HTTP request and manipulate the response (for example, redirect to `\https://mibank.example.com` and steal their credentials).
|
|
|
|
Many users omit the `https` protocol, and this is why https://tools.ietf.org/html/rfc6797[HTTP Strict Transport Security (HSTS)] was created.
|
|
Once `mybank.example.com` is added as a https://tools.ietf.org/html/rfc6797#section-5.1[HSTS host], a browser can know ahead of time that any request to mybank.example.com should be interpreted as `\https://mybank.example.com`.
|
|
This greatly reduces the possibility of a Man-in-the-Middle attack occurring.
|
|
|
|
[NOTE]
|
|
====
|
|
In accordance with https://tools.ietf.org/html/rfc6797#section-7.2[RFC6797], the HSTS header is injected only into HTTPS responses.
|
|
For the browser to acknowledge the header, the browser must first trust the CA that signed the SSL certificate used to make the connection (not just the SSL certificate).
|
|
====
|
|
|
|
One way for a site to be marked as a HSTS host is to have the host preloaded into the browser.
|
|
Another way is to add the `Strict-Transport-Security` header to the response.
|
|
For example, Spring Security's default behavior is to add the following header, which instructs the browser to treat the domain as an HSTS host for a year (there are 31536000 seconds in a non-leap year):
|
|
|
|
|
|
.Strict Transport Security HTTP Response Header
|
|
[source]
|
|
----
|
|
Strict-Transport-Security: max-age=31536000 ; includeSubDomains ; preload
|
|
----
|
|
|
|
The optional `includeSubDomains` directive instructs the browser that subdomains (such as `secure.mybank.example.com`) should also be treated as an HSTS domain.
|
|
|
|
The optional `preload` directive instructs the browser that the domain should be preloaded in browser as an HSTS domain.
|
|
For more details on HSTS preload, see https://hstspreload.org.
|
|
|
|
[[headers-hpkp]]
|
|
== HTTP Public Key Pinning (HPKP)
|
|
|
|
[NOTE]
|
|
====
|
|
To remain passive, Spring Security still provides xref:servlet/exploits/headers.adoc#servlet-headers-hpkp[support for HPKP in servlet environments].
|
|
However, for the reasons listed earlier, HPKP is no longer recommended by the Spring Security team.
|
|
====
|
|
|
|
https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning[HTTP Public Key Pinning (HPKP)] specifies to a web client which public key to use with a certain web server to prevent Man-in-the-Middle (MITM) attacks with forged certificates.
|
|
When used correctly, HPKP could add additional layers of protection against compromised certificates.
|
|
However, due to the complexity of HPKP, many experts no longer recommend using it and https://www.chromestatus.com/feature/5903385005916160[Chrome has even removed support] for it.
|
|
|
|
[[headers-hpkp-deprecated]]
|
|
For additional details around why HPKP is no longer recommended, read https://blog.qualys.com/ssllabs/2016/09/06/is-http-public-key-pinning-dead[Is HTTP Public Key Pinning Dead?] and https://scotthelme.co.uk/im-giving-up-on-hpkp/[I'm giving up on HPKP].
|
|
|
|
[[headers-frame-options]]
|
|
== X-Frame-Options
|
|
|
|
[NOTE]
|
|
====
|
|
See the relevant sections to see how to customize the defaults for both xref:servlet/exploits/headers.adoc#servlet-headers-frame-options[servlet] and xref:reactive/exploits/headers.adoc#webflux-headers-frame-options[webflux] based applications.
|
|
====
|
|
|
|
Letting your website be added to a frame can be a security issue.
|
|
For example, by using clever CSS styling, users could be tricked into clicking on something that they were not intending.
|
|
For example, a user that is logged into their bank might click a button that grants access to other users.
|
|
This sort of attack is known as https://en.wikipedia.org/wiki/Clickjacking[Clickjacking].
|
|
|
|
[NOTE]
|
|
====
|
|
Another modern approach to dealing with clickjacking is to use <<headers-csp>>.
|
|
====
|
|
|
|
There are a number ways to mitigate clickjacking attacks.
|
|
For example, to protect legacy browsers from clickjacking attacks, you can use https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Best-for-now_Legacy_Browser_Frame_Breaking_Script[frame breaking code].
|
|
While not perfect, the frame breaking code is the best you can do for the legacy browsers.
|
|
|
|
A more modern approach to address clickjacking is to use https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options[X-Frame-Options] header.
|
|
By default, Spring Security disables rendering pages within an iframe by using with the following header:
|
|
|
|
[source]
|
|
----
|
|
X-Frame-Options: DENY
|
|
----
|
|
|
|
[[headers-xss-protection]]
|
|
== X-XSS-Protection
|
|
|
|
[NOTE]
|
|
====
|
|
See the relevant sections to see how to customize the defaults for both xref:servlet/exploits/headers.adoc#servlet-headers-xss-protection[servlet]- and xref:reactive/exploits/headers.adoc#webflux-headers-xss-protection[webflux]-based applications.
|
|
====
|
|
|
|
Some browsers have built-in support for filtering out https://www.owasp.org/index.php/Testing_for_Reflected_Cross_site_scripting_(OWASP-DV-001)[reflected XSS attacks].
|
|
The filter has been deprecated in major browsers, and https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-xss-protection[current OWASP recommendation] is to explicitly set the header to 0.
|
|
|
|
By default, Spring Security blocks the content by using the following header:
|
|
|
|
[source]
|
|
----
|
|
X-XSS-Protection: 0
|
|
----
|
|
|
|
|
|
[[headers-csp]]
|
|
== Content Security Policy (CSP)
|
|
|
|
[NOTE]
|
|
====
|
|
See the relevant sections to see how to configure both xref:servlet/exploits/headers.adoc#servlet-headers-csp[servlet]- and xref:reactive/exploits/headers.adoc#webflux-headers-csp[webflux]-based applications.
|
|
====
|
|
|
|
https://www.w3.org/TR/CSP2/[Content Security Policy (CSP)] is a mechanism that web applications can use to mitigate content injection vulnerabilities, such as cross-site scripting (XSS).
|
|
CSP is a declarative policy that provides a facility for web application authors to declare and ultimately inform the client (user-agent) about the sources from which the web application expects to load resources.
|
|
|
|
[NOTE]
|
|
====
|
|
Content Security Policy is not intended to solve all content injection vulnerabilities.
|
|
Instead, you can use CSP to help reduce the harm caused by content injection attacks.
|
|
As a first line of defense, web application authors should validate their input and encode their output.
|
|
====
|
|
|
|
A web application can use CSP by including one of the following HTTP headers in the response:
|
|
|
|
* `Content-Security-Policy`
|
|
* `Content-Security-Policy-Report-Only`
|
|
|
|
Each of these headers are used as a mechanism to deliver a security policy to the client.
|
|
A security policy contains a set of security policy directives, each responsible for declaring the restrictions for a particular resource representation.
|
|
|
|
For example, a web application can declare that it expects to load scripts from specific, trusted sources by including the following header in the response:
|
|
|
|
.Content Security Policy Example
|
|
[source]
|
|
----
|
|
Content-Security-Policy: script-src https://trustedscripts.example.com
|
|
----
|
|
|
|
An attempt to load a script from another source other than what is declared in the `script-src` directive is blocked by the user-agent.
|
|
Additionally, if the https://www.w3.org/TR/CSP2/#directive-report-uri[report-uri] directive is declared in the security policy, the violation will be reported by the user-agent to the declared URL.
|
|
|
|
For example, if a web application violates the declared security policy, the following response header instructs the user-agent to send violation reports to the URL specified in the policy's `report-uri` directive.
|
|
|
|
.Content Security Policy with report-uri
|
|
[source]
|
|
----
|
|
Content-Security-Policy: script-src https://trustedscripts.example.com; report-uri /csp-report-endpoint/
|
|
----
|
|
|
|
https://www.w3.org/TR/CSP2/#violation-reports[Violation reports] are standard JSON structures that can be captured either by the web application's own API or by a publicly hosted CSP violation reporting service, such as https://report-uri.io/.
|
|
|
|
The `Content-Security-Policy-Report-Only` header provides the capability for web application authors and administrators to monitor security policies rather than enforce them.
|
|
This header is typically used when experimenting or developing security policies for a site.
|
|
When a policy is deemed effective, it can be enforced by using the `Content-Security-Policy` header field instead.
|
|
|
|
Given the following response header, the policy declares that scripts can be loaded from one of two possible sources.
|
|
|
|
.Content Security Policy Report Only
|
|
[source]
|
|
----
|
|
Content-Security-Policy-Report-Only: script-src 'self' https://trustedscripts.example.com; report-uri /csp-report-endpoint/
|
|
----
|
|
|
|
If the site violates this policy, by attempting to load a script from `evil.example.com`, the user-agent sends a violation report to the declared URL specified by the `report-uri` directive but still lets the violating resource load.
|
|
|
|
Applying Content Security Policy to a web application is often a non-trivial undertaking.
|
|
The following resources may provide further assistance in developing effective security policies for your site:
|
|
|
|
https://www.html5rocks.com/en/tutorials/security/content-security-policy/[An Introduction to Content Security Policy]
|
|
|
|
https://developer.mozilla.org/en-US/docs/Web/Security/CSP[CSP Guide - Mozilla Developer Network]
|
|
|
|
https://www.w3.org/TR/CSP2/[W3C Candidate Recommendation]
|
|
|
|
[[headers-referrer]]
|
|
== Referrer Policy
|
|
|
|
[NOTE]
|
|
====
|
|
See the relevant sections to see how to configure both xref:servlet/exploits/headers.adoc#servlet-headers-referrer[servlet]- and xref:reactive/exploits/headers.adoc#webflux-headers-referrer[webflux]-based applications.
|
|
====
|
|
|
|
https://www.w3.org/TR/referrer-policy[Referrer Policy] is a mechanism that web applications can use to manage the referrer field, which contains the last
|
|
page the user was on.
|
|
|
|
Spring Security's approach is to use the https://www.w3.org/TR/referrer-policy/[Referrer Policy] header, which provides different https://www.w3.org/TR/referrer-policy/#referrer-policies[policies]:
|
|
|
|
.Referrer Policy Example
|
|
[source]
|
|
----
|
|
Referrer-Policy: same-origin
|
|
----
|
|
|
|
The Referrer-Policy response header instructs the browser to let the destination knows the source where the user was previously.
|
|
|
|
[[headers-feature]]
|
|
== Feature Policy
|
|
|
|
[NOTE]
|
|
====
|
|
See the relevant sections to see how to configure both xref:servlet/exploits/headers.adoc#servlet-headers-feature[servlet]- and xref:reactive/exploits/headers.adoc#webflux-headers-feature[webflux]-based applications.
|
|
====
|
|
|
|
https://wicg.github.io/feature-policy/[Feature Policy] is a mechanism that lets web developers to selectively enable, disable, and modify the behavior of certain APIs and web features in the browser.
|
|
|
|
.Feature Policy Example
|
|
[source]
|
|
----
|
|
Feature-Policy: geolocation 'self'
|
|
----
|
|
|
|
With Feature Policy, developers can opt-in to a set of "`policies`" for the browser to enforce on specific features used throughout your site.
|
|
These policies restrict what APIs the site can access or modify the browser's default behavior for certain features.
|
|
|
|
|
|
[[headers-permissions]]
|
|
== Permissions Policy
|
|
|
|
[NOTE]
|
|
====
|
|
See the relevant sections to see how to configure both xref:servlet/exploits/headers.adoc#servlet-headers-permissions[servlet]- and xref:reactive/exploits/headers.adoc#webflux-headers-permissions[webflux]-based applications.
|
|
====
|
|
|
|
https://w3c.github.io/webappsec-permissions-policy/[Permissions Policy] is a mechanism that lets web developers selectively enable, disable, and modify the behavior of certain APIs and web features in the browser.
|
|
|
|
.Permissions Policy Example
|
|
[source]
|
|
----
|
|
Permissions-Policy: geolocation=(self)
|
|
----
|
|
|
|
With Permissions Policy, developers can opt-in to a set of "policies" for the browser to enforce on specific features used throughout your site.
|
|
These policies restrict what APIs the site can access or modify the browser's default behavior for certain features.
|
|
|
|
|
|
[[headers-clear-site-data]]
|
|
== Clear Site Data
|
|
|
|
[NOTE]
|
|
====
|
|
See the relevant sections to see how to configure both xref:servlet/exploits/headers.adoc#servlet-headers-clear-site-data[servlet]- and xref:reactive/exploits/headers.adoc#webflux-headers-clear-site-data[webflux]- based applications.
|
|
====
|
|
|
|
https://www.w3.org/TR/clear-site-data/[Clear Site Data] is a mechanism by which any browser-side data (cookies, local storage, and the like) can be removed when an HTTP response contains this header:
|
|
|
|
[source]
|
|
----
|
|
Clear-Site-Data: "cache", "cookies", "storage", "executionContexts"
|
|
----
|
|
|
|
This is a nice clean-up action to perform on logout.
|
|
|
|
|
|
[[headers-custom]]
|
|
== Custom Headers
|
|
|
|
[NOTE]
|
|
====
|
|
See the relevant section to see how to configure xref:servlet/exploits/headers.adoc#servlet-headers-custom[servlet] based applications.
|
|
====
|
|
|
|
Spring Security has mechanisms to make it convenient to add the more common security headers to your application.
|
|
However, it also provides hooks to enable adding custom headers.
|