跨站請求偽造
跨網站請求偽造是一種漏洞,其中惡意頁面使您的瀏覽器向您登入的網站提交請求 - 使用您的憑證,執行未經您授權的操作。 SameSite cookie 已經關閉了大部分歷史攻擊面,但只要 cookie 驗證狀態變更操作,底層類別仍然很重要。
完整的文章正文以英文提供如下。
跨站點請求偽造(CSRF,有時稱為 XSRF 或“sea-surf”) 利用網站對使用者瀏覽器的信任。攻擊者看不到您的 cookie,但瀏覽器會在每次要求時自動將它們傳送到它們所屬的來源。如果攻擊者可以觸發您的瀏覽器向您登入的網站發出請求,則該網站會看到經過驗證的請求 - 即使攻擊者發動了該請求。
經典攻擊
想像一家透過簡單的 GET 請求處理轉帳的銀行:https://bank.example/transfer?to=Bob&amount=1000。您已登入銀行。攻擊者透過電子郵件向您發送一個連結或託管一個帶有指向 的映像標籤的頁面 https://bank.example/transfer?to=Attacker&amount=10000。您的瀏覽器載入圖像;銀行看到來自您會話的經過身份驗證的請求;
這個具體例子大多是歷史性的——銀行不再透過 GET 處理轉帳——但模式是通用的。任何僅透過會話 cookie 進行身份驗證的狀態變更要求都可能存在 CSRF 漏洞。
什麼使 CSRF 成為可能
三個基礎:
- Cookie 會自動發送。 瀏覽器不要求許可; cookies 屬於源頭,並且隨每個請求一起傳送到該來源頭,無論請求是在哪裡發起的。
- HTML 可以觸發跨來源請求。 圖像標籤、表單提交、腳本標籤和各種其他元素都可以針對任何 URL。
- 伺服器在不驗證意圖的情況下對請求進行操作。 伺服器看到經過驗證的請求;如果沒有明確的 CSRF 保護,它會處理該操作。
標準防禦
- CSRF 令牌(同步器令牌)。 伺服器包含每種形式的隨機令牌。提交的內容必須包含令牌。攻擊者的惡意頁面無法讀取token(同源策略),因此偽造請求失敗。現代 Web 框架會自動產生和驗證令牌。
- SameSite cookies。 標記為 SameSite=Lax(自 2020 年起在現代瀏覽器中預設)的 Cookie 不會在除頂級導航之外的跨站點請求上發送。 SameSite=Strict 甚至更嚴格。這是過去五年中降低 CSRF 風險的最大單一變化。
- Origin 和 Referer 標頭驗證。 伺服器可以檢查 Origin 標頭是否與預期來源相符。跨站請求有不同的Origin,允許拒絕。
- 雙提交cookie。 伺服器在cookie和單獨的請求參數中都設定一個值;驗證者檢查它們是否符合。無需伺服器端會話狀態即可運作。
- 對敏感操作進行重新驗證。 對高價值操作進行密碼確認、MFA 質詢或逐步驗證。同時擊敗 CSRF 和其他幾種攻擊類別。
SameSite cookies 革命
2020 年之前,每個跨網站請求都攜帶目標網站的 cookie — 包括來自惡意頁面的狀態變更請求。 SameSite=Lax 使跨網站 cookie 成為例外而不是規則。主要瀏覽器在 2020-2021 年預設為 Lax,影響是巨大的:大多數偶然的 CSRF 漏洞一夜之間變得不可利用。
問題:SameSite=Lax 仍然允許頂級導覽上的 cookie(全頁面重新導向)。透過點擊連結觸發的狀態改變操作仍然可以攜帶cookie。防禦很好,但不完整。
SameSite=Strict 完全阻止了這種情況。權衡:它破壞了依賴跨網站導航(單一登入、OAuth 後重定向)的登入流程。大多數主要網站預設使用 Lax,僅對最敏感的 cookie 使用 Strict。
CSRF 和 API
現代 API 通常透過授權標頭(承載令牌)而不是 cookie 進行身份驗證。 CSRF 不適用,因為瀏覽器不會自動在跨來源請求中包含任意標頭。 CSRF 問題很大程度上屬於 cookie 身份驗證系統。
但是,混合某些流的 cookie 和其他流的令牌的 API 可能具有微妙的 CSRF 表面。一致地使用其中之一。
CSRF 和 CORS
CORS(跨來源資源共用)定義瀏覽器何時允許 JavaScript 讀取跨來源請求。 CSRF是關於請求是否為sent,帶有cookie。它們相關但又不同:
- CSRF 防止惡意頁面引起請求
- CORS 防止惡意頁面讀取回應
CSRF 攻擊不需要讀取回應 - 它只需要伺服器執行操作。瀏覽器盡職盡責地發出請求並獲得回應;惡意頁面可能看不到它,但損害已經造成。 CORS 無法修復 CSRF.
著名的 CSRF 事件
- Netflix 隊列操縱 (2006). 研究人員發現,精心設計的 IMG 標籤可以在無需您參與的情況下將影片新增至您的 Netflix 佇列。該修復是第一個廣泛使用的CSRF令牌。
- YouTube帳號接管變體在2000年代後期。
- GitHub儲存庫刪除透過CSRF在2012年(很快修復)。
- 許多WordPress插件CSRF每年都會報告 漏洞;插件生態系統仍在大規模生產它們。
對於 2026 年的開發人員
- 使用具有內建 CSRF 保護的框架(Django、Rails、Spring、Laravel 都有)
- 在每個狀態變更請求上驗證在每個狀態變更法上驗證嚴格要求
- 對於 API,盡可能使用承載令牌而不是 Cookie
- 需要對高風險操作進行重新身份驗證
- 不要單獨依賴 Origin/Referer — 某些客戶端省略這些標頭
常見問題
- SameSite cookies 殺死了 CSRF 嗎?
- 大幅減少但並未消除。 SameSite=Lax(現代預設設定)允許在頂級導覽上使用跨網站 cookie。 SameSite=Strict 也可以防止這種情況,但會破壞合法的流量。 CSRF 代幣仍然是建議的防禦方式; SameSite 是一個補充層。
- CSRF 與 XSS 有何不同?
- XSS 將惡意程式碼注入受信任的站點,並以其權限執行。 CSRF 欺騙瀏覽器向受信任的網站發送請求,而不注入任何內容。 XSS 可以做 CSRF 能做的一切,甚至更多。它們是不同的攻擊機制。
- 我可以在自己的應用程式中測試 CSRF 嗎?
- 是的。嘗試提交刪除或更改令牌的表單;如果操作成功,您就擁有了 CSRF。在 Chrome 中使用 SameSite 強制進行測試;一些遺留框架具有未經實際驗證的 CSRF 令牌。手動審核非常簡單。
- 單頁應用需要CSRF保護嗎?
- 如果他們透過 cookie 進行身份驗證,是的。如果它們透過儲存在用戶端 (localStorage) 的非記名令牌進行身份驗證,則它們不易受到 CSRF 攻擊,但更容易受到 XSS 攻擊。兩個攻擊面都很重要;選擇您的身份驗證機制時要考慮兩者。
- CSRF 還在 OWASP 前 10 名嗎?
- 由於廣泛的框架級緩解措施和 SameSite cookie 預設值,它在 2021 年跌出了前 10 名。它仍然位於 OWASP 重大漏洞清單中;流行率下降了,但根本機制卻沒有下降。