安全響應(yīng)頭
1. 前言
上節(jié)我們討論了 Spring Security 如何防范 CSRF 攻擊,本節(jié)我們討論如何用最簡(jiǎn)單的方式提升 Spring Security Web 項(xiàng)目的安全性。
Spring Security 可以通過(guò)「HTTP 安全響應(yīng)頭」的方式提升安全性。
本節(jié)我們討論如何實(shí)現(xiàn) HTTP 安全響應(yīng)頭。
2. 安全響應(yīng)頭
Spring Security 提供了一些默認(rèn) HTTP 安全性相關(guān)的響應(yīng)頭。這些默認(rèn)響應(yīng)頭如下:
2.1 Cache-Control
當(dāng)用戶通過(guò)了認(rèn)證,訪問(wèn)了敏感信息而后點(diǎn)擊了退出,此時(shí)若瀏覽器對(duì)頁(yè)面進(jìn)行了緩存,攻擊者就可能通過(guò)點(diǎn)擊瀏覽器「后退」按鍵訪問(wèn)到剛剛認(rèn)證用戶看到的內(nèi)容。
Spring Security 默認(rèn)禁用瀏覽器頁(yè)面緩存,這樣可以減少敏感信息泄漏風(fēng)險(xiǎn)。
2.2 Content Type Options
瀏覽器為了增強(qiáng)用戶體驗(yàn),會(huì)去嗅探用戶請(qǐng)求的內(nèi)容格式。例如當(dāng)瀏覽器訪問(wèn)到某個(gè) JavaScript 文件,然而此時(shí)并沒(méi)有指定其文件類型,此時(shí)瀏覽器則會(huì)自動(dòng)判斷并且執(zhí)行它。
內(nèi)容嗅探帶來(lái)了一些問(wèn)題,比如攻擊者會(huì)利用某些可被解析成多種內(nèi)容格式的文件,執(zhí)行 XSS 攻擊。例如,有些網(wǎng)站可能允許用戶上傳和預(yù)覽 PostScript 代碼,攻擊者創(chuàng)建一個(gè) PostScript 文檔,同時(shí)該文檔也是一個(gè) JavaScript 格式文件,此時(shí),攻擊者便可以實(shí)現(xiàn) XSS 攻擊。
Spring Security 默認(rèn)禁用了內(nèi)容嗅探功能。
2.3 HTTP Strict Transport Security (HSTS)
通常我們?cè)L問(wèn)網(wǎng)站的時(shí)候是直接輸入域名,比如:mybank.example.com,此時(shí)默認(rèn)情況下瀏覽器會(huì)訪問(wèn) http://mybank.example.com。HTTP 協(xié)議由于信息不加密,無(wú)法保證訪問(wèn)目標(biāo)的真實(shí)性,容易受到中間人攻擊。增加 Strict-Transport-Security 響應(yīng)頭,可以強(qiáng)制將訪問(wèn)協(xié)議轉(zhuǎn)換成 Https。
2.4 X-Frame-Options
允許網(wǎng)站被放到 iframe 對(duì)象里,這種情況下攻擊者可能通過(guò)設(shè)置 CSS,讓用戶的點(diǎn)擊發(fā)生在非意愿的位置。
默認(rèn)情況下 Spring Security 拒絕網(wǎng)頁(yè)在 iframe 對(duì)象中渲染。
2.5 X-XSS-Protection
盡管大部分瀏覽器都已經(jīng)內(nèi)置了過(guò)濾 XSS 攻擊的支持,但也并非所有瀏覽器都默認(rèn)支持。增加 XSS-Protection 頭可以確保 XSS 攻擊過(guò)濾已啟動(dòng)。
3. Spring Security 配置
3.1 默認(rèn)的安全頭配置
Spring Security 提供了一系列默認(rèn) Http 安全響應(yīng)頭,我們可以便捷的配置它們。
例如,為 X-Frame-Options
指定值 SAMEORIGIN
:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
http.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.sameOrigin()));
}
}
如果不希望默認(rèn)頭被自動(dòng)添加,可以通過(guò)如下方式配置,例如僅添加 Cache Control 頭:
@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
// 取消自動(dòng)添加默認(rèn)頭
.defaultsDisabled()
// 添加 CacheControl 頭
.cacheControl(withDefaults())
);
}
}
或者通過(guò)以下方式禁用所有 HTTP 安全響應(yīng)頭:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers(headers -> headers.disable());
}
}
3.2 Cache Control
Spring Security 默認(rèn)包含「Cache Control」頭。
如果只需要緩存指定類型的內(nèi)容,我們可以通過(guò) HttpServletResponse.setHeader(String,String)
方式指定緩存項(xiàng),如 CSS、JavaScript、圖片等。
我們也可以直接禁用掉「Cache Control」頭,方式如下:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
http.headers(headers -> headers.cacheControl(cache -> cache.disable()));
}
}
3.3 Content-Type 頭
Spring Security 默認(rèn)包含了 Content-Type
頭。如果需要禁用它,可以通過(guò)如下方式:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
http.headers(headers -> headers.contentTypeOptions(contentTypeOptions -> contentTypeOptions.disable()));
}
}
3.4 HSTS 頭
HTTP Strict Transport Security(HSTS)頭,在 Spring Security 中是被默認(rèn)開(kāi)啟的,我們可以修改它的默認(rèn)狀態(tài),如下:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.httpStrictTransportSecurity(hsts -> hsts
.includeSubDomains(true)
.preload(true)
.maxAgeInSeconds(31536000)
)
);
}
}
3.5 X-Frame-Options 頭
默認(rèn)情況下,Spring Security 通過(guò) X-Frame-Options 頭方式禁止 iframe 層渲染,我們可以通過(guò)如下方式修改其配置:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.sameOrigin()));
}
}
3.6 X-XSS-Protection 頭
默認(rèn)情況下,Spring Security 為了防止 XSS 攻擊增加了 X-XSS-Protection 頭,我們可以通過(guò)以下方式對(duì)其配置進(jìn)行修改:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers(headers -> headers.xssProtection(xss -> xss.block(false)));
}
}
3.7 自定義響應(yīng)頭
Spring Security 的實(shí)現(xiàn)機(jī)制使得它可以輕易的添加安全響應(yīng)頭。
3.7.1 靜態(tài)頭
例如配置如下自定義頭:
X-Custom-Security-Header: header-value
我們可以通過(guò) StaticHeadersWriter 對(duì)象添加:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers(headers -> headers.addHeaderWriter(new StaticHeadersWriter("X-Custom-Security-Header","header-value")));
}
}
3.7.2 動(dòng)態(tài)添加
當(dāng)Spring Security 的默認(rèn)配置方式不能滿足我們添加響應(yīng)頭的需求時(shí),我們可以通過(guò) HeadersWriter
實(shí)例動(dòng)態(tài)添加。例如動(dòng)態(tài)添加 X-Frame-Options
頭:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers(headers -> headers.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN)));
}
}
3.7.3 為指定請(qǐng)求添加響應(yīng)頭
有時(shí)候我們只想為某個(gè)確定的請(qǐng)求添加響應(yīng)頭,例如只針對(duì)對(duì)登錄頁(yè)面的請(qǐng)求,這是可以通過(guò) DelegatingRequestMatcherHeaderWriter
實(shí)現(xiàn)。例如:
@EnableWebSecurity
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(headers -> headers.frameOptions(frameOptions -> frameOptions.disable()).addHeaderWriter(headerWriter));
}
}
4. 小結(jié)
本節(jié)討論了如何利用 HTTP 請(qǐng)求頭提升 Spring Security Web 項(xiàng)目的安全性,主要內(nèi)容有:
- Http 安全響應(yīng)頭是提升 B/S 應(yīng)用安全性的有效手段;
- Spring Security 默認(rèn)實(shí)現(xiàn)了常用的安全響應(yīng)頭;
- Spring Security 可以通過(guò)配置類,直接開(kāi)啟、關(guān)閉或調(diào)整各個(gè)內(nèi)置請(qǐng)求頭的狀態(tài)及參數(shù);
- Spring Security 提供了靜態(tài)設(shè)置響應(yīng)頭的方法;
- Spring Security 支持動(dòng)態(tài)添加響應(yīng)頭;
- Spring Security 支持針對(duì)某個(gè)特殊請(qǐng)求動(dòng)態(tài)設(shè)置響應(yīng)頭。
下節(jié)我們討論針對(duì) HTTP 協(xié)議,我們還能有哪些安全性提升策略。