javascript
SpringSecurity之CSRF漏洞保护
1.csrf簡介
CSRF(Cross-Site Request Forgery跨站請(qǐng)求偽造),也可稱為一鍵式攻擊(one-click-attack),通常縮寫為CSRF或者XSRF
CSRF攻擊是一種挾持用戶在當(dāng)前已登錄的瀏覽器上發(fā)送惡意請(qǐng)求的攻擊方法。相對(duì)于XSS利用用戶對(duì)指定網(wǎng)站的信任,CSRF則是利用網(wǎng)站對(duì)用戶網(wǎng)頁瀏覽器的信任。簡單來說,SCRF是攻擊者通過一些技術(shù)手段欺騙用戶的瀏覽器,去訪問一個(gè)用戶曾經(jīng)認(rèn)證過的網(wǎng)站并執(zhí)行惡意請(qǐng)求,例如發(fā)送郵件、發(fā)消息、甚至財(cái)產(chǎn)操作(如轉(zhuǎn)賬和購買商品)。由于客戶端(瀏覽器)已經(jīng)在該網(wǎng)站上認(rèn)證過,所以該網(wǎng)站會(huì)認(rèn)為是真正用戶在操作而執(zhí)行請(qǐng)求(實(shí)際上這個(gè)并非用戶的本意)。
例子:
假設(shè)zkt現(xiàn)在登錄了某銀行的網(wǎng)站準(zhǔn)備完成一項(xiàng)轉(zhuǎn)賬操作,轉(zhuǎn)賬的鏈接如下:
https://bank.xxx.com/withdrwa?account=zkt&amount=1000for=zhangsan
可以看到,這個(gè)連接是想從zkt這個(gè)賬戶下轉(zhuǎn)賬1000元到張三賬戶下,假設(shè)zkt沒有注銷登錄該銀行的網(wǎng)站,就在同一個(gè)瀏覽器新的選項(xiàng)卡中打開了一個(gè)危險(xiǎn)網(wǎng)站,這個(gè)危險(xiǎn)網(wǎng)站中有一幅圖片,代碼如下:
一旦用戶打開了這個(gè)網(wǎng)站,這個(gè)圖片鏈接中的請(qǐng)求就會(huì)被發(fā)送出去。由于是同一個(gè)瀏覽器并且用戶尚未注銷登錄,所以該請(qǐng)求會(huì)自動(dòng)攜帶上對(duì)應(yīng)的有效的cookie信息,進(jìn)而完成一次轉(zhuǎn)賬操作。這就是跨站請(qǐng)求偽造。
2.csrf防御
CSRF攻擊的根源在于瀏覽器默認(rèn)的身份驗(yàn)證機(jī)制(自動(dòng)攜帶當(dāng)前網(wǎng)站的Cookie信息),這種機(jī)制雖然可以保證請(qǐng)求是來自用戶的某個(gè)瀏覽器,但是無法確保這請(qǐng)求是用戶授權(quán)發(fā)送。攻擊者和用戶發(fā)送的請(qǐng)求一模一樣,這意味著我們沒有辦法去直接拒絕這里的某一個(gè)請(qǐng)求。如果能在合法請(qǐng)求中額外攜帶一個(gè)攻擊者無法獲取的參數(shù),就可以成功區(qū)分出兩種不同的請(qǐng)求,進(jìn)而直接拒絕掉惡意請(qǐng)求。在SpringSecurity中就提供了這種機(jī)制來防御CSRF攻擊,這種機(jī)制我們稱之為令牌同步模式。
3.令牌同步模式
這是目前主流的CSRF攻擊防御方案。具體的操作方式就是在每一個(gè)HTTP請(qǐng)求中,除了默認(rèn)自動(dòng)攜帶的Cookie參數(shù)之外,再提供一個(gè)安全的、隨機(jī)生成的字符串,我們稱之為CSRF令牌。這個(gè)CSRF令牌由服務(wù)端生成,生成后再HttpSession中保存一份。當(dāng)前端請(qǐng)求到達(dá)后,將請(qǐng)求攜帶的CSRF令牌信息和服務(wù)端中保存的令牌進(jìn)行對(duì)比,如果兩者不相等,則拒絕掉該HTTP請(qǐng)求。
注意:考慮到會(huì)有一些外部站點(diǎn)鏈接到我們的網(wǎng)站,所以我們要求請(qǐng)求是冪等的,這樣對(duì)于HEAD、OPTIONS、TRACE等方法就沒有必要使用CSRF令牌了,強(qiáng)行使用可能會(huì)導(dǎo)致令牌泄露。4.開啟CSRF防御
@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeHttpRequests().anyRequest().authenticated().and().formLogin().and().csrf(); //開啟csrf}5.傳統(tǒng)Web開發(fā)使用CSRF防御
開啟CSRF防御后會(huì)自動(dòng)在提交的表單中加入如下代碼,如果不能自動(dòng)加入,需要在開啟之后手動(dòng)加入如下代碼,并隨著請(qǐng)求提交。獲取服務(wù)端令牌方式如下:
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>6.前后端分離使用CSRF防御
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter {//...@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeHttpRequests().anyRequest().authenticated().and().formLogin().and().csrf()//開啟csrf // .disable();.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); //將令牌保存到cookie中 允許cookie前端獲取http.addFilterAt(loginFilter(), UsernamePasswordAuthenticationFilter.class);} }訪問登錄界面查看cookie
發(fā)送請(qǐng)求攜帶令牌即可
- 請(qǐng)求參數(shù)中攜帶令牌
- 請(qǐng)求頭中攜帶令牌
總結(jié)
以上是生活随笔為你收集整理的SpringSecurity之CSRF漏洞保护的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数字信号处理——DDS模块设计(3)
- 下一篇: gradle idea java ssm