保持领先
VMware 提供培训和认证,助您加速进步。
了解更多注意:本博客文章不再维护。请参阅头文档,以获取关于 Spring Security 头的最新信息。
这是关于 Spring Security 3.2.0.RC1 的两部分系列文章的最后一篇。我的上一篇文章讨论了 Spring Security 的 CSRF 防护。在这篇文章中,我们将讨论如何使用 Spring Security 添加各种响应头来帮助保护您的应用程序。
Spring Security 3.2.0.RC1 中的许多新特性都是通过向响应添加头来实现的。这些特性的基础来自于 Marten Deinum 的辛勤工作。如果这个名字听起来很熟悉,那可能是因为他在 Spring 论坛上的 10K+ 篇帖子中的一篇曾经帮助过您。
如果您使用 XML 配置,可以通过使用 Spring Security 的
<http ...>
...
<headers />
</http>
如果您使用 Spring Security 的 Java 配置,所有默认安全头都将默认添加。您可以使用下面的 Java 配置禁用它们
```xml @EnableWebSecurity @Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Override protected void configure(HttpSecurity http) throws Exception { http .headers().disable() ...; } }```
<p>The remainder of this post will discuss each of the default headers in more detail:</p>
<ul>
<li><a href="#cache-control">Cache Control</a></li>
<li><a href="#content-type-options">Content Type Options</a></li>
<li><a href="#hsts">HTTP Strict Transport Security</a></li>
<li><a href="#x-frame-options">X-Frame-Options</a></li>
<li><a href="#x-xss-protection">X-XSS-PROTECTION</a></li>
</ul>
<p><a name="cache-control"></a></p>
<h3>Cache Control</h3>
<p>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.</p>
```xml
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
简单地添加
<http ...>
...
<headers>
<cache-control />
</headers>
</http>
同样,您可以在 Java 配置中仅启用缓存控制,如下所示
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.cacheControl()
.and()
...;
}
}
如果您确实想缓存特定的响应,您的应用程序可以选择性地调用 HttpServletResponse.setHeader(String,String) 来覆盖 Spring Security 设置的头。这对于确保 CSS、JavaScript 和图片等资源得到正确缓存非常有用。
使用 Spring Web MVC 时,这通常在您的配置中完成。例如,以下配置将确保为您的所有资源设置缓存头
@EnableWebMvc
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/")
.setCachePeriod(31556926);
}
// ...
}
从历史上看,包括 Internet Explorer 在内的浏览器会尝试使用内容嗅探来猜测请求的内容类型。这使得浏览器能够通过猜测未指定内容类型的资源的内容类型来改善用户体验。例如,如果浏览器遇到一个未指定内容类型的 JavaScript 文件,它就能够猜测内容类型然后执行它。
内容嗅探的问题在于,这允许恶意用户使用多语言文件(即,一个文件对多种内容类型都有效)来执行 XSS 攻击。例如,某些网站可能允许用户提交一个有效的 postscript 文档并查看它。恶意用户可能会创建一个同时也是有效 JavaScript 文件的 postscript 文档,并用它执行 XSS 攻击。
通过在响应中添加以下头可以禁用内容嗅探
X-Content-Type-Options: nosniff
与缓存控制元素一样,当使用
<http ...>
...
<headers>
<content-type-options />
</headers>
</http>
X-Content-Type-Options 头在 Spring Security Java 配置中默认添加。如果您想更精细地控制头,可以显式指定内容类型选项,如下所示
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.contentTypeOptions()
.and()
...;
}
}
当您输入银行网站时,您是输入 mybank.example.com 还是输入 https://mybank.example.com?如果您省略 https 协议,您可能容易受到中间人攻击。即使网站执行重定向到 https://mybank.example.com,恶意用户也可能拦截最初的 HTTP 请求并篡改响应(例如,重定向到 https://mibank.example.com 并窃取其凭据)。
许多用户省略了 https 协议,这就是创建HTTP Strict Transport Security (HSTS) 的原因。一旦 mybank.example.com 被添加为 HSTS 主机,浏览器就可以提前知道任何对 mybank.example.com 的请求都应被解释为 https://mybank.example.com。这大大降低了中间人攻击发生的可能性。
一个网站被标记为 HSTS 主机的方式之一是将其预加载到浏览器中。另一种方式是向响应中添加“Strict-Transport-Security”头。例如,以下内容将指示浏览器将该域视为 HSTS 主机一年(一年大约有 31536000 秒)
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
可选的 includeSubDomains 指令指示 Spring Security 子域(例如 secure.mybank.example.com)也应被视为 HSTS 域。
与其他头一样,当使用
<http ...>
...
<headers>
<hsts />
</headers>
</http>
同样,您可以在 Java 配置中仅启用 HSTS 头
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.hsts()
.and()
...;
}
}
允许您的网站被添加到框架中可能会带来安全问题。例如,使用巧妙的 CSS 样式,用户可能被欺骗点击他们不想点击的东西(视频演示)。例如,一个已登录银行的用户可能会点击一个授予其他用户访问权限的按钮。这种攻击被称为点击劫持(Clickjacking)。
有多种方法可以减轻点击劫持攻击。例如,为了保护旧版浏览器免受点击劫持攻击,您可以使用帧破坏代码。虽然不完美,但帧破坏代码是针对旧版浏览器的最佳方案。
更现代的解决点击劫持的方法是使用X-Frame-Options 头
X-Frame-Options: DENY
X-Frame-Options 响应头指示浏览器阻止响应中包含此头的任何网站在框架内呈现。与其他的响应头一样,当使用
<http ...>
...
<headers>
<frame-options />
</headers>
</http>
同样,您可以在 Java 配置中仅启用帧选项,如下所示
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.frameOptions()
.and()
...;
}
}
一些浏览器内置了过滤反射型 XSS 攻击的支持。这绝不是完全可靠的,但确实有助于 XSS 防护。
过滤功能通常默认启用,因此添加该头通常只是确保它已启用,并指示浏览器在检测到 XSS 攻击时执行什么操作。例如,过滤器可能会尝试以侵入性最小的方式更改内容,以便仍然渲染所有内容。有时,这种替换本身可能成为一个XSS 漏洞。相反,最好是阻止内容而不是尝试修复它。为此,我们可以添加以下头
X-XSS-Protection: 1; mode=block
当使用
<http ...>
...
<headers>
<xss-protection />
</headers>
</http>
同样,您可以在 Java 配置中仅启用 xss 防护,如下所示
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.xssProtection()
.and()
...;
}
}
如果您遇到错误、有改进的想法等,请不要犹豫提出来!我们希望听取您的想法,以确保在代码正式发布之前一切都正确。尽早试用新功能是回馈社区的好方法,也很简单。这还能确保您想要的功能得以存在并按照您期望的方式工作。
请将任何问题或功能请求记录到 Spring Security JIRA。在记录 JIRA 后,我们鼓励(但不要求)您以拉取请求的形式提交您的更改。您可以在贡献者指南中阅读有关如何执行此操作的更多信息。
如果您对如何执行某项操作有疑问,请使用Spring Security 论坛或Stack Overflow 并带上 spring-security 标签(我将密切关注)。如果您对此博客有具体的评论或问题,请随时发表评论。使用适当的工具将有助于让每个人都更轻松。
您应该对 Spring Security 3.2.RC1 中的新特性有了很好的理解。