mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-25 05:22:16 +00:00
Extract HTTP Response Headers Documentation
Fixes gh-7625
This commit is contained in:
parent
1188a3bb5f
commit
e1fad001d9
@ -0,0 +1,369 @@
|
||||
[[headers]]
|
||||
= Security HTTP Response Headers
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
This portion of the documentation discusses the general topic of Security HTTP Response Headers.
|
||||
Refer to the relevant sections for specific information on Security HTTP Response Headers <<servlet-headers,servlet>> and <<webflux-headers,WebFlux>> based applications.
|
||||
====
|
||||
|
||||
There are many https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#tab=Headers[HTTP response headers] that can be used to increase the security of web applications.
|
||||
This section is dedicated to the various HTTP response headers that Spring Security provides explicit support for.
|
||||
If necessary, Spring Security can also be configured to provide <<headers-custom,custom headers>>.
|
||||
|
||||
[[headers-default]]
|
||||
== Default Security Headers
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Refer to the relevant sections to see how to customize the defaults for both <<servlet-headers-default,servlet>> and <<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: 1; mode=block
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: Strict-Transport-Security is only added 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, refer to 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]
|
||||
====
|
||||
Refer to the relevant sections to see how to customize the defaults for both <<servlet-headers-cache-control,servlet>> and <<webflux-headers-cache-control,webflux>> based applications.
|
||||
====
|
||||
|
||||
Spring Security's default is to disable caching to protect user's content.
|
||||
|
||||
If a user authenticates to view sensitive information and then logs out, we don't 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
|
||||
----
|
||||
====
|
||||
|
||||
In order to be secure by default, Spring Security adds these headers by default.
|
||||
However, if your application provides it's own cache control headers Spring Security will back out of the way.
|
||||
This allows for applications to ensure that static resources like 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 <<servlet-headers-content-type-options,servlet>> and <<webflux-headers-content-type-options,webflux>> based applications.
|
||||
====
|
||||
|
||||
Historically browsers, including Internet Explorer, would try to guess the content type of a request 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 execute it.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
There are many additional things one should do (i.e. only display the document in a distinct domain, ensure Content-Type header is set, sanitize the document, etc) 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 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 (i.e. a file that is valid as multiple content types) to execute 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 execute a XSS attack with it.
|
||||
|
||||
Spring Security disables content sniffing by default 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 <<servlet-headers-hsts,servlet>> and <<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 (i.e. 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 only injected into HTTPS responses.
|
||||
In order 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 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 approximately 31536000 seconds in a 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 (i.e. secure.mybank.example.com) should also be treated as an HSTS domain.
|
||||
|
||||
The optional `preload` directive instructs the browser that domain should be preloaded in browser as HSTS domain.
|
||||
For more details on HSTS preload please see https://hstspreload.org.
|
||||
|
||||
[[headers-hpkp]]
|
||||
== HTTP Public Key Pinning (HPKP)
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
In order to remain passive Spring Security still provides <<servlet-headers-hpkp,support for HPKP in servlet environments>>, but for the reasons listed above HPKP is no longer recommended by the 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 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]
|
||||
====
|
||||
Refer to the relevant sections to see how to customize the defaults for both <<servlet-headers-frame-options,servlet>> and <<webflux-headers-frame-options,webflux>> based applications.
|
||||
====
|
||||
|
||||
Allowing your website to be added to a frame can be a security issue.
|
||||
For example, using clever CSS styling users could be tricked into clicking on something that they were not intending (https://www.youtube.com/watch?v=3mk0RySeNsU[video demo]).
|
||||
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 using with the following header:
|
||||
|
||||
[source]
|
||||
----
|
||||
X-Frame-Options: DENY
|
||||
----
|
||||
|
||||
[[headers-xss-protection]]
|
||||
== X-XSS-Protection
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Refer to the relevant sections to see how to customize the defaults for both <<servlet-headers-xss-protection,servlet>> and <<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].
|
||||
This is by no means foolproof, but does assist in XSS protection.
|
||||
|
||||
The filtering is typically enabled by default, so adding the header typically just ensures it is enabled and instructs the browser what to do when a XSS attack is detected.
|
||||
For example, the filter might try to change the content in the least invasive way to still render everything.
|
||||
At times, this type of replacement can become a https://hackademix.net/2009/11/21/ies-xss-filter-creates-xss-vulnerabilities/[XSS vulnerability in itself].
|
||||
Instead, it is best to block the content rather than attempt to fix it.
|
||||
By default Spring Security blocks the content using the following header:
|
||||
|
||||
[source]
|
||||
----
|
||||
X-XSS-Protection: 1; mode=block
|
||||
----
|
||||
|
||||
|
||||
[[headers-csp]]
|
||||
== Content Security Policy (CSP)
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Refer to the relevant sections to see how to configure both <<servlet-headers-csp,servlet>> and <<webflux-headers-csp,webflux>> based applications.
|
||||
====
|
||||
|
||||
https://www.w3.org/TR/CSP2/[Content Security Policy (CSP)] is a mechanism that web applications can leverage 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, CSP can be leveraged 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 may employ the use of 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 will be 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, then 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 will instruct 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 and/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 may 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.com_, the user-agent will send a violation report to the declared URL specified by the _report-uri_ directive, but still allow the violating resource to load nevertheless.
|
||||
|
||||
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]
|
||||
====
|
||||
Refer to the relevant sections to see how to configure both <<servlet-headers-referrer,servlet>> and <<webflux-headers-referrer,webflux>> based applications.
|
||||
====
|
||||
|
||||
https://www.w3.org/TR/referrer-policy[Referrer Policy] is a mechanism that web applications can leverage to manage the referrer field, which contains the last
|
||||
page the user was on.
|
||||
|
||||
Spring Security's approach is to use 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]
|
||||
====
|
||||
Refer to the relevant sections to see how to configure both <<servlet-headers-feature,servlet>> and <<webflux-headers-feature,webflux>> based applications.
|
||||
====
|
||||
|
||||
https://wicg.github.io/feature-policy/[Feature Policy] is a mechanism that allows 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-clear-site-data]]
|
||||
== Clear Site Data
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Refer to the relevant sections to see how to configure both <<servlet-headers-clear-site-data,servlet>> and <<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]
|
||||
====
|
||||
Refer to the relevant sections to see how to configure both <<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.
|
@ -6,3 +6,5 @@ Whenever possible, the protection is enabled by default.
|
||||
Below you will find high level description of the various exploits that Spring Security protects against.
|
||||
|
||||
include::csrf.adoc[leveloffset=+1]
|
||||
|
||||
include::headers.adoc[leveloffset=+1]
|
||||
|
@ -1,54 +1,22 @@
|
||||
[[webflux-headers]]
|
||||
= Security HTTP Response Headers
|
||||
This section discusses Spring Security's support for adding various security headers to the response of WebFlux.
|
||||
|
||||
<<headers,Security HTTP Response Headers>> can be used to increase the security of web applications.
|
||||
This section is dedicated to WebFlux based support for Security HTTP Response Headers.
|
||||
|
||||
[[webflux-headers-default]]
|
||||
== Default Security Headers
|
||||
Spring Security allows users to easily inject the default security headers to assist in protecting their application.
|
||||
The default for Spring Security is to include the following 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: 1; mode=block
|
||||
----
|
||||
|
||||
NOTE: Strict-Transport-Security is only added on HTTPS requests
|
||||
|
||||
For additional details on each of these headers, refer to the corresponding sections:
|
||||
|
||||
* <<webflux-headers-cache-control,Cache Control>>
|
||||
* <<webflux-headers-content-type-options,Content Type Options>>
|
||||
* <<webflux-headers-hsts,HTTP Strict Transport Security>>
|
||||
* <<webflux-headers-frame-options,X-Frame-Options>>
|
||||
* <<webflux-headers-xss-protection,X-XSS-Protection>>
|
||||
|
||||
Spring Security provides a <<headers-default,default set set of Security HTTP Response Headers>> to provide secure defaults.
|
||||
While each of these headers are considered best practice, it should be noted that not all clients utilize the headers, so additional testing is encouraged.
|
||||
|
||||
You can customize specific headers.
|
||||
For example, assume that want your HTTP response headers to look like the following:
|
||||
|
||||
[source,http]
|
||||
----
|
||||
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
|
||||
Pragma: no-cache
|
||||
Expires: 0
|
||||
X-Content-Type-Options: nosniff
|
||||
X-Frame-Options: SAMEORIGIN
|
||||
X-XSS-Protection: 1; mode=block
|
||||
----
|
||||
|
||||
Specifically, you want all of the default headers with the following customizations:
|
||||
|
||||
* <<webflux-headers-frame-options,X-Frame-Options>> to allow any request from same domain
|
||||
* <<webflux-headers-hsts,HTTP Strict Transport Security (HSTS)>> will not be added to the response
|
||||
For example, assume that you want the defaults except you wish to specify `SAMEORIGIN` for <<servlet-headers-frame-options,X-Frame-Options>>.
|
||||
|
||||
You can easily do this with the following Java Configuration:
|
||||
|
||||
.Customize Default Security Headers with Java Configuration
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
@ -57,10 +25,6 @@ SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
// ...
|
||||
.headers(headers ->
|
||||
headers
|
||||
.hsts(hsts ->
|
||||
hsts
|
||||
.disable()
|
||||
)
|
||||
.frameOptions(frameOptions ->
|
||||
frameOptions
|
||||
.mode(Mode.SAMEORIGIN)
|
||||
@ -69,13 +33,13 @@ SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
If you do not want the defaults to be added and want explicit control over what should be used, you can disable the defaults.
|
||||
An example for both Java and XML based configuration is provided below:
|
||||
|
||||
If necessary, you can disable all of the HTTP Security response headers with the following Java Configuration:
|
||||
An example for both Java configuration is provided below:
|
||||
|
||||
.Disable HTTP Security Response Headers
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
@ -89,27 +53,23 @@ SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
[[webflux-headers-cache-control]]
|
||||
== Cache Control
|
||||
In the past Spring Security required you to provide your own cache control for your web application.
|
||||
This seemed reasonable at the time, but browser caches have evolved to include caches for secure connections as well.
|
||||
This means that a user may view an authenticated page, log out, and then a malicious user can use the browser history to view the cached page.
|
||||
To help mitigate this Spring Security has added cache control support which will insert the following headers into you response by default.
|
||||
|
||||
[source]
|
||||
----
|
||||
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
|
||||
Pragma: no-cache
|
||||
Expires: 0
|
||||
----
|
||||
Spring Security includes <<headers-cache-control,Cache Control>> headers by default.
|
||||
|
||||
|
||||
If you actually want to cache specific responses, your application can selectively set the cache control headers to override the header set by Spring Security.
|
||||
However, if you actually want to cache specific responses, your application can selectively add them to the https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/server/reactive/ServerHttpResponse.html[ServerHttpResponse] to override the header set by Spring Security.
|
||||
This is useful to ensure things like CSS, JavaScript, and images are properly cached.
|
||||
|
||||
You can also disable cache control using the following Java Configuration:
|
||||
When using Spring WebFluxZz, this is typically done within your configuration.
|
||||
Details on how to do this can be found in the https://docs.spring.io/spring/docs/5.0.0.RELEASE/spring-framework-reference/web-reactive.html#webflux-config-static-resources[Static Resources] portion of the Spring Reference documentation
|
||||
|
||||
If necessary, you can also disable Spring Security's cache control HTTP response headers.
|
||||
|
||||
.Cache Control Disabled
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
@ -123,34 +83,16 @@ SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
[[webflux-headers-content-type-options]]
|
||||
== Content Type Options
|
||||
Historically browsers, including Internet Explorer, would try to guess the content type of a request 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 execute it.
|
||||
|
||||
[NOTE]
|
||||
==
|
||||
There are many additional things one should do (i.e. only display the document in a distinct domain, ensure Content-Type header is set, sanitize the document, etc) 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 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 (i.e. a file that is valid as multiple content types) to execute 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 execute a XSS attack with it.
|
||||
|
||||
Content sniffing can be disabled by adding the following header to our response:
|
||||
|
||||
[source]
|
||||
----
|
||||
X-Content-Type-Options: nosniff
|
||||
----
|
||||
|
||||
Just as with the cache control element, the nosniff directive is added by default.
|
||||
However, if need to disable the header, the following may be used:
|
||||
Spring Security includes <<headers-content-type-options,Content-Type>> headers by default.
|
||||
However, you can disable it in Java Configuration with:
|
||||
|
||||
.Content Type Options Disabled with Java Configuration
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
@ -164,40 +106,16 @@ SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
[[webflux-headers-hsts]]
|
||||
== HTTP Strict Transport Security (HSTS)
|
||||
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 (i.e. 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 only injected into HTTPS responses.
|
||||
In order 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 is to add the "Strict-Transport-Security" header to the response.
|
||||
For example the following would instruct the browser to treat the domain as an HSTS host for a year (there are approximately 31536000 seconds in a year):
|
||||
|
||||
[source]
|
||||
----
|
||||
Strict-Transport-Security: max-age=31536000 ; includeSubDomains ; preload
|
||||
----
|
||||
|
||||
The optional includeSubDomains directive instructs Spring Security that subdomains (i.e. secure.mybank.example.com) should also be treated as an HSTS domain.
|
||||
|
||||
The optional preload directive instructs Spring Security that domain should be preloaded in browser as HSTS domain. For more details on HSTS preload please see
|
||||
https://hstspreload.org.
|
||||
|
||||
As with the other headers, Spring Security adds HSTS by default.
|
||||
You can customize HSTS headers with Java Configuration:
|
||||
Spring Security provides the <<headers-hsts,Strict Transport Security>> header by default.
|
||||
However, you can customize the results explicitly.
|
||||
For example, the following is an example of explicitly providing HSTS with Java Configuration:
|
||||
|
||||
.Strict Transport Security with Java Configuration
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
@ -216,36 +134,16 @@ SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[webflux-headers-frame-options]]
|
||||
== X-Frame-Options
|
||||
Allowing your website to be added to a frame can be a security issue.
|
||||
For example, using clever CSS styling users could be tricked into clicking on something that they were not intending (https://www.youtube.com/watch?v=3mk0RySeNsU[video demo]).
|
||||
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].
|
||||
By default, Spring Security disables rendering within an iframe using <<headers-frame-options,X-Frame-Options>>.
|
||||
|
||||
[NOTE]
|
||||
==
|
||||
Another modern approach to dealing with clickjacking is to use <<webflux-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:
|
||||
|
||||
[source]
|
||||
----
|
||||
X-Frame-Options: DENY
|
||||
----
|
||||
|
||||
The X-Frame-Options response header instructs the browser to prevent any site with this header in the response from being rendered within a frame.
|
||||
By default, Spring Security disables rendering within an iframe.
|
||||
|
||||
You can customize X-Frame-Options with Java Configuration using the following:
|
||||
You can customize frame options to use the same origin within Java Configuration using the following:
|
||||
|
||||
.X-Frame-Options: SAMEORIGIN
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
@ -262,26 +160,15 @@ SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
[[webflux-headers-xss-protection]]
|
||||
== X-XSS-Protection
|
||||
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].
|
||||
This is by no means foolproof, but does assist in XSS protection.
|
||||
|
||||
The filtering is typically enabled by default, so adding the header typically just ensures it is enabled and instructs the browser what to do when a XSS attack is detected.
|
||||
For example, the filter might try to change the content in the least invasive way to still render everything.
|
||||
At times, this type of replacement can become a https://hackademix.net/2009/11/21/ies-xss-filter-creates-xss-vulnerabilities/[XSS vulnerability in itself].
|
||||
Instead, it is best to block the content rather than attempt to fix it.
|
||||
To do this we can add the following header:
|
||||
|
||||
[source]
|
||||
----
|
||||
X-XSS-Protection: 1; mode=block
|
||||
----
|
||||
|
||||
This header is included by default.
|
||||
However, we can customize with Java Configuration with the following:
|
||||
By default, Spring Security instructs browsers to block reflected XSS attacks using the <<headers-xss-protection,X-XSS-Protection header>.
|
||||
You can disable `X-XSS-Protection` with the following Java Configuration:
|
||||
|
||||
.X-XSS-Protection Customization
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
@ -295,75 +182,27 @@ SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
[[webflux-headers-csp]]
|
||||
== Content Security Policy (CSP)
|
||||
|
||||
https://www.w3.org/TR/CSP2/[Content Security Policy (CSP)] is a mechanism that web applications can leverage 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, CSP can be leveraged 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 may employ the use of 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_* (for example, _script-src_ and _object-src_), 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:
|
||||
|
||||
[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 will be 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, then 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 will instruct the user-agent to send violation reports to the URL specified in the policy's _report-uri_ directive.
|
||||
|
||||
[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/[*_REPORT-URI_*].
|
||||
|
||||
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 and/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 may be loaded from one of two possible sources.
|
||||
|
||||
[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.com_, the user-agent will send a violation report to the declared URL specified by the _report-uri_ directive, but still allow the violating resource to load nevertheless.
|
||||
|
||||
[[webflux-headers-csp-configure]]
|
||||
=== Configuring Content Security Policy
|
||||
|
||||
It's important to note that Spring Security *_does not add_* Content Security Policy by default.
|
||||
Spring Security does not add <<headers-csp,Content Security Policy>> by default, because a reasonable default is impossible to know without context of the application.
|
||||
The web application author must declare the security policy(s) to enforce and/or monitor for the protected resources.
|
||||
|
||||
For example, given the following security policy:
|
||||
|
||||
[source]
|
||||
.Content Security Policy Example
|
||||
====
|
||||
[source,http]
|
||||
----
|
||||
script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/
|
||||
Content-Security-Policy: script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/
|
||||
----
|
||||
====
|
||||
|
||||
You can enable the CSP header using Java configuration as shown below:
|
||||
|
||||
.Content Security Policy
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
@ -380,9 +219,12 @@ SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
To enable the CSP _'report-only'_ header, provide the following Java configuration:
|
||||
To enable the CSP `report-only` header, provide the following Java configuration:
|
||||
|
||||
.Content Security Policy Report Only
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
@ -400,40 +242,16 @@ SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
[[webflux-headers-csp-links]]
|
||||
=== Additional Resources
|
||||
|
||||
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]
|
||||
====
|
||||
|
||||
[[webflux-headers-referrer]]
|
||||
== Referrer Policy
|
||||
|
||||
https://www.w3.org/TR/referrer-policy[Referrer Policy] is a mechanism that web applications can leverage to manage the referrer field, which contains the last page the user was on.
|
||||
|
||||
Spring Security's approach is to use https://www.w3.org/TR/referrer-policy/[Referrer Policy] header, which provides different https://www.w3.org/TR/referrer-policy/#referrer-policies[policies]:
|
||||
|
||||
[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.
|
||||
|
||||
[[webflux-headers-referrer-configure]]
|
||||
=== Configuring Referrer Policy
|
||||
|
||||
Spring Security *_doesn't add_* Referrer Policy header by default.
|
||||
|
||||
You can enable the Referrer-Policy header using Java configuration as shown below:
|
||||
Spring Security does not add <<headers-referrer,Referrer Policy>> headers by default.
|
||||
You can enable the Referrer Policy header using Java configuration as shown below:
|
||||
|
||||
.Referrer Policy Java Configuration
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
@ -450,28 +268,27 @@ SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
[[webflux-headers-feature]]
|
||||
== Feature Policy
|
||||
|
||||
https://wicg.github.io/feature-policy/[Feature Policy] is a mechanism that allows web developers to selectively enable, disable, and modify the behavior of certain APIs and web features in the browser.
|
||||
Spring Security does not add <<headers-feature,Feature Policy>> headers by default.
|
||||
The following `Feature-Policy` header:
|
||||
|
||||
.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.
|
||||
|
||||
[[webflux-headers-feature-configure]]
|
||||
=== Configuring Feature Policy
|
||||
|
||||
Spring Security *_doesn't add_* Feature Policy header by default.
|
||||
|
||||
You can enable the Feature-Policy header using Java configuration as shown below:
|
||||
can enable the Feature Policy header using Java configuration as shown below:
|
||||
|
||||
.Feature-Policy Java Configuration
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
@ -485,43 +302,40 @@ SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
[[webflux-headers-clearsitedata]]
|
||||
[[webflux-headers-clear-site-data]]
|
||||
== Clear Site Data
|
||||
|
||||
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:
|
||||
Spring Security does not add <<headers-clear-site-data,Clear-Site-Data>> headers by default.
|
||||
The following Clear-Site-Data header:
|
||||
|
||||
[source]
|
||||
.Clear-Site-Data Example
|
||||
====
|
||||
----
|
||||
Clear-Site-Data: "cache", "cookies", "storage", "executionContexts"
|
||||
Clear-Site-Data: "cache", "cookies"
|
||||
----
|
||||
====
|
||||
|
||||
This is a nice clean-up action to perform on logout.
|
||||
|
||||
[[webflux-headers-clearsitedata-configure]]
|
||||
=== Configuring Clear Site Data
|
||||
|
||||
Spring Security *_doesn't add_* the Clear Site Data header by default.
|
||||
|
||||
You can configure your application to send down this header on logout like so:
|
||||
can be sent on log out with the following configuration:
|
||||
|
||||
.Clear-Site-Data Java Configuration
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
|
||||
ServerLogoutHandler securityContext = new SecurityContextServerLogoutHandler();
|
||||
ServerLogoutHandler clearSiteData = new HeaderWriterServerLogoutHandler(new ClearSiteDataServerHttpHeadersWriter());
|
||||
ClearSiteDataServerHttpHeadersWriter writer = new ClearSiteDataServerHttpHeadersWriter(CACHE, COOKIES);
|
||||
ServerLogoutHandler clearSiteData = new HeaderWriterServerLogoutHandler(writer);
|
||||
DelegatingServerLogoutHandler logoutHandler = new DelegatingServerLogoutHandler(securityContext, clearSiteData);
|
||||
|
||||
http
|
||||
// ...
|
||||
.logout()
|
||||
.logoutHandler(logoutHandler);
|
||||
.logoutHandler(logoutHandler);
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
It's not recommended that you configure this header writer via the `headers()` directive.
|
||||
The reason for this is that any session state, say the `JSESSIONID` cookie, would be removed, effectively logging the user out.
|
||||
====
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user