在Web上使用Cross-Site Request Forgery進行勞做以後,咱們終於有了一個合適的解決方案。 沒有網站全部者的技術負擔,沒有困難的實施,部署簡單,它是Same-Site Cookies。html
跨站請求僞造,也稱爲CSRF或XSRF,基本上永遠存在。 它源於網站必須向另外一個站點發出請求的簡單功能。 假設我在此頁面中嵌入瞭如下表單。ios
<form action="https://your-bank.com/transfer" method="POST" id="stealMoney">
<input type="hidden" name="to" value="Scott Helme">
<input type="hidden" name="account" value="14278935">
<input type="hidden" name="amount" value="£1,000">
複製代碼
您的瀏覽器加載此頁面,結果是上面的表單,而後我在頁面上使用一個簡單的JS提交。web
document.getElementById("stealMoney").submit();
複製代碼
這就是CSRF的名稱來源。 我正在僞造一個跨站點發送請求到您的銀行。 這裏真正的問題不是我發送了請求,而是您的瀏覽器會發送您的cookie。 該請求將把您當前持有的所有權限一併發送,這意味着若是您已登陸到您的銀行,您就需向我捐贈1,000英鎊, 謝謝! 若是您沒有登陸,那麼請求將是無害的,由於您沒法在未登陸的狀況下轉帳。目前,您的銀行能夠經過幾種方式來緩解這些CSRF攻擊。跨域
我不會詳細說明這些,由於網上有大量有關此主題的信息,但我想快速介紹它們以顯示實施它們的技術要求。瀏覽器
在服務端收到請求時,會向咱們提供Origin頭和Referer頭來講明請求的來源。 您能夠檢查其中的一個或兩個值,以查看請求是否源自不一樣的來源。 若是是跨域請求,則只需將其丟棄便可。 Origin和Referer頭確實獲得了一些防止瀏覽器的保護,以防止被篡改,但它們可能並不老是存在。安全
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
accept-encoding: gzip, deflate, br
cache-control: max-age=0
content-length: 166
content-type: application/x-www-form-urlencoded
dnt: 1
origin: https://report-uri.io
referer: https://report-uri.io/login
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
複製代碼
您可使用兩種不一樣的方式使用Anti-CSRF令牌,但原則保持不變。當訪問者請求頁面時,如上例中的轉移金額頁面,您將隨機令牌嵌入到表單中。當真正的用戶提交此表單時,將返回隨機令牌,您能夠檢查它是否與您在表單中發出的令牌相匹配。在CSRF攻擊情形中,攻擊者永遠沒法得到此值,即便他們請求頁面也沒法獲取此值,由於同源策略(SOP)會阻止攻擊者讀取包含令牌的響應。此方法運行良好,但要求站點跟蹤Anti-CSRF令牌的發佈和返回。相似的方法是將令牌嵌入到表單中,並向瀏覽器發出包含相同值的cookie。當真正的用戶提交他們的表單時,cookie中的值和表單將在網站收到時匹配。當攻擊者發送僞造請求時,瀏覽器將不會設置CSRF cookie,測試將失敗。bash
<form action="https://report-uri.io/login/auth" method="POST">
<input type="hidden" name="csrf_token" value="d82c90fc4a14b01224gde6ddebc23bf0">
<input type="email" id="email" name="email">
<input type="password" id="password" name="password">
<button type="submit" class="btn btn-primary">Login</button>
</form>
複製代碼
上述方法長期爲咱們提供了至關強大的CSRF保護。 檢查Origin和Referer頭不是100%可靠,而且大多數站點採用Anti-CSRF令牌方法的一些變體。 問題是,這些都對網站提出了某種要求來實施和維護解決方案。 它們可能不是世界上技術最複雜的東西,但咱們仍然在構建一個解決方案,圍繞瀏覽器作一些咱們不但願它作的事情。 相反,爲何咱們不告訴瀏覽器中止作咱們不但願它作的事情?...如今咱們能夠!cookie
您可能已經在我最近的一篇名爲Tough Cookies的博客中看到過Same-Site Cookies,但我將在這裏經過一些例子更深刻地介紹它。 從本質上講,Same-Site Cookies徹底有效地抵消了CSRF攻擊。Dead. Finito. Adios! 捕獲咱們在網絡上真正須要的本質以贏得安全戰,Same-Site Cookies易於部署,很是簡單。 拿你現有的cookie:網絡
Set-Cookie: sess=abc123; path=/
複製代碼
只需添加SameSite屬性便可。併發
Set-Cookie: sess=abc123; path=/; SameSite=lax
複製代碼
你完成了。 說真的,就是這樣! 在cookie上啓用此屬性將指示瀏覽器爲此cookie提供某些保護。 有兩種模式能夠在Strict或Lax中啓用此保護,具體取決於您想要得到的嚴重程度。
SameSite=Strict
SameSite=Lax
複製代碼
將SameSite保護設置爲嚴格模式顯然是首選,但咱們有兩個選擇的緣由是並不是全部站點都相同,也沒有相同的要求。當在嚴格模式下操做時,瀏覽器根本不會在任何跨源請求上發送cookie,所以CSRF徹底死在水中。您可能遇到的惟一問題是它也不會在頂級導航上發送cookie(更改地址欄中的URL)。若是我提供了https://facebook.com的連接,而且Facebook將SameSite cookie設置爲嚴格模式,當您單擊連接到打開Facebook時,您將沒法登陸。不管您是否已登陸,在新標籤頁中打開它,不管您作什麼,從該連接訪問時都不會登陸到Facebook。這對用戶來講可能有點煩人和/或意外,但確實提供了使人難以置信的強大保護。 Facebook在這裏須要作的是相似於亞馬遜作的,他們有2個cookie。一種是一種「基本」cookie,能夠將您識別爲用戶,並容許您擁有登陸體驗,但若是您想作一些敏感的事情,好比購買或更改賬戶中的內容,則須要第二個cookie, 「真正的」cookie,可讓你作重要的事情。在這種狀況下,第一個cookie不會設置SameSite屬性,由於它是一個「方便」的cookie,它實際上不容許你作任何敏感的事情,若是攻擊者能夠用它作出跨域請求,則沒有任何反應。可是,第二個cookie(敏感cookie)將設置SameSite屬性,攻擊者就不能濫用權限到跨源請求中。這是用戶和安全性的理想解決方案。但這並不老是可行的,由於咱們但願SameSite cookie易於部署,這裏還有第二種選擇。
將SameSite保護設置爲Lax模式能夠修復上述用戶點擊連接的嚴格模式中提到的問題,若是他們已經登陸,則不會在目標站點上登陸。在Lax模式下,只有一個例外容許cookie附加到使用安全HTTP方法的頂級導航。 「安全」HTTP方法在RFC 7321第4.2.1節中定義爲GET,HEAD,OPTIONS和TRACE,咱們對此處的GET方法感興趣。 這意味着,當用戶單擊連接時,咱們對https://facebook.com的頂級導航如今在瀏覽器發出請求時附加了SameSite標記的cookie,從而保持了預期的用戶體驗。 咱們還徹底受到基於POST的CSRF攻擊的保護。 回到頂部的示例,此攻擊仍然沒法在Lax模式下工做。
<form action="https://your-bank.com/transfer" method="POST" id="stealMoney">
<input type="hidden" name="to" value="Scott Helme">
<input type="hidden" name="account" value="14278935">
<input type="hidden" name="amount" value="£1,000">
複製代碼
因爲POST方法不被認爲是安全的,所以瀏覽器不會在請求中附加cookie。 攻擊者固然能夠自由地將方法更改成「安全」方法併發出相同的請求。
<form action="https://your-bank.com/transfer" method="GET" id="stealMoney">
<input type="hidden" name="to" value="Scott Helme">
<input type="hidden" name="account" value="14278935">
<input type="hidden" name="amount" value="£1,000">
複製代碼
只要咱們不接受GET請求代替POST請求,那麼這種攻擊是不可能的,可是在Lax模式下操做時須要注意。 此外,若是攻擊者能夠觸發頂級導航或彈出新窗口,他們還可使瀏覽器發出附加了cookie的GET請求。 這是在Lax模式下運營的權衡,咱們保持用戶體驗不變,但也有較小的風險接受付款。
此博客旨在使用SameSite Cookie緩解CSRF,但正如您可能已經猜到的那樣,此機制也有其餘用途。 規範中列出的第一個是跨站點腳本包含(XSSI),瀏覽器在此處請求資源,例如腳本,該腳本將根據用戶是否通過身份驗證而更改。 在跨站點請求方案中,攻擊者不能濫用SameSite Cookie的環境權限來產生不一樣的響應。 此處詳細介紹了一些有趣的計時攻擊,那能夠有效緩解濫用狀況。
另外一個不詳細的有趣用途是防止在BEAST式壓縮攻擊(CRIME,BREACH,HEIST,TIME)中泄露會話cookie的價值。 這是很是高級別的,但基本狀況是MiTM能夠強制瀏覽器經過他們喜歡的任何機制發出跨源請求並監視它們。 經過濫用請求有效負載大小的變化,攻擊者能夠經過改變瀏覽器發出的請求並在線路上觀察它們的大小,一次一個字節地猜想會話ID值。 使用SameSite Cookies,瀏覽器不會在此類請求中包含cookie,所以攻擊者沒法猜想其值。
隨着瀏覽器中大多數新的安全功能,您能夠指望Firefox或Chrome的領導這項功能,這裏的狀況也不例外。 自v51以來,Chrome已經支持Same-Site Cookies,這意味着Android上的Opera,Android瀏覽器和Chrome也有支持。 您能夠在caniuse.com上查看列出當前支持的詳細信息,Firefox也有一個bug,能夠添加支持。 儘管支持還沒有普及,但咱們仍應將SameSite屬性添加到cookie中。 理解它的瀏覽器將尊重設置並提供cookie額外的保護,而那些不理解它的人將徹底忽略它並繼續前行。 這裏沒有什麼可失去的,它造成了一個很是好的防護深度方法。 咱們能夠考慮刪除傳統的反CSRF機制,可是在這些機制之上添加SameSite會給咱們帶來難以置信的強大防護。
原文:scotthelme.co.uk/csrf-is-dea… 原文發佈日期:2017年2月20日 做者:Scott Helme 譯者:帕奇式
翻譯及轉載得到做者許可:
![]()