CSRF漏洞跨域攜帶cookie問題


CSRF漏洞跨域攜帶cookie問題

1. CSRF漏洞

  用戶在登錄A網站www.a.com,獲取會話憑證sessionid,記錄在Cookie
  
  此時用戶在同一窗口中打開新標簽頁網站Bwww.b.com,網站B中含有惡意請求,請求內容為網站A中的接口
  
  在用戶打開網站B后,瀏覽器會自動發起請求,這個時候會自動帶上A網站的Cookie
  
  即在用戶無感的情況下,完成了一次以用戶身份對A網站的惡意請求

2. 什么情況下會發生CSRF

  ①用戶會話憑證存放在Cookie
  ②使用Cookie中的會話憑證進行身份認證(有可能Cookie中存放了sessionid值,但是實際身份驗證是對Header頭中的自定義字段Auth:sessionid進行驗證)
  ③后端未校驗Referer字段(Referer字段記錄HTTP請求源地址)
  ④后端允許跨域請求(非簡單請求,OPTIONS請求預檢)
  ⑤使用GET請求進行重要操作(增刪改查)(http://www.a.com/creat.php?username=123&password=456)(並非只有GET請求會遭受攻擊,只是GET請求較容易實現CSRF攻擊)

3. CSRF的利用方式

  ①使用HTML標簽發送正常跨域請求
  ②通過JS發送請求(CORS策略限制)

4. 實際滲透遇到問題

4.1 同源策略

  同源策略是指兩個URL的協議、域名、端口相同的話,那么這兩個URL為同源。
  關於同源策略的官方說明
  
  總的來說有以下三點限制:
    1.無法讀取非同源網頁的 CookieLocalStorageIndexedDB
    2.無法獲取非同源網頁的 DOM
    3.向非同源地址發送 AJAX 請求瀏覽器會拒絕響應

4.2 跨域

  根據CSRF攻擊的原理來講,攻擊者構造的惡意網站肯定是和要攻擊的網站是不同源的,所以這里要考慮的就是跨域的問題了,跨域的方法的話有兩種

4.2.1 JSONP跨域

  JSONP利用了scriptiframe等標簽的src等屬性,這些屬性是沒有同源策略限制的,從而實現了跨域請求。

  JSONP請求只能使用GET方式發送請求,也就是說如果被攻擊的Web應用采用的是GET方式進行操作的話,可以使用JSONP進行CSRF實現,但是在實際操作過程中需要考慮Cookie問題,因為需要Cookie中的字段進行身份驗證

  對於JSONP跨域能否攜帶Cookie的問題,理論上來說使用JSONP進行跨域是不能獲取Cookie的,對於瀏覽器是否會攜帶跨域請求中對方域的Cookie值,使用三種瀏覽器進行了測試

  Firefox:攜帶網站A的Cookie值發起GET請求
  Edge:沒有攜帶網站A的Cookie值發起GET請求
  Chrome:沒有攜帶網站A的Cookie值發起GET請求

  對於這個結果,和下面說到的CORSPOST跨域請求的結果是一樣的,應該都是因為SameSite設置導致的。

4.2.2 CORS跨域

  CORS將跨域請求分為兩種:簡單請求、非簡單請求
  滿足下圖中所有限制的請求即為簡單請求,其余的均為非簡單請求
  
  在滿足簡單請求的情況下,瀏覽器會自動攜帶Cookie發送跨域請求,也就是說進行身份校驗的會話憑證如果存儲在Cookie中,並且Web應用中的操作可以用簡單請求的方式完成,那么就一定存在CSRF漏洞。
  如果跨域請求為非簡單請求,則瀏覽器會先發送OPTIONS預檢請求,后端服務器在接收到OPTIONS請求后,會返回針對實際請求的要求,如果符合要求的話,則會繼續發送實際請求,如果不符合的話就不會發送實際請求了。
  下圖為實際發送OPTIONS請求,右側為后端服務器響應信息其中包含了對實際請求的要求

  Access-Control-Request-Method 服務器允許客戶端使用POST發起請求
  Access-Control-Request-Headers 服務器允許請求中攜帶Content-Type字段
  Access-Control-Allow-Origin 服務器允許哪些域發起請求(由於上圖中的請求是本地文件目錄的HTML發起,如下圖所示,所以返回的是null)

  Access-Control-Allow-Credentials 服務器是否允許使用憑證進行實際請求(例如攜帶Cookie)
  如果實際請求都滿足了以上的要求,那么瀏覽器就會發送實際的請求,但是此時的話並未攜帶Cookie值來完成CSRF攻擊,如果想要實際請求攜帶Cookie值的話,需要前后端滿足以下要求
  后端:
  ①Access-Control-Allow-Credentials字段設置為True
  ②Access-Control-Allow-Origin字段不能設置為*,必須為指定的域名,像上圖請求中的null也算是
  前端:
  ①請求要設置withCredentials = true

  在滿足上述前后端條件后,瀏覽器在完成預檢請求后會自動攜帶上Cookie字段,但是由於瀏覽器的內核特性不同,此時又出現了不同的情況
  Firefox攜帶網站A的Cookie值發起POST請求
  Edge沒有攜帶網站A的Cookie值發起POST請求
  Chrome沒有攜帶網站A的Cookie值發起POST請求
  測試發現不同的瀏覽器在同樣的前后端配置下,對於Cookie字段的攜帶產生了不同,於是又產生了以下內容:
  查過資料后發現,Edge和Chrome使用的是同一內核,對於Cookie中的SameSite屬性默認是Lax,在這種級別下,具有如下限制

  在這種情況下,想要實現POST跨域請求攜帶Cookie在Chrome瀏覽器中是不行的
  測試后發現在將Cookie中的某一字段SameSite屬性值手動設置為None(必須先設置字段的Secure屬性,否則無效)時

  發送POST跨域請求時,Chrome(Edge)瀏覽器會自動攜帶上Cookie中該字段值

  這個就說明了在進行非簡單請求時,在滿足上文所講的前后端設置時,是否會自動攜帶Cookie值在Chrome與Edge瀏覽器中取決於CookieSameSite字段的值,瀏覽器默認情況下設置為Lax,如果要手動設置為None的話,必須先設置Secure屬性,否則無效。

  本文僅從CSRF攻擊者視角出發,記錄一下實際滲透過程中遇到的CSRF漏洞利用問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM