一、概述
跨站點請求偽造(CSRF)是一種網絡攻擊,攻擊者試圖欺騙已登錄的用戶執行一些操作,如更改密碼、發佈內容等。其原理是攻擊者向用戶的瀏覽器發送一個看似正常的請求,但該請求會自動在用戶已登錄的網站上執行。因此,攻擊者可以利用該漏洞完成一些惡意操作。
根據攻擊方式的不同,CSRF攻擊可分為直接提交表單、圖片引用、腳本引用等幾種類型。在直接提交表單中,攻擊者會構建一個帶有CSRF攻擊代碼的表單,推送給用戶進行提交;在圖片引用方式中,攻擊者通過在惡意網站中插入一個引用了受害者瀏覽器會話的圖片,從而觸發惡意請求;腳本引用方式類似於圖片引用方式,但攻擊者通過惡意腳本替換受害者瀏覽器會話中的某些腳本等操作,從而實現跨站請求偽造攻擊。
防禦CSRF攻擊的主要手段是通過使用token,主流的編程語言和框架中也都提供了相應的方法,下面將詳細介紹如何實現。
二、基本防禦機制
CSRF攻擊的原理是攻擊者可以在用戶沒有意識到的情況下,利用用戶的身份(即瀏覽器已經登錄某個網站),向網站提交惡意請求。因此,防止CSRF攻擊的首要問題是如何讓網站能夠確定這是一個合法請求,而不是一個惡意的偽造請求。實際上,任何偽造的請求都無法獲得合法的token,因此正常情況下只有獲得了token的請求才會被處理。
三、常用實現方法
1. 請求可以包含一個根據服務器生成的隨機值
服務器會為每個重要操作生成一個唯一的隨機值,並將其添加到請求參數或請求體中。該隨機值可以是用戶會話ID、時間戳或其他任何足夠隨機的值。由於這個值是動態生成、唯一的,因此攻擊者無法預先構造CSRF請求。
<form action="/example/form" method="POST"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <!--其他表單控件--> <button type="submit">提交</button> </form>
2. 請求可以包含一個根據用戶會話信息生成的token
服務器會根據用戶的登錄狀態、IP地址、User-Agent字符串等信息動態生成一個加密簽名,然後將其添加到請求參數或請求體中。因此,每個token都只與一個特定用戶會話和特定的請求信息相關聯,極大地降低了攻擊者構造偽造請求的機會。
// 生成token function generateToken(req, res, next) { res.locals.csrfToken = req.csrfToken(); return next(); } // 提交表單 app.post('/formsubmit', generateToken, function (req, res) { // do something }); // 在表單中添加token <form method="POST" action="/formsubmit"> <input type="hidden" name="_csrf" value="{{ csrfToken }}"> <!--其他表單控件--> <button type="submit">提交</button> </form>
3. 請求可以包含一些被隱藏的字段
隱藏字段是指在表單中添加一些看不見的字段。攻擊者無法知道表單中的這些隱藏字段字段,因此無法構造偽造請求。
<form action="/example/form" method="POST"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <input type="text" name="username" value="" placeholder="請輸入用戶名"> <input type="password" name="password" value="" placeholder="請輸入密碼"> <!--其他表單控件--> <input type="hidden" name="foo" value="bar"> <input type="hidden" name="hello" value="world"> <button type="submit">提交</button> </form>
四、總結
跨站點請求偽造是一種常見且危險的攻擊方式,可以通過讓用戶執行惡意操作,對網站造成損失。為防止此類攻擊,我們可以採用一些比較常見的防禦方法,如包含一個隨機值、根據用戶會話信息生成一個token、包含一些看不見的字段等。雖然這些方法並不能絕對保證安全,但可以有效地減少攻擊的成功率。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/195847.html