自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

讓我們一起來消滅CSRF跨站請(qǐng)求偽造(下)

安全 漏洞
在本系列文章的上集中,我們跟大家介紹了關(guān)于CSRF的一些基本概念,并對(duì)常見的幾種CSRF漏洞類型進(jìn)行了講解。那么接下來,我們就要跟大家討論一下如何才能消滅CSRF。

寫在前面的話

本系列文章的上集中,我們跟大家介紹了關(guān)于CSRF的一些基本概念,并對(duì)常見的幾種CSRF漏洞類型進(jìn)行了講解。那么接下來,我們就要跟大家討論一下如何才能消滅CSRF。

[[208441]]

現(xiàn)代保護(hù)機(jī)制

實(shí)際上,通過修改應(yīng)用程序源代碼來實(shí)現(xiàn)CSRF保護(hù)在很多情況下是不現(xiàn)實(shí)的,要么就是源代碼無法獲取,要么就是修改應(yīng)用程序的風(fēng)險(xiǎn)太高了。但我們所設(shè)計(jì)的解決方案可以輕松地部署到RASP、WAF、反向代理或均衡負(fù)載器中,并且可以同時(shí)保護(hù)一個(gè)或多個(gè)配置相同的應(yīng)用程序。

首先我們要知道,正確地使用安全或不安全的HTTP verb是非常重要的。雖然這一點(diǎn)并不能構(gòu)成一個(gè)有效的解決方案,但它是另外兩種方法實(shí)現(xiàn)的基礎(chǔ)。在構(gòu)建應(yīng)用程序之前,我們需要對(duì)其進(jìn)行架構(gòu)設(shè)計(jì)。幸運(yùn)的是,大多數(shù)現(xiàn)代Web框架都有路由的概念,并且可以強(qiáng)制讓節(jié)點(diǎn)與HTTP verb配對(duì)。在現(xiàn)代框架中,帶有錯(cuò)誤verb的請(qǐng)求將會(huì)導(dǎo)致錯(cuò)誤的產(chǎn)生。如果你的應(yīng)用程序中不能實(shí)現(xiàn)這種機(jī)制的話,請(qǐng)繼續(xù)往下看。

另一種方法是驗(yàn)證請(qǐng)求的發(fā)送源,這種方法可以確保發(fā)送給應(yīng)用程序的請(qǐng)求來自于一個(gè)受信任的源。在這里,正確使用HTTP verb同樣是非常重要的,如果我們假設(shè)只有改變狀態(tài)的請(qǐng)求會(huì)來自于不安全的請(qǐng)求,那我們就只需要對(duì)不安全的請(qǐng)求源進(jìn)行驗(yàn)證就可以了。但正如我們之前所討論的,在驗(yàn)證源的可靠性時(shí)我們還會(huì)遇到很多的問題。其中的一種解決方案是創(chuàng)建一個(gè)安全URL白名單,這樣就可以防止來自外部源的CSRF。

第三種方法,也是最常見的方法,即使用令牌Token。令牌本身有多種形式,但大多數(shù)使用的都是同步器令牌(synchronizer token)。說得更加詳細(xì)一點(diǎn),這種令牌主要分為“雙提交令牌”以及“加密令牌”。事實(shí)證明,結(jié)合使用雙提交令牌以及加密令牌可以提供最好的安全性。

簡(jiǎn)單說來,所謂的同步器令牌,就是服務(wù)器和瀏覽器之間需要同步一個(gè)令牌(唯一的)。安全的請(qǐng)求方法會(huì)返回一個(gè)令牌,當(dāng)瀏覽器在發(fā)送請(qǐng)求時(shí)會(huì)攜帶這個(gè)令牌,而服務(wù)器在處理請(qǐng)求之前,會(huì)驗(yàn)證令牌的有效性。處理完請(qǐng)求之后,服務(wù)器還會(huì)提供一個(gè)新的令牌以保證之前的令牌無法繼續(xù)使用(防止重放攻擊)。此時(shí),攻擊者將無法訪問到令牌或者將其插入到惡意請(qǐng)求之中,因?yàn)槿绻粽呦脒@樣做的話,他必須要強(qiáng)迫目標(biāo)用戶向遠(yuǎn)程網(wǎng)站發(fā)送請(qǐng)求并訪問請(qǐng)求內(nèi)容,但SOP可以防止這種情況的發(fā)生。這樣一來,攻擊者所能使用的最后一種方法就是利用目標(biāo)程序可能存在的XSS漏洞了。

