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, 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 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> <link linkend="nsa-headers">&lt;headers&gt;</link> element with no child elements:</para>
<programlisting language="xml"><![CDATA[ <programlisting language="xml"><![CDATA[<http>
<http ...> <!-- ... -->
...
<headers /> <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> </http>]]></programlisting>
<para>If you are using Spring Security's Java configuration, all of the default security headers are added by default. <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> They can be disabled using the Java configuration below:</para>
@ -44,11 +57,27 @@ public class WebSecurityConfig extends
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http 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> }]]></programlisting>
</section>
<section xml:id="headers-cache-control"> <section xml:id="headers-cache-control">
<title>Cache Control</title> <title>Cache Control</title>
<para>In the past Spring Security required you to provide your own cache control for your web application. This <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> which will insert the following headers into you response.</para>
<programlisting><![CDATA[Cache-Control: no-cache, no-store, max-age=0, must-revalidate <programlisting><![CDATA[Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache]]></programlisting> 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 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 enable this feature using Spring Security's XML namespace with the
<link linkend="nsa-cache-control">&lt;cache-control /&gt;</link> element.</para> <link linkend="nsa-cache-control">&lt;cache-control&gt;</link> element.</para>
<programlisting langauage="xml"><![CDATA[<http ...> <programlisting language="xml"><![CDATA[<http>
... <!-- ... -->
<headers> <headers>
<cache-control /> <cache-control />
</headers> </headers>
@ -77,10 +107,9 @@ public class WebSecurityConfig extends
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
// ...
.headers() .headers()
.cacheControl() .cacheControl();
.and()
...;
} }
}]]></programlisting> }]]></programlisting>
<para>If you actually want to cache specific responses, your application can selectively invoke <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> 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> <para>Content sniffing can be disabled by adding the following header to our response:</para>
<programlisting><![CDATA[X-Content-Type-Options: nosniff]]></programlisting> <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 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> <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> <headers>
<content-type-options /> <content-type-options />
</headers> </headers>
@ -141,10 +171,9 @@ public class WebSecurityConfig extends
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
// ...
.headers() .headers()
.contentTypeOptions() .contentTypeOptions();
.and()
...;
} }
}]]></programlisting> }]]></programlisting>
</section> </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 <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 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> <link linkend="nsa-hsts">&lt;hsts&gt;</link> element as shown below:</para>
<programlisting language="xml"><![CDATA[<http ...> <programlisting language="xml"><![CDATA[<http>
... <!-- ... -->
<headers> <headers>
<hsts /> <hsts />
</headers> </headers>
@ -188,10 +218,9 @@ public class WebSecurityConfig extends
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
// ...
.headers() .headers()
.hsts() .hsts();
.and()
...;
} }
}]]></programlisting> }]]></programlisting>
</section> </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 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 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> are added to the response.</para>
<programlisting language="xml"><![CDATA[<http ...> <programlisting language="xml"><![CDATA[<http>
... <!-- ... -->
<headers> <headers>
<frame-options /> <frame-options />
</headers> </headers>
@ -236,12 +266,13 @@ public class WebSecurityConfig extends
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
// ...
.headers() .headers()
.frameOptions() .frameOptions();
.and()
...;
} }
}]]></programlisting> }]]></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>
<section xml:id="headers-xss-protection"> <section xml:id="headers-xss-protection">
<title>X-XSS-Protection</title> <title>X-XSS-Protection</title>
@ -257,8 +288,9 @@ public class WebSecurityConfig extends
<programlisting><![CDATA[X-XSS-Protection: 1; mode=block]]></programlisting> <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 <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> 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> <headers>
<xss-protection /> <xss-protection />
</headers> </headers>
@ -272,13 +304,17 @@ public class WebSecurityConfig extends
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
// ...
.headers() .headers()
.xssProtection() .xssProtection();
.and()
...;
} }
}]]></programlisting> }]]></programlisting>
</section> </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"> <section xml:id="headers-static">
<title>Static Headers</title> <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 <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> 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 <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> shown below:</para>
<programlisting language="xml"><![CDATA[<http ...> <programlisting language="xml"><![CDATA[<http>
... <!-- ... -->
<headers> <headers>
<header name="X-Content-Security-Policy" value="default-src 'self'"/> <header name="X-Content-Security-Policy" value="default-src 'self'"/>
<header name="X-WebKit-CSP" value="default-src 'self'"/> <header name="X-WebKit-CSP" value="default-src 'self'"/>
</headers> </headers>
</http>]]></programlisting> </http>]]></programlisting>
<para>Similarly, the headers could be added to the response using Java Configuration as shown in the following:</para> <para>Similarly, the headers could be added to the response using Java Configuration as shown in the following:</para>
<programlisting language="java"><![CDATA[@EnableWebSecurity <programlisting language="java"><![CDATA[@EnableWebSecurity
@Configuration @Configuration
@ -305,11 +342,10 @@ public class WebSecurityConfig extends
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
// ...
.headers() .headers()
.addHeaderWriter(new StaticHeaderWriter("X-Content-Security-Policy","default-src 'self'")) .addHeaderWriter(new StaticHeaderWriter("X-Content-Security-Policy","default-src 'self'"))
.addHeaderWriter(new StaticHeaderWriter("X-WebKit-CSP","default-src 'self'")) .addHeaderWriter(new StaticHeaderWriter("X-WebKit-CSP","default-src 'self'"));
.and()
...;
} }
}]]></programlisting> }]]></programlisting>
</section> </section>
@ -319,19 +355,21 @@ public class WebSecurityConfig extends
or even provide a custom implementation of the <interfacename>HeadersWriter</interfacename>.</para> 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 <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> 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> 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 ...> <programlisting language="xml"><![CDATA[<http>
... <!-- ... -->
<headers> <headers>
<header header-ref="frameOptionsWriter"/> <header ref="frameOptionsWriter"/>
</headers> </headers>
</http> </http>
<!-- Requires the c-namespace. <!-- Requires the c-namespace.
See http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-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" class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"
c:frameOptionsMode="SAMEORIGIN"/>]]></programlisting> c:frameOptionsMode="SAMEORIGIN"/>]]></programlisting>
<para>We could also restrict framing of content to the same origin with Java configuration:</para> <para>We could also restrict framing of content to the same origin with Java configuration:</para>
<programlisting language="java"><![CDATA[@EnableWebSecurity <programlisting language="java"><![CDATA[@EnableWebSecurity
@Configuration @Configuration
@ -341,12 +379,52 @@ public class WebSecurityConfig extends
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
// ...
.headers() .headers()
.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN)) .addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN));
.and()
...;
} }
}]]></programlisting> }]]></programlisting>
</section> </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> </chapter>

View File

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