领先一步
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 文档并查看它。恶意用户可能会创建一个 既是有效 Postscript 文件又是有效 JavaScript 文件的文档 并用它执行 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”头信息添加到响应中。例如,以下代码将指示浏览器将该域视为一年(大约 31536000 秒)的 HSTS 主机:
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()
...;
}
}
如果您遇到错误,有改进的想法等,请随时提出!我们希望听到您的想法,以便在代码普遍可用之前确保我们能够正确处理。尽早尝试新功能是回馈社区的一种简单有效的方式。这也确保了您想要的特性存在并且按您预期的方式工作。
请将任何问题或功能请求记录到 Spring Security JIRA。记录 JIRA 后,我们鼓励(但不强制要求)您在拉取请求中提交更改。您可以在 贡献者指南 中阅读有关如何执行此操作的更多信息。
如果您对如何执行某些操作有疑问,请使用 Spring Security 论坛 或 Stack Overflow 并使用标签 spring-security(我会密切关注它们)。如果您对这篇博文有具体的评论或疑问,请随时留下评论。使用合适的工具将使每个人都更容易。
您应该对 Spring Security 3.2.RC1 中的新功能有很好的了解。