需要注意的是,令牌主要有四個(gè)部分(一個(gè)隨機(jī)數(shù),用戶識(shí)別符,過期時(shí)間以及真實(shí)性驗(yàn)證信息)組成,因此保持其“整體完整性”就非常重要了,其中缺少任何一項(xiàng)都將導(dǎo)致令牌的安全性大打折扣。

在令牌機(jī)制的實(shí)現(xiàn)過程中,有兩個(gè)方面我們需要仔細(xì)斟酌,即服務(wù)器端和客戶端。其中,服務(wù)器端負(fù)責(zé)生成和驗(yàn)證令牌,而客戶端負(fù)責(zé)向需要請(qǐng)求資源的服務(wù)器發(fā)送令牌。需要注意的是,大家絕對(duì)有必要為每一個(gè)請(qǐng)求生成一個(gè)新的令牌,即使這樣會(huì)犧牲一定的性能。除此之外,你也可以在cookie中添加令牌,但你需要確保cookie沒有使用HttpOnly標(biāo)記。下面這段簡(jiǎn)單的示例代碼是生成令牌的常用方法:

  1. String generateToken(int userId, int key) { 
  2. byte[16] data = random() 
  3. expires = time() + 3600 
  4. raw = hex(data) + "-" + userId + "-" + expires 
  5. signature = hmac(sha256, raw, key) 
  6. return raw + "-" + signature 

大家可以從上面這段代碼中看到組成令牌的那四個(gè)部分。其中,HMAC是用于驗(yàn)證前三個(gè)元素有效性的令牌,并最終會(huì)添加到raw的結(jié)尾。

  1. bool validateToken(token, user) { 
  2. parts = token.split("-") 
  3. str = parts[0] + "-" + parts[1] + "-" + parts[2] 
  4. generated = hmac(sha256, str, key) 
  5. if !constantCompare(generated, parts[3]) { 
  6. return false 
  1. if parts[2] < time() { 
  2. return false 
  3. if parts[1] != user { 
  4. return false 
  5. return true 

上面這段示例代碼演示的是驗(yàn)證和計(jì)算令牌有效性的常用方法。首先我們需要將令牌拆分成它的四個(gè)組成部分,然后第一步就是利用前三個(gè)部分生成并驗(yàn)證HMAC的有效性(與之前的HMAC進(jìn)行對(duì)比)。對(duì)比時(shí)間一定要確保使用的是固定時(shí)間,這樣可以避免基于時(shí)間的攻擊。如果驗(yàn)證成功,我們接下來就要確保令牌沒有過期,最后進(jìn)行用戶匹配。但在真實(shí)場(chǎng)景中,最麻煩的事情就是讓用戶的瀏覽器在發(fā)送所有請(qǐng)求時(shí)自動(dòng)提交令牌。

實(shí)際上在開發(fā)應(yīng)用的過程中,絕大多數(shù)的現(xiàn)代框架都已經(jīng)幫我們搞定這一切了??蚣軒?kù)可以處理XHR,并將令牌自動(dòng)插入到請(qǐng)求信息(包括表單)中。但是如果框架沒有幫我們實(shí)現(xiàn)的話,我們也可以自己實(shí)現(xiàn)這種功能。這一步主要可以分為兩個(gè)部分,一個(gè)是處理表單提交,另一個(gè)是處理XHR。下面這段示例代碼可以處理onclick事件回調(diào):

  1. var target = evt.target; 
  2. while (target !== null) { 
  3. if (target.nodeName === 'A' || target.nodeName === 
  4. 'INPUT' || target.nodeName === 'BUTTON') { 
  5. break; 
  6.    
  7. targettarget = target.parentNode; 
  8.    
  9. // We didn't find any of the delegates, bail out 
  10. if (target === null) { 
  11. return; 

我們可以將這段代碼添加到文檔中,而不是添加到單獨(dú)的表單或可點(diǎn)擊的元素之中,因?yàn)楹苡锌赡鼙韱位蛟馗揪筒淮嬖谂c頁(yè)面DOM之中。我們所指的元素是用戶可以點(diǎn)擊的東西,由于DOM樹的結(jié)構(gòu)以及事件處理系統(tǒng)的不同,所以我們要尋找的是那種可以提交表單的元素,例如input或button標(biāo)簽。

接下來,我們可以檢測(cè)一個(gè)標(biāo)簽是否為input標(biāo)簽。如果它是,那么我們就可以確保這里有一個(gè)提交按鈕了。當(dāng)我們驗(yàn)證提交事件已經(jīng)被觸發(fā)之后,我們就可以繼續(xù)搜索DOM樹并尋找form標(biāo)簽了。如果找遍了DOM樹卻沒有找到form標(biāo)簽,那么就說明元素沒有被提交,除非它使用了XHR。找到form標(biāo)簽之后,最后一步就是將令牌以一個(gè)隱藏input元素添加到表單之中,即創(chuàng)建一個(gè)新的元素并將其添加到表單。

  1. var token = 
  2. form.querySelector('input[name="csrf_token"]'); 
  3.    
  4. var tokenValue = getCookieValue('CSRF-TOKEN'); 
  5. if (token !== undefined && token !== null) { 
  6. if (token.value !== tokenValue) { 
  7. token.value = tokenValue
  8. return; 
  9.    
  10. var newToken = document.createElement('input'); 
  11. newToken.setAttribute('type', 'hidden'); 
  12. newToken.setAttribute('name', 'csrf_token'); 
  13. newToken.setAttribute('value', tokenValue); 
  14. form.appendChild(newToken); 

對(duì)于那些并非基于表單的請(qǐng)求,我們就需要想辦法將令牌插入到XHR請(qǐng)求之中了。大多數(shù)代碼庫(kù)都提供了相關(guān)的抽象方法,包括jQuery,但我們需要針對(duì)標(biāo)準(zhǔn)XHR API創(chuàng)建我們自己的函數(shù)鉤子。通過利用JavaScript的原型繼承機(jī)制以及動(dòng)態(tài)特性,我們可以直接將原始的發(fā)送方法添加到對(duì)象之中,這樣我們就可以隨時(shí)調(diào)用這些方法了。接下來,我們需要?jiǎng)?chuàng)建一個(gè)新的函數(shù)并將令牌插入到cookie中,然后再在請(qǐng)求信息中添加一個(gè)帶值的header。

不過需要注意的是,對(duì)于IE瀏覽器,我們所設(shè)計(jì)的這種方法只適用于IE 8及其以上版本的IE瀏覽器,因?yàn)檫@些版本才支持方法原型和XHR,雖然IE 支持XHR但并不支持方法原型。具體的瀏覽器支持情況如下圖所示:

 

總結(jié)

在本系列文章中,我們跟大家介紹了關(guān)于CSRF的一些基本概念,并對(duì)常見的幾種CSRF漏洞類型進(jìn)行了講解。除此之外,我們還給大家提供了一些用于對(duì)付CSRF漏洞的最佳實(shí)踐方法。這里我給大家推薦一款名叫Same-Site的擴(kuò)展插件,它可以幫助我們對(duì)cookie進(jìn)行檢測(cè),并對(duì)瀏覽器所發(fā)送的cookie進(jìn)行嚴(yán)格的安全限制。這款插件的瀏覽器支持情況如下圖所示:

責(zé)任編輯:趙寧寧 來源: 安全客
相關(guān)推薦

2017-11-02 14:39:54

2012-04-14 20:47:45

Android

2013-08-19 10:59:48

2021-01-20 15:31:00

區(qū)塊鏈比特幣數(shù)字貨幣

2021-12-29 08:27:05

ByteBuffer磁盤服務(wù)器

2021-08-27 07:06:10

IOJava抽象

2022-03-08 17:52:58

TCP格式IP

2013-05-22 18:32:57

2022-03-31 18:59:43

數(shù)據(jù)庫(kù)InnoDBMySQL

2016-09-12 15:35:38

新華三

2019-01-09 10:06:29

交換機(jī)運(yùn)維 軟硬件

2022-02-14 07:03:31

網(wǎng)站安全MFA

2022-06-26 09:40:55

Django框架服務(wù)

2016-09-06 10:39:30

Dell Techno

2022-02-14 10:16:22

Axios接口HTTP

2021-07-15 07:23:28

Singlefligh設(shè)計(jì)

2021-11-26 07:00:05

反轉(zhuǎn)整數(shù)數(shù)字

2023-08-14 08:38:26

反射reflect結(jié)構(gòu)體

2011-04-19 13:40:27

2021-12-16 12:01:21

區(qū)塊鏈Libra貨幣
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)