How much do you want to send?
<input name="amount" />
To whom do you want to send it?
<input name="receiver" />
<input type="submit" value="Send" />
</form>

攻擊者在 BankApp 網(wǎng)站上以用戶名 @evil 開設(shè)賬戶。攻擊者撰寫了兩封單獨(dú)的釣魚郵件。第一封郵件假裝來自 BankApp,內(nèi)容是“警告!您的 BankApp 賬戶中檢測(cè)到潛在欺詐行為。”第二封郵件內(nèi)容是“您可能贏了 1,000 美元。”第一封郵件的目的是鼓勵(lì)用戶登錄 BankApp。第二封郵件包含以下標(biāo)記:HTML

<form method="post" action="https://bankapp.com/transfer">
<input name="amount" type="hidden" value="1000" />
<input name="recipient" type="hidden" value="@evil" />
</form>
<script>document.forms[0].submit();</script>

用戶甚至無需點(diǎn)擊任何內(nèi)容。第二封電子郵件提交表單并在用戶瀏覽器中呈現(xiàn)后立即執(zhí)行攻擊。攻擊者使用這兩封電子郵件向 100,000 名用戶發(fā)送垃圾郵件。其中一些用戶可能擁有 BankApp 帳戶。其中一些用戶會(huì)打開電子郵件,攻擊者從每封電子郵件中獲得 1000 美元。

服務(wù)器通過 HTTP 公開的任何狀態(tài)更改都可能受到偽造請(qǐng)求的影響。CSRF 攻擊可以更改密碼、發(fā)布社交媒體帖子、刪除帳戶、配置路由器以及許多其他危險(xiǎn)或破壞性的操作。

其他 HTTP 動(dòng)詞

BankApp 示例假設(shè)您必須通過 POST 表單來轉(zhuǎn)賬。并非所有 Web 端點(diǎn)都以這種方式編寫。如果 BankApp 網(wǎng)站允許使用 GET 請(qǐng)求轉(zhuǎn)賬,那么攻擊者的電子郵件可能只會(huì)這樣做:HTML

<IMG src="http://bankapp.com/transfer?amount=1000&recipient=@evil">

當(dāng)用戶在釣魚郵件中看到損壞的圖像標(biāo)簽時(shí),1000 美元就已經(jīng)沒了。

其他可改變狀態(tài)的 HTTP 動(dòng)詞也可能被利用。只有 PATCH、POST、PUT 和 DELETE應(yīng)允許更改狀態(tài),但如果 GET、HEAD 和 OPTIONS 也能進(jìn)行更改,則可能存在漏洞。

登錄CSRF

不要忽略登錄頁面上的 CSRF 警告。在登錄時(shí),即使用戶尚未通過身份驗(yàn)證,CSRF 攻擊仍然可能是一種威脅,盡管方法和風(fēng)險(xiǎn)與經(jīng)過身份驗(yàn)證的 CSRF 不同。在登錄 CSRF 攻擊中,攻擊者偽造請(qǐng)求,使用攻擊者的登錄憑據(jù)將用戶登錄到站點(diǎn)。受害者可能會(huì)認(rèn)為自己已經(jīng)登錄了自己的帳戶,從而留下攻擊者可以使用的信息。針對(duì) Google 和 Yahoo 的登錄 CSRF 攻擊可能會(huì)將受害者的搜索歷史記錄暴露給攻擊者。針對(duì) PayPal 等網(wǎng)站的登錄攻擊可能會(huì)誘使用戶提供信用卡信息,然后攻擊者可以登錄并使用這些信息。

主要防御

CSRF 攻擊依賴于能夠預(yù)測(cè)瀏覽器請(qǐng)求的內(nèi)容,從而偽造瀏覽器請(qǐng)求。針對(duì) CSRF 的最強(qiáng)大防御方法是使每個(gè)請(qǐng)求的內(nèi)容不可預(yù)測(cè)。基于令牌的防御依賴于隨機(jī)生成的值來做到這一點(diǎn)。 

同步器令牌

為了保護(hù)自己,服務(wù)器會(huì)向每個(gè)表單添加一個(gè)隱藏字段,為每個(gè)會(huì)話(或每個(gè)請(qǐng)求)分配一個(gè)不同的隨機(jī)值。服務(wù)器會(huì)確認(rèn)每個(gè)后續(xù)請(qǐng)求都具有此字段,并且其值與為會(huì)話分配的值相匹配。這稱為同步器令牌模式

加密令牌 

