CSRF 介紹

CSRF 是什麼?

CSRF(Cross Site Request Forgery) 為跨站請求偽造。簡單講,被害者點擊了攻擊者提供的網頁後,網頁裡面埋了一些惡意的程式碼,
目的為假冒被害者的身份去對目標網站發出請求,請求可以是刪除資源或是轉帳等動作,通常是發生在目標網站使用 cookie 做身份認證的情況,利用 cookie 會隨著請求一起被送出的特性來達到攻擊的效果。

解法

  • SameSite cookie
  • Referer
  • CSRF Token
  • Double Submit Cookie

此做法是在 server 設定 cookie 時,加上 SameSite 設定,表示只有在同網站的情況下瀏覽器才隨請求發送 cookie 給 server。

1
Set-Cookie: session_id=zxcvbn19rtyu89; SameSite

但是有幾個缺點:

  • 不是所有瀏覽器版本都支援,使用前須先確認
  • 對於如果是從 Google 搜尋頁或是別人分享的連結來點擊進入網頁,會無法保持登入的效果,對使用者體驗不利

解法有兩種:

  • 設定兩種類型的 cookie
    把 cookie 分成兩種,一種是維持登入狀態用的 cookie,不設為 SameSite,讓點擊連結進入網站時仍然對 server 發送 cookie,讓使用者保持登入狀態;
    另一種是敏感操作時候用的 cookie,要設為 SameSite,避免偽造請求的攻擊。
1
2
Set-Cookie: session_id=zxcvbn19rtyu89 
Set-Cookie: name=secret; SameSite
  • 使用 Lax & Strict
    先簡單介紹一下 SameSite 的幾種設定:Strict、Lax、None。

Strict:要求最嚴格,只有 same site 的情況下,才會送出 cookie。
Lax:比 Strict 寬鬆一點,除了 GET 請求以外,不發送 cookie 到第三方。
None: 允許所有網站對 cookie 的存取。

所以我們可以使用 SameSite=Lax,讓 POST、PUT、DELETE 請求在跨域的情況下不發送 cookie,避免 CSRF 攻擊,又可以在透過點擊連結進入網站時保持登入狀態。

1
Set-Cookie: session_id=zxcvbn19rtyu89; SameSite=Lax

詳細的細節可以看看 RFC 對於 SameSite cookie 的規範

Referer

檢查 request header 的 referer,看 domian 是否合法來避掉偽造請求。
但是有風險:

  • 瀏覽器可能不支援
  • 使用者也可以關閉 referer 的傳送,這樣就會遺失真正的請求

如果對 referer 不太暸解可以看HTTP Referer 教程

CSRF Token

最常見的解法,許多框架也直接支援這個做法。

手法為在 session 和 form 裡面直接埋入一個 CSRF token,然後 server 收到請求後比對是否相同,偽造請求因為不會有這個 CSRF token,所以可以避免造假攻擊,但是缺點為 session 也要存一份,無法 stateless。

Double Submit Cookie 是 CSRF token 的變形,一樣是要產出一組 CSRF token,但是改存在 cookie 裡面,作法也分兩種:

  • 由 server 產生 token:
    server 產生 token 後,不存在 session,改存在 cookie 裡,然後 form 也一樣埋入這個 token,等 server 收到請求後一樣把兩者做比對,因為偽造攻擊的網頁裡面的 form ㄧ定沒有這個 token,所以比對後會發現是非法的請求。

  • 由 client 產生 token:
    client 產生 token 後,同時設定在 cookie 裡和 header 上,等 server 收到請求後一樣把兩者做比對,概念是因為攻擊者無法偽造出目標網站的 cookie 。

Reference

讓我們來談談 CSRF

wiki:跨站請求偽造