CSRF 代表 跨站請求偽造。
CSRF 是 XSS 和 SQL 注入之後,最常見的網路攻擊之一。
簡單來說,CSRF 攻擊是讓訪問我們網站的人執行他們原本不想執行的操作。
一次成功的 CSRF 攻擊可能導致資料損失、未經授權的活動和資料損失,所以絕對是一個需要仔細研究的議題。
使用 HTTP GET 請求進行 CSRF 攻擊
讓我們從最簡單的 CSRF 情境開始。
你有一個汽車的資料庫。
透過 GET 請求 /api/delete?id=1
將會刪除 id 為 1 的汽車。
我訪問了另一個網站,該網站有一個圖片,圖片的來源 URL 是 https://yoursite.com/api/delete?id=1
類似這樣:
<img src="<https://yoursite.com/api/delete?id=1>" />
瀏覽器連接到該 URL 嘗試取得圖片。請求被執行,請求被提交,並且汽車被刪除。
如果應用程式需要驗證,如果你沒有從網站登出,則請求將會成功執行,因為會話仍然有效。
由於 Web 的運作方式,任何對於一個網域的請求都會自動附上會話 cookies(除非使用嚴格的 SameSite cookies),所以伺服器認為該請求是合法的。
你可以輕易地透過 Node.js 應用程式來嘗試重現這個情境。
解決這個問題的簡單方法是避免使用 GET 請求來進行任何資料操作,因為像這類的請求只需使用 GET 方法即可。改用 POST。
這不僅限於圖片,像是 iframes
也有相同的問題。
透過表單進行 CSRF 攻擊
你的應用程式中的任何表單都應該被 CSRF 保護。
Express 是一個用於 Express 的 CSRF 保護中介軟體。
每當你渲染一個表單時,你可以在表單中嵌入一個 CSRF token,並在接收到表單資料時驗證該 token。
對於單頁應用程式 (SPA) 來說,你可以使用一個端點來檢索此 token,並將其存儲到一個 cookie 中。
使用 SameSite Cookies 解決 CSRF
對於 cookie 而言,SameSite
屬性(可惜並未受到所有瀏覽器的支援)允許伺服器要求在跨域請求(例如圖片來源連結或 iframe 請求)中不傳遞 cookie,在僅有將 cookie 網域視為起源的資源上才傳遞 cookie,這將有助於降低 CSRF(跨站請求偽造)攻擊的風險。
這解決了大部分常見的 CSRF 問題。
現代瀏覽器預設將 cookie 自動設置為 SameSite=Lax
,這是在完全保護但阻擋一些圖片來源 URL 的請求之間取得平衡。
這允許使用者使用連結訪問網站,並保持他們的會話不中斷。
最嚴格的效果是使用 SameSite=Strict
,在從連結來到網站時該會話 cookie 不被識別。
我想像這對銀行來說是理想的情況。
使用一次性 token 或密碼解決 CSRF
談到銀行,許多銀行實施了一次性 token,即使是最簡單的操作也需要使用。
每當我想要匯款時,我必須拿出手機上的一次性 token 應用程式,透過臉部辨識進行驗證,然後將看到的數字複製到電腦上。
無論如何,即使是最晚的星期五部署都無法觸發相似網站的 CSRF 問題。
我注意到 GitHub 要求我的密碼更改設定,例如。
還有我用於電子郵件的 Fastmail 服務。
它們在執行上都至關重要,我們希望它們實施所有正確的對策。我們應該從中獲得靈感。