同步器令牌要求服務(wù)器在服務(wù)器端存儲(chǔ)隨機(jī)會(huì)話值。如果您不想在服務(wù)器上保留狀態(tài),則可以使用只有服務(wù)器上才知道的私鑰加密令牌值。加密值應(yīng)該是時(shí)間戳。通過確認(rèn)每個(gè)請(qǐng)求都包含隱藏字段、您可以解密字段值、解密值是時(shí)間戳以及時(shí)間戳是最近的(令牌未過期)來驗(yàn)證后續(xù)請(qǐng)求。

加密令牌是一種無狀態(tài)的 CSRF 防御措施,而雙重提交的 cookie 是另一種。在這種防御措施中,隨機(jī)令牌值保存在客戶端的 cookie 中。每個(gè)后續(xù)請(qǐng)求都必須在隱藏字段中包含相同的值。在每次請(qǐng)求中,服務(wù)器都會(huì)確認(rèn)隱藏字段是否存在,并且其值與 cookie 中的值匹配。 

為了確保這種防御的可靠性,您必須使用 HTTPS(無論如何都推薦使用)并確保您的子域也是安全的。 

AJAX 中的反 CSRF 令牌

AJAX 調(diào)用發(fā)生在基于 Cookie 的瀏覽器會(huì)話上下文中,也容易受到 CSRF 攻擊。AJAX 調(diào)用通常不會(huì)發(fā)布可以放置隱藏字段的表單。相反,它會(huì)在自定義 AJAX 標(biāo)頭中將 CSRF 令牌返回給服務(wù)器。JavaScript

var xhr = new XMLHttpRequest();
xhr.setRequestHeader(tokenname, tokenvalue);

tokenname和替換tokenvalue為生成 AJAX 請(qǐng)求的頁面中隱藏的隨機(jī)令牌字段的名稱和值。

使用自定義 HTTP 標(biāo)頭是一種防御措施,因?yàn)橹挥?JavaScript 可以創(chuàng)建自定義標(biāo)頭,并且瀏覽器的單源策略 (SOP) 會(huì)阻止跨站點(diǎn) JavaScript 調(diào)用。

基于框架的防御

許多編程框架(例如Spring、Django、.NET和AngularJS )都帶有基于令牌的 CSRF 防御的內(nèi)置實(shí)現(xiàn),這些實(shí)現(xiàn)可以生成加密性強(qiáng)的隨機(jī)令牌值并在每次請(qǐng)求時(shí)對(duì)其進(jìn)行驗(yàn)證。其他一些框架也有可用的附加組件:例如,適用于 Java 的OWASP CSRFGuard和適用于 PHP 的CSRFProtector 項(xiàng)目。正確實(shí)施基于令牌的防御可能很棘手,因此如果有人已經(jīng)為您制定了可靠的實(shí)現(xiàn),請(qǐng)不要自行構(gòu)建。

次要防御

基于令牌的防御效果最好,但縱深防御方法需要考慮額外措施來阻止可能的 CSRF 攻擊。

SameSite是一種 Cookie 屬性,類似于SecureHTTPOnlyExpires。SameSite 屬性讓網(wǎng)站設(shè)計(jì)者決定瀏覽器何時(shí)應(yīng)在跨站點(diǎn)請(qǐng)求中包含 Cookie。SameSite 的值可能是StrictLax,任何一個(gè)值都會(huì)阻止至少一些 CSRF 請(qǐng)求。這是一種有用的防御措施,但僅靠它還不夠,因?yàn)椴⒎撬袨g覽器都支持它(大多數(shù)瀏覽器都支持),而且它可以被繞過。

原產(chǎn)地驗(yàn)證

要確認(rèn)請(qǐng)求是否有效,請(qǐng)檢查 HTTP 標(biāo)頭以確認(rèn)來源和目標(biāo)值是否匹配。要確定請(qǐng)求的來源,請(qǐng)檢查 Origin 或 Referer 標(biāo)頭。將其與請(qǐng)求的目的地進(jìn)行比較:目標(biāo)來源。這些值無法偽造。只有瀏覽器才允許設(shè)置它們。

這種防御措施的優(yōu)點(diǎn)是,甚至在身份驗(yàn)證之前就可以識(shí)別跨站點(diǎn)請(qǐng)求。但是,一小部分網(wǎng)絡(luò)流量可能會(huì)出于正當(dāng)理由忽略請(qǐng)求來源,并且如果您的應(yīng)用程序位于代理后面,則確定目標(biāo)來源并非易事。  

重新認(rèn)證

有時(shí)(尤其是對(duì)于高風(fēng)險(xiǎn)交易)直接讓用戶參與是緩解 CSRF 和其他偽造請(qǐng)求的有效方法。要求用戶提供密碼或一次性令牌,或者通過 CAPTCHA,可以提供有效的保護(hù)。

實(shí)用建議

這些提示將幫助您避免防御 CSRF 時(shí)常見的問題。

防御被打破

