领先一步
VMware 提供培训和认证,助您加速进步。
了解更多注意 本博文已不再维护。有关 Spring Security 的 Headers 的最新信息,请参阅 Headers 文档。
这是我关于 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 文件,它能够猜测内容类型并执行它。
内容嗅探的问题在于,它允许恶意用户使用多态文件(polyglots)(即,一个文件可以作为多种内容类型有效)来执行 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 严格传输安全 (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 样式,用户可能会被诱骗点击他们不打算点击的内容(视频演示)。例如,登录了银行的用户可能会点击一个授予其他用户访问权限的按钮。这种攻击被称为 点击劫持。
有许多方法可以缓解点击劫持攻击。例如,为了保护旧版浏览器免受点击劫持攻击,您可以使用 框架破坏代码。虽然不完美,但框架破坏代码是您为旧版浏览器所能做的最好的。
解决点击劫持的一种更现代的方法是使用 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()
...;
}
}
如果您遇到 bug、有改进的想法等,请随时提出!我们希望听到您的想法,以便在代码普遍可用之前确保我们做得正确。尽早试用新功能是回馈社区的一种良好而简单的方式。这也能确保您想要的功能存在并按您期望的方式工作。
请将任何问题或功能请求记录到 Spring Security JIRA。记录 JIRA 后,我们鼓励(但不是必需)您提交您的更改作为 pull request。您可以在 贡献者指南 中阅读更多关于如何执行此操作的信息。
如果您有关于如何做某事的问题,请使用 Spring Security 论坛 或 Stack Overflow 并使用 spring-security 标签(我将密切关注它们)。如果您对这篇博文有任何具体评论或问题,请随时发表评论。使用合适的工具将有助于让每个人都更容易。
您应该对 Spring Security 3.2.RC1 中存在的新功能有了很好的了解。