From 86340b8016b9da7a90ef52ca9d2b48481689d5af Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Thu, 29 Aug 2013 13:47:54 -0500 Subject: [PATCH] SEC-2283: Polish headers doc --- docs/manual/src/docbook/headers.xml | 468 +++++++++++-------- docs/manual/src/docbook/namespace-config.xml | 4 +- 2 files changed, 275 insertions(+), 197 deletions(-) diff --git a/docs/manual/src/docbook/headers.xml b/docs/manual/src/docbook/headers.xml index 0e2e4222b1..3eb41133ec 100644 --- a/docs/manual/src/docbook/headers.xml +++ b/docs/manual/src/docbook/headers.xml @@ -29,10 +29,23 @@ utilize the headers, so additional testing is encouraged. If you are using Spring Security's XML namespace support, you can easily add all of the default headers with the <headers> element with no child elements: - - ... + + + +]]> + Alternatively, you can choose to explicitly list the headers you wish to include. For example, the following is + the same the previous configuration. Removing any of the elements will remove that header from the responses. + + + + + + + + + + ]]> If you are using Spring Security's Java configuration, all of the default security headers are added by default. They can be disabled using the Java configuration below: @@ -44,32 +57,14 @@ public class WebSecurityConfig extends @Override protected void configure(HttpSecurity http) throws Exception { http - .headers().disable() - ...; + // ... + .headers().disable(); } }]]> - -
- 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. - - Simply adding the <headers /> element with no child elements will - automatically add Cache Control and quite a few other protections. However, if you only want cache control, you can - enable this feature using Spring Security's XML namespace with the - <cache-control /> element. - - ... - - - -]]> - Similarly, you can enable only cache control within Java Configuration with the following: - As soon as you specify any headers that should be included, then only those headers will be include. For example, the + following configuration will include support for Cache Control and + X-Frame-Options only. + - If you actually want to cache specific responses, your application can selectively invoke - HttpServletResponse.setHeader(String,String) - to override the header set by Spring Security. This is useful to ensure things - like CSS, JavaScript, and images are properly cached. - When using Spring Web MVC, this is typically done within your configuration. For example, the following configuration will - ensure that the cache headers are set for all of your resources: - + 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. + + Simply adding the <headers> element with no child elements will + automatically add Cache Control and quite a few other protections. However, if you only want cache control, you can + enable this feature using Spring Security's XML namespace with the + <cache-control> element. + + + + + + +]]> + Similarly, you can enable only cache control within Java Configuration with the following: + + If you actually want to cache specific responses, your application can selectively invoke + HttpServletResponse.setHeader(String,String) + to override the header set by Spring Security. This is useful to ensure things + like CSS, JavaScript, and images are properly cached. + When using Spring Web MVC, this is typically done within your configuration. For example, the following configuration will + ensure that the cache headers are set for all of your resources: + -
-
- Content Type Options - Historically browsers, including Internet Explorer, would try to guess the content type of a request using - 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. - - 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 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: - - Just as with the cache control element, the nosniff directive is added by default when using the <headers /> element with no child elements. - However, if you want more control over which headers are added you can use the - <content-type-options> element as shown below: - - ... +
+
+ Content Type Options + Historically browsers, including Internet Explorer, would try to guess the content type of a request using + 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. + + 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 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: + + Just as with the cache control element, the nosniff directive is added by default when using the <headers> element with no child elements. + However, if you want more control over which headers are added you can use the + <content-type-options> element as shown below: + + + ]]> - The X-Content-Type-Options header is added by default with Spring Security Java configuration. If you want more control over the headers, you can - explicitly specify the content type options with the following: - The X-Content-Type-Options header is added by default with Spring Security Java configuration. If you want more control over the headers, you can + explicitly specify the content type options with the following: + -
-
- 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 - 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 HTTP Strict Transport Security (HSTS) - was created. Once mybank.example.com is added as a 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. - - In accordance with 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): - - The optional includeSubDomains directive instructs Spring Security that subdomains (i.e. secure.mybank.example.com) should also be - treated as an HSTS domain. - As with the other headers, Spring Security adds the previous header to the response when the <headers> element is specified with - no child elements. It is also automatically added when you are using Java Configuration. You can also only use HSTS headers with the - <hsts> element as shown below: - - ... +
+
+ 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 + 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 HTTP Strict Transport Security (HSTS) + was created. Once mybank.example.com is added as a 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. + + In accordance with 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): + + The optional includeSubDomains directive instructs Spring Security that subdomains (i.e. secure.mybank.example.com) should also be + treated as an HSTS domain. + As with the other headers, Spring Security adds the previous header to the response when the <headers> element is specified with + no child elements. It is also automatically added when you are using Java Configuration. You can also only use HSTS headers with the + <hsts> element as shown below: + + + ]]> - Similarly, you can enable only HSTS headers with Java Configuration: - Similarly, you can enable only HSTS headers with Java Configuration: + -
-
- 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 ( - 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 - Clickjacking. - - Another modern approach to dealing with clickjacking is using a Content - Security Policy. Spring Security does not provide - support for this as the specification is not released and it is quite a bit more complicated. However, you could use the - static headers feature to implement this. To stay up to date with this - issue and to see how you can implement it with Spring Security refer to - SEC-2117 - - There are a number ways to mitigate clickjacking attacks. For example, to protect legacy browsers from clickjacking attacks you - can use - 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 - X-Frame-Options header: - - 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. As with the other response headers, this is automatically included when the <headers> element is specified with no - child elements. You can also explicitly specify the frame-options element to control which headers - are added to the response. - - ... +
+
+ 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 ( + 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 + Clickjacking. + + Another modern approach to dealing with clickjacking is using a Content + Security Policy. Spring Security does not provide + support for this as the specification is not released and it is quite a bit more complicated. However, you could use the + static headers feature to implement this. To stay up to date with this + issue and to see how you can implement it with Spring Security refer to + SEC-2117 + + There are a number ways to mitigate clickjacking attacks. For example, to protect legacy browsers from clickjacking attacks you + can use + 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 + X-Frame-Options header: + + 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. As with the other response headers, this is automatically included when the <headers> element is specified with no + child elements. You can also explicitly specify the frame-options element to control which headers + are added to the response. + + + ]]> - Similarly, you can enable only frame options within Java Configuration with the following: - Similarly, you can enable only frame options within Java Configuration with the following: + -
-
- X-XSS-Protection - Some browsers have built in support for filtering out - reflected - XSS attacks. This is by no means full proof, 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 - 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: - - This header is included by default when the <headers> element is specified with no child elements. We can explicitly - state it using the xss-protection element as shown below: - - ... + If you want to change the value for the X-Frame-Options header, then you can use a + XFrameOptionsHeaderWriter instance. +
+
+ X-XSS-Protection + Some browsers have built in support for filtering out + reflected + XSS attacks. This is by no means full proof, 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 + 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: + + This header is included by default when the <headers> element is specified with no child elements. We can explicitly + state it using the xss-protection element as shown below: + + + ]]> - Similarly, you can enable only xss protection within Java Configuration with the following: - Similarly, you can enable only xss protection within Java Configuration with the following: + +
-
- Static Headers - There may be times you wish to inject custom security headers into your application that are not supported out of the box. For example, perhaps - you wish to have early support for Content Security Policy in order to ensure that resources - are only loaded from the same origin. Since support for Content Security Policy has not been finalized, browsers use one of two common extension headers - to implement the feature. This means we will need to inject the policy twice. An example of the headers can be seen below: - + Custom Headers + 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. +
+ Static Headers + There may be times you wish to inject custom security headers into your application that are not supported out of the box. For example, perhaps + you wish to have early support for Content Security Policy in order to ensure that resources + are only loaded from the same origin. Since support for Content Security Policy has not been finalized, browsers use one of two common extension headers + to implement the feature. This means we will need to inject the policy twice. An example of the headers can be seen below: + - When using the XML namespace, these headers can be added to the response using the <header> element as - shown below: - - ... - -
-
- -]]> - Similarly, the headers could be added to the response using Java Configuration as shown in the following: - When using the XML namespace, these headers can be added to the response using the <header> element as + shown below: + + + + +
+
+ + ]]> + Similarly, the headers could be added to the response using Java Configuration as shown in the following: + -
-
- Headers Writer - When the namespace or Java configuration does not support the headers you want, you can create a custom HeadersWriter instance - or even provide a custom implementation of the HeadersWriter. - Let's take a look at an example of using an custom instance of XFrameOptionsHeaderWriter. Perhaps you want to allow framing of content - for the same origin. This is easily supported by setting the policy - attribute to "SAMEORIGIN", but let's take a look at a more explicit example. - - ... +
+
+ Headers Writer + When the namespace or Java configuration does not support the headers you want, you can create a custom HeadersWriter instance + or even provide a custom implementation of the HeadersWriter. + Let's take a look at an example of using an custom instance of XFrameOptionsHeaderWriter. Perhaps you want to allow framing of content + for the same origin. This is easily supported by setting the policy + attribute to "SAMEORIGIN", but let's take a look at a more explicit example using the ref attribute. + + + -
+
-]]> - We could also restrict framing of content to the same origin with Java configuration: - We could also restrict framing of content to the same origin with Java configuration: + -
+
+
+ DelegatingRequestMatcherHeaderWriter + At times you may want to only write a header for certain requests. For example, perhaps you want to only protect your log in page from being framed. You could use the + DelegatingRequestMatcherHeaderWriter to do so. When using the XML namespace configuration, this can be done with the following: + + + +
+ + + + + + + + + + +]]> + We could also prevent framing of content to the log in page using java configuration: + +
+ diff --git a/docs/manual/src/docbook/namespace-config.xml b/docs/manual/src/docbook/namespace-config.xml index 90ade594e4..7ecb9dd7a8 100644 --- a/docs/manual/src/docbook/namespace-config.xml +++ b/docs/manual/src/docbook/namespace-config.xml @@ -659,8 +659,8 @@ List<OpenIDAttribute> attributes = token.getAttributes();The ]]> - For additional information on how to customize the headers element refer to the headers - section of the Security Namespace appendix. + For additional information on how to customize the headers element refer to the Security Headers + section of the reference.
Adding in Your Own Filters