切換語言為:簡體

通俗講一下CSRF攻擊

  • 爱糖宝
  • 2024-10-20
  • 2034
  • 0
  • 0

什麼是CSRF??

大家都聽過一句話叫“陌生的連結不要亂點”,原因就是釣魚網站的連結點開之後會造成CSRF攻擊。 CSRF譯為“跨站請求偽造”。簡單來說就是釣魚網站連結盜用了使用者的資訊(例如銀行網站頒發給使用者的token),執行了非使用者本意的操作(如轉賬交易)。

舉個例子

a使用者是某bank的使用者,在a登入bank.com時,bank.com會設定響應頭

Set-Cookie: token=abcdefg;

以後a使用者再訪問bank.com時會在請求頭中自動攜帶該cookie。

這時a使用者點選了danger.com時,danger.com會響應一個頁面,頁面中可能包含以下元素

<img src="https://bank.com/pay?payuser=dangeruser&money=10000" />

雖然danger.com拿不到a使用者在bank.com的cookie,但<img/>元素會向bank.com傳送請求,傳送請求就會攜帶cookie,而cookie中就包含使用者資訊(token),bank.com收到該請求,並驗證該使用者的token正確後,就會正常響應這個轉賬請求

<img/>元素與ajax不同,不受到瀏覽器同源策略中跨域的影響,可以正常傳送請求

常見的CSRF攻擊防範手段

1.直接不使用cookie

不使用cookie行不行呢?肯定是可以,畢竟有localstorage嘛。但cookie的相容性比localstorage要好,很多大廠的網站依舊使用cookie。

並且cookie對ssr的場景較友好,因為服務端渲染中,構建頁面的地方在服務端。假設使用者已經登陸過a.com。那麼下次輸入url請求a.com時,自動攜帶cookie。a.com就能自動推薦該使用者喜歡的內容。而假設沒有使用cookie而是localstorage。使用者在請求a.com時,就不能自動攜帶localstorage中的使用者資訊,因為localstorage需要js來手動加到請求中。

2.使用SameSite

SameSite是近幾年新出的一個屬性,用於增強cookie的安全性,但相容性較差,用法如下。

Set-Cookie: token=abcdefg;SameSite=Lax;

SameSite有兩個取值

SameSite=Strict

這種設定下,瀏覽器只會在當前請求源和 cookie 設定的源相同時才傳送 cookie。即使使用者從別的站點點選了一個連結,跳轉到當前站點,cookie 也不會被髮送。

還是剛纔那個例子,由於使用者登入bank.com後bank.com響應的Set-Cookie中SameSite=Strict

Set-Cookie: token=abcdefg;SameSite=Strict;

即使danger.com中嵌入了

<img src="https://bank.com/pay?payuser=dangeruser&money=10000" />

由於 SameSite=Strict 的存在,danger.com與bank.com的源不一樣,cookie則不會攜帶過去。即使bank.com能收到轉賬請求,但由於沒有cookie中的token,則驗證失敗,拒絕轉賬請求。

它提供了最高階別的安全性,但也會影響到一些正當的跨站點請求。

SameSite=Lax

Lax譯為寬鬆的、不嚴格的。 當 SameSite=Lax 時,允許某些跨站點請求帶上 cookie,比如從其他站點透過 GET 請求連結到當前站點時會攜帶 cookie。然而,POST 請求、iframe、AJAX 等不會攜帶 cookie。

一般的轉賬請求都是使用POST<img/>元素髮送的請求是GET,則無法請求成功。

3.使用CSRF token

當用戶想轉賬時,在請求bank.com的轉賬頁面時,bank.com會響應一個CSRF token

Set-Cookie: CSRFtoken=qwerty;

這個CSRF token是一次性的,當用戶點選轉賬時,將CSRF token也一併提交。

bank.com比之前多加了一道驗證。不僅驗證a使用者的token,還要驗證使用者的CSRF token。驗證透過後,轉賬成功,CSRF token也自動失效。

總結

每種策略都有一定的隱患,因此在實際開發中,通常建議多種防護手段相結合,比如使用 CSRF Token 配合 SameSite Cookie 屬性,以達到更強的安全性。

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.