如果未正確實(shí)施,基于令牌的防御措施可能會(huì)被攻破。為了確保隨機(jī)令牌值無法預(yù)測(cè),應(yīng)使用加密性強(qiáng)的隨機(jī)數(shù)生成器來創(chuàng)建令牌值。此外,請(qǐng)謹(jǐn)慎使用將生成的值與請(qǐng)求中收到的值進(jìn)行匹配的邏輯。驗(yàn)證邏輯中的錯(cuò)誤導(dǎo)致GlassDoor 遭受 CSRF 攻擊。在 GlassDoor 實(shí)施的某些情況下,檢查失敗會(huì)引發(fā)異常,但該異常僅被記錄下來,代碼會(huì)繼續(xù)執(zhí)行,就像驗(yàn)證成功一樣。

此外,跨站點(diǎn)腳本漏洞 (XSS)可以擊敗任何 CSRF 保護(hù)。如果攻擊者可以從用戶的瀏覽器中檢索令牌,即使是完美實(shí)施的基于令牌的 CSRF 防御也幾乎無法提供保護(hù)。可靠的 XSS 防御是 CSRF 防御的先決條件。

虛假辯護(hù)

這些措施有時(shí)被視為緩解措施,但卻不起作用:

多步驟交易

如果攻擊者仍然可以預(yù)測(cè)事務(wù)的每個(gè)步驟,那么將改變服務(wù)器狀態(tài)的操作分成多個(gè) HTTP 請(qǐng)求是沒有幫助的。

秘密cookie

創(chuàng)建攻擊者無法預(yù)測(cè)的秘密 cookie 毫無用處,因?yàn)闉g覽器總是在每次請(qǐng)求時(shí)發(fā)回所有相關(guān) cookie。攻擊者無需猜測(cè)秘密 cookie。

HTTPS

單純加密網(wǎng)絡(luò)流量并不能阻止 CSRF 攻擊。然而,對(duì)于其他一些緩解措施(例如雙重提交的 cookie)而言,這是必要的步驟,并且在所有情況下都可取,以使其他措施更加可靠。

URL 重寫

您可以在頁面加載時(shí)修改 URL,從而消除會(huì)話 cookie,但這樣做會(huì)在 URL 上暴露會(huì)話 ID,從而增加攻擊者捕獲會(huì)話 ID 的風(fēng)險(xiǎn)。

CSRF 與 XSS

跨站點(diǎn)腳本 (XSS) 漏洞與跨站點(diǎn)請(qǐng)求偽造 (CSRF) 漏洞具有一些共同的特征。兩者都旨在在受害者的合法網(wǎng)絡(luò)會(huì)話環(huán)境中運(yùn)行惡意代碼。然而,XSS 旨在將惡意代碼直接注入易受攻擊的頁面,而 CSRF 通常依賴于社交工程(例如網(wǎng)絡(luò)釣魚電子郵件)將惡意代碼放入受害者瀏覽器中的不相關(guān)頁面。XSS 依賴于目標(biāo)網(wǎng)站中的缺陷,這些缺陷允許注入惡意代碼,服務(wù)器將把這些惡意代碼作為其自身網(wǎng)頁的一部分傳遞給受害者。

差異很大。惡意 XSS 腳本可以直接訪問目標(biāo)站點(diǎn)中的頁面。事實(shí)上,XSS 漏洞可以向攻擊者暴露頁面上的所有內(nèi)容,包括任何反 CSRF 令牌值。即使是完美的防御措施也幾乎無法為易受 XSS 攻擊的站點(diǎn)提供 CSRF 保護(hù)。

測(cè)試 CSRF

漏洞測(cè)試是任何安全程序的基本組成部分。掃描工具能夠發(fā)現(xiàn)許多 CSRF(和 XSS)漏洞。鑒于此類漏洞的潛在嚴(yán)重性,任何擁有 Web 應(yīng)用程序的人都應(yīng)系統(tǒng)地測(cè)試它們 – 最好將自動(dòng)掃描作為 CI/CD 管道的一部分。漏洞測(cè)試需要遵守最佳實(shí)踐和標(biāo)準(zhǔn),例如 NIST SP 800-53 和 ISO 27001。高風(fēng)險(xiǎn)應(yīng)用程序還應(yīng)在其安全程序中包括手動(dòng)滲透測(cè)試。

文章來源:What is Cross-Site Request Forgery (CSRF)?

上一篇:

.NET 損壞認(rèn)證指南:示例和預(yù)防

下一篇:

Vue XML 外部 實(shí)體(XXE)指南:示例和預(yù)防
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊(cè)

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門場(chǎng)景實(shí)測(cè),選對(duì)API

#AI文本生成大模型API

對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對(duì)比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)