SEC-2283: Polish headers doc

This commit is contained in:
Rob Winch 2013-08-29 13:47:54 -05:00
parent ae368829f4
commit 86340b8016
2 changed files with 275 additions and 197 deletions

View File

@ -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
<link linkend="nsa-headers">&lt;headers&gt;</link> element with no child elements:</para>
<programlisting language="xml"><![CDATA[
<http ...>
...
<programlisting language="xml"><![CDATA[<http>
<!-- ... -->
<headers />
</http>]]></programlisting>
<para>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.</para>
<programlisting language="xml"><![CDATA[<http>
<!-- ... -->
<headers>
<cache-control />
<content-type-options />
<hsts />
<frame-options />
<xss-protection />
</headers>
</http>]]></programlisting>
<para>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:</para>
@ -44,11 +57,27 @@ public class WebSecurityConfig extends
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().disable()
...;
// ...
.headers().disable();
}
}]]></programlisting>
<para>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 <link linkend="headers-cache-control">Cache Control</link> and
<link linkend="headers-frame-options">X-Frame-Options</link> only.</para>
<programlisting language="java"><![CDATA[@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.headers()
.cacheControl()
.frameOptions();
}
}]]></programlisting>
</section>
<section xml:id="headers-cache-control">
<title>Cache Control</title>
<para>In the past Spring Security required you to provide your own cache control for your web application. This
@ -58,12 +87,13 @@ public class WebSecurityConfig extends
which will insert the following headers into you response.</para>
<programlisting><![CDATA[Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache]]></programlisting>
<para>Simply adding the <link linkend="nsa-headers">&lt;headers /&gt;</link> element with no child elements will
<para>Simply adding the <link linkend="nsa-headers">&lt;headers&gt;</link> 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
<link linkend="nsa-cache-control">&lt;cache-control /&gt;</link> element.</para>
<programlisting langauage="xml"><![CDATA[<http ...>
...
<link linkend="nsa-cache-control">&lt;cache-control&gt;</link> element.</para>
<programlisting language="xml"><![CDATA[<http>
<!-- ... -->
<headers>
<cache-control />
</headers>
@ -77,10 +107,9 @@ public class WebSecurityConfig extends
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.headers()
.cacheControl()
.and()
...;
.cacheControl();
}
}]]></programlisting>
<para>If you actually want to cache specific responses, your application can selectively invoke
@ -122,11 +151,12 @@ public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
JavaScript file</link> and execute a XSS attack with it.</para>
<para>Content sniffing can be disabled by adding the following header to our response:</para>
<programlisting><![CDATA[X-Content-Type-Options: nosniff]]></programlisting>
<para>Just as with the cache control element, the nosniff directive is added by default when using the &lt;headers /&gt; element with no child elements.
<para>Just as with the cache control element, the nosniff directive is added by default when using the &lt;headers&gt; element with no child elements.
However, if you want more control over which headers are added you can use the
<link linkend="nsa-content-type-options">&lt;content-type-options&gt;</link> element as shown below:</para>
<programlisting language="xml"><![CDATA[<http ...>
...
<programlisting language="xml"><![CDATA[<http>
<!-- ... -->
<headers>
<content-type-options />
</headers>
@ -141,10 +171,9 @@ public class WebSecurityConfig extends
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.headers()
.contentTypeOptions()
.and()
...;
.contentTypeOptions();
}
}]]></programlisting>
</section>
@ -173,8 +202,9 @@ public class WebSecurityConfig extends
<para>As with the other headers, Spring Security adds the previous header to the response when the &lt;headers&gt; 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
<link linkend="nsa-hsts">&lt;hsts&gt;</link> element as shown below:</para>
<programlisting language="xml"><![CDATA[<http ...>
...
<programlisting language="xml"><![CDATA[<http>
<!-- ... -->
<headers>
<hsts />
</headers>
@ -188,10 +218,9 @@ public class WebSecurityConfig extends
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.headers()
.hsts()
.and()
...;
.hsts();
}
}]]></programlisting>
</section>
@ -221,8 +250,9 @@ public class WebSecurityConfig extends
within a frame. As with the other response headers, this is automatically included when the &lt;headers&gt; element is specified with no
child elements. You can also explicitly specify the <link linkend="nsa-frame-options">frame-options</link> element to control which headers
are added to the response.</para>
<programlisting language="xml"><![CDATA[<http ...>
...
<programlisting language="xml"><![CDATA[<http>
<!-- ... -->
<headers>
<frame-options />
</headers>
@ -236,12 +266,13 @@ public class WebSecurityConfig extends
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.headers()
.frameOptions()
.and()
...;
.frameOptions();
}
}]]></programlisting>
<para>If you want to change the value for the X-Frame-Options header, then you can use a
<link linkend="headers-headers-writer">XFrameOptionsHeaderWriter instance</link>.</para>
</section>
<section xml:id="headers-xss-protection">
<title>X-XSS-Protection</title>
@ -257,8 +288,9 @@ public class WebSecurityConfig extends
<programlisting><![CDATA[X-XSS-Protection: 1; mode=block]]></programlisting>
<para>This header is included by default when the &lt;headers&gt; element is specified with no child elements. We can explicitly
state it using the <link linkend="nsa-xss-protection">xss-protection</link> element as shown below:</para>
<programlisting language="xml"><![CDATA[<http ...>
...
<programlisting language="xml"><![CDATA[<http>
<!-- ... -->
<headers>
<xss-protection />
</headers>
@ -272,13 +304,17 @@ public class WebSecurityConfig extends
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.headers()
.xssProtection()
.and()
...;
.xssProtection();
}
}]]></programlisting>
</section>
</section>
<section xml:id="headers-custom">
<title>Custom Headers</title>
<para>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.</para>
<section xml:id="headers-static">
<title>Static Headers</title>
<para>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
@ -289,13 +325,14 @@ public class WebSecurityConfig extends
X-WebKit-CSP: default-src 'self']]></programlisting>
<para>When using the XML namespace, these headers can be added to the response using the <link linkend="nsa-header">&lt;header&gt;</link> element as
shown below:</para>
<programlisting language="xml"><![CDATA[<http ...>
...
<programlisting language="xml"><![CDATA[<http>
<!-- ... -->
<headers>
<header name="X-Content-Security-Policy" value="default-src 'self'"/>
<header name="X-WebKit-CSP" value="default-src 'self'"/>
</headers>
</http>]]></programlisting>
</http>]]></programlisting>
<para>Similarly, the headers could be added to the response using Java Configuration as shown in the following:</para>
<programlisting language="java"><![CDATA[@EnableWebSecurity
@Configuration
@ -305,11 +342,10 @@ public class WebSecurityConfig extends
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.headers()
.addHeaderWriter(new StaticHeaderWriter("X-Content-Security-Policy","default-src 'self'"))
.addHeaderWriter(new StaticHeaderWriter("X-WebKit-CSP","default-src 'self'"))
.and()
...;
.addHeaderWriter(new StaticHeaderWriter("X-WebKit-CSP","default-src 'self'"));
}
}]]></programlisting>
</section>
@ -319,19 +355,21 @@ public class WebSecurityConfig extends
or even provide a custom implementation of the <interfacename>HeadersWriter</interfacename>.</para>
<para>Let's take a look at an example of using an custom instance of <classname>XFrameOptionsHeaderWriter</classname>. Perhaps you want to allow framing of content
for the same origin. This is easily supported by setting the <link linkend="nsa-frame-options-policy">policy</link>
attribute to "SAMEORIGIN", but let's take a look at a more explicit example.</para>
<programlisting language="xml"><![CDATA[<http ...>
...
attribute to "SAMEORIGIN", but let's take a look at a more explicit example using the <link linkend="nsa-header-ref">ref</link> attribute.</para>
<programlisting language="xml"><![CDATA[<http>
<!-- ... -->
<headers>
<header header-ref="frameOptionsWriter"/>
<header ref="frameOptionsWriter"/>
</headers>
</http>
<!-- Requires the c-namespace.
See http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-c-namespace
-->
<bean:bean id="frameOptionsWriter"
<beans:bean id="frameOptionsWriter"
class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"
c:frameOptionsMode="SAMEORIGIN"/>]]></programlisting>
<para>We could also restrict framing of content to the same origin with Java configuration:</para>
<programlisting language="java"><![CDATA[@EnableWebSecurity
@Configuration
@ -341,12 +379,52 @@ public class WebSecurityConfig extends
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.headers()
.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
.and()
...;
.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN));
}
}]]></programlisting>
</section>
<section xml:id="headers-delegatingrequestmatcherheaderwriter">
<title>DelegatingRequestMatcherHeaderWriter</title>
<para>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
<classname>DelegatingRequestMatcherHeaderWriter</classname> to do so. When using the XML namespace configuration, this can be done with the following:</para>
<programlisting language="xml"><![CDATA[<http>
<!-- ... -->
<headers>
<header header-ref="headerWriter"/>
</headers>
</http>
<beans:bean id="headerWriter"
class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
<beans:constructor-arg>
<bean class="org.springframework.security.web.util.AntPathRequestMatcher"
c:pattern="/login"/>
</beans:constructor-arg>
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"/>
</beans:constructor-arg>
</beans:bean>]]></programlisting>
<para>We could also prevent framing of content to the log in page using java configuration:</para>
<programlisting language="java"><![CDATA[@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
RequestMatcher matcher = new AntPathRequestMatcher("/login");
DelegatingRequestMatcherHeaderWriter headerWriter =
new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());
http
// ...
.headers()
.addHeaderWriter(headerWriter);
}
}]]></programlisting>
</section>
</section>
</chapter>

View File

@ -659,8 +659,8 @@ List&lt;OpenIDAttribute> attributes = token.getAttributes();</programlisting>The
</http>]]>
</programlisting>
</para>
<para>For additional information on how to customize the headers element refer to the <link linkend="nsa-headers">headers</link>
section of the Security Namespace appendix.</para>
<para>For additional information on how to customize the headers element refer to the <link linkend="headers">Security Headers</link>
section of the reference.</para>
</section>
<section xml:id="ns-custom-filters">
<title>Adding in Your Own Filters</title>