題:
為什麼要針對每個表單請求刷新CSRF令牌?
Philipp Gayret
2012-10-20 16:15:45 UTC
view on stackexchange narkive permalink

在許多教程和指南中,我看到應該根據請求刷新CSRF令牌。我的問題是為什麼我必須這樣做?在每個會話中使用單個CSRF令牌是否比在每個請求中生成一個並跟踪所請求的令牌要容易得多?

在每個請求的基礎上生成令牌似乎並不能提高安全性。每個會話令牌已經可以了。唯一的論據似乎是XSS保護,但這並不適用,因為當您遇到XSS漏洞時,腳本仍然可以讀出新令牌。

每個請求生成新令牌有什麼好處?

八 答案:
bobince
2012-10-22 01:31:40 UTC
view on stackexchange narkive permalink

由於已經討論的原因,沒有必要為每個請求生成新的令牌。它帶來了幾乎為零的安全優勢,並且在可用性方面使您付出了代價:一次只能使用一個令牌,用戶將無法正常瀏覽Web應用程序。例如,如果他們單擊“後退”按鈕並使用新值提交表單,則提交將失敗,並可能向他們發送一些敵對的錯誤消息。如果他們嘗試在第二個選項卡中打開資源,他們會發現會話在一個或兩個選項卡中隨機中斷。通常不值得犧牲應用程序的可用性來滿足這一無意義的要求。

在一個地方,值得 發行一個新的CSRF令牌:一個會話。也就是說,主要是在登錄時。這是為了防止會話固定攻擊導致CSRF攻擊的可能性。

例如:攻擊者訪問站點並生成一個新會話。他們獲取會話ID並將其註入受害者的瀏覽器中(例如,通過從易受攻擊的鄰居域編寫cookie或使用其他漏洞(如jsessionid URL)),還將CSRF令牌注入受害者的瀏覽器中的一種形式。他們等待受害者使用該表單登錄,然後使用另一個表單發布讓受害者使用仍然有效的CSRF令牌執行操作。

為防止這種情況,請使CSRF令牌無效並在您已經在對會話ID進行相同操作的地方(例如登錄名)發布一個新的密碼,以防止會話固定攻擊。

既然BREACH攻擊已經成為現實,那麼這個建議仍然有效嗎?
BREACH攻擊應該在另一層解決(通過禁用應用程序數據壓縮和TLS壓縮),所以答案是:您不必擔心BREACH攻擊,除非您設置TLS或HTTP服務器
D.W.
2012-10-21 04:55:57 UTC
view on stackexchange narkive permalink

概述。標準建議是使用唯一的CSRF令牌,該令牌對於每個請求都是唯一的。為什麼?因為與每個會話令牌相比,每個請求令牌對某些類型的實現錯誤更具彈性。這使得每個請求令牌可以說是新Web應用程序開發的最佳選擇。同樣,沒有安全審核員會麻煩您使用按請求的CSRF令牌。

如果您是Web應用程序開發人員,這就是您所需要知道的,您可以在這裡停止閱讀。但是,如果您是安全專家,想知道此建議背後的詳細原理,或者想知道如果您確實使用按會話的令牌會帶來多大的風險,請繼續閱讀...。


深入研究。事實是,如果您的網站中沒有其他漏洞,則每個會話一個CSRF令牌就可以了。沒有理由為什麼您必須必須為每個請求生成一個新的CSRF令牌。

事實也證明了這一點,您還會找到著名的安全專家,他們說另一種合理的做法防禦CSRF的方法是使用cookie兩次提交:換句話說,您使用一些客戶端Javascript計算會話cookie的哈希並將其添加到每個POST請求中,並將哈希視為CSRF令牌。您可以看到,這實質上是即時生成的CSRF令牌與整個會話相同。

當然,我知道為什麼有人建議為每個請求生成一個新的CSRF令牌的爭論。他們在想,如果您的網站上也存在XSS漏洞,那麼如果您在每個會話中使用單個CSRF令牌,則使用XSS即可輕鬆恢復CSRF令牌,而如果您根據每個請求生成一個新的CSRF令牌,則會很容易將需要更多的工作來恢復CSRF令牌。就我個人而言,我認為這不是一個令人信服的論點。如果您的站點上存在XSS漏洞,即使您為每個請求生成一個新的CSRF令牌,也仍然可以恢復CSRF令牌,它只需要多加幾行惡意Javascript。無論哪種方式,如果您的站點上都有XSS漏洞,並且您面對的是嚴重的,知識淵博的攻擊者,那麼無論您如何生成CSRF令牌,都很難保證安全性。

總體而言,它不會造成傷害為每個請求生成一個新的CSRF令牌。也許最好這樣做,只是讓安全審核員擺脫困境。但是,如果您已經有一個在整個會話中使用單個CSRF令牌的舊版應用程序,那麼花錢將其轉換為每個請求生成一個新的CSRF令牌可能不會在我的優先級列表中過高:我敢打賭可以找到這筆錢和開發人員精力的其他用途,從而進一步提高安全性。

如果他們推薦雙重Cookie提交,我不會稱他們為“信譽良好的安全專家”……XSS並非唯一的問題。 OWASP在這方面有一個很好的總結...
@AviD,兩次提交Cookie都很好。我還沒有看到任何證據表明這種方法比其他方法更容易受到攻擊。每種技術都有其漏洞。這個沒什麼不同。
@Gili雙重提交Cookie的問題在於,這通常是指正常的,已經存在的會話Cookie,並且JavaScript無法訪問該Cookie(例如,使用`HttpOnly`標誌)。使用此技術可能會阻止CSRF攻擊,但會使會話cookie打開其他問題,例如使其更容易受到可能的XSS漏洞的攻擊。有些技術可以很好地工作,而不會引起其他單獨的漏洞。
http://security.stackexchange.com/q/61110/5002中提到的@AviD,正是出於這個原因,OWASP指示開發人員為CSRF令牌使用單獨的cookie。您可以在會話Cookie中保留`HttpOnly`標誌。
@Gili是的,這就是重點。
@AviD,對不起,我不明白您的意思。您說過兩次提交cookie會迫使您從會話cookie中刪除`HttpOnly`標誌,但是我只是解釋了事實並非如此(您可以為單獨提交的cookie令牌使用單獨的cookie)。這不會使您的原始投訴無效嗎?
@Gili,重新閱讀了AviD的評論。不要錯過他對“通常”一詞的使用。通常,將雙cookie提交理解為意味著重新使用會話cookie。如果有人建議提交雙cookie,而沒有明顯相反的免責聲明,則意味著他們建議重新使用會話cookie。我認為AviD在上面的評論中涵蓋了這一點。
很公平。 PS:在相關說明中,http://security.stackexchange.com/a/43550/5002質疑HttpOnly對XSS攻擊的價值。
@Gili,是的,我知道。 :-)我剛剛發布了您鏈接到的問題的答案,並且還鏈接到有關`HttpOnly`的相同討論。感謝您的指導和討論!
@Gili是的,與D.W.完全一樣說,那正是我的意圖。
@AviD,很高興我們倆在同一頁面上。感謝您的澄清。
“為每個請求生成一個新的CSRF令牌都不會受到損害”,這會損害可用性(?)
可以刷新每個請求的CSRF令牌,但是您必須處理Ajax調用。在某種程度上,這是一個乏味的過程,但是可以更新Ajax調用。
rook
2012-10-20 23:24:34 UTC
view on stackexchange narkive permalink

XSS可以用來讀取CSRF令牌,即使它是單個提交令牌也是如此,這就是孩子的遊戲。推薦的單個提交令牌可能來自不了解CSRF的人。

使用“單個提交令牌”的唯一原因是要防止用戶意外單擊提交。兩次。這樣做的一個好方法是防止用戶兩次單擊“結帳”並意外向客戶收費兩次。

CAPTCHA或要求用戶提供當前密碼可以用作不能使用的反csrf措施

我建議閱讀 CSRF預防速查表

面對XSS,我看不出驗證碼或輸入密碼的安全性。它只是迫使攻擊者跳了幾圈。
攻擊者必須知道@CodesInChaos的密碼,然後才能知道其爭論點。
如果用戶在xss之後的某個時間輸入密碼,則攻擊者可能會竊取它。因此,重新輸入密碼會有所幫助,但作用不大。
@CodesInChaos在紙上可以正常工作,但是這種提議的攻擊在現實世界中成功的可能性很小。
@CodesInChaos您是正確的,CAPTCHA與此無關。另一方面,重新認證(選擇性地針對敏感操作)是CSRF的最佳解決方案之一,應使用更多。另請參閱Schneier關於“事務驗證”的討論,儘管沒有完全相同,但它們是相似的。
一次性令牌具有更大的好處(至少對於關鍵任務操作而言):它們增加了針對[重放攻擊]的安全性(http://en.wikipedia.org/wiki/Replay_attack)。
@Domi首先取決於他們如何獲得令牌。如果使用XSS或通過不安全的通道,則滾動令牌將無關緊要。
鑑於沒有XSS,它們仍然增加了針對重放攻擊的安全性。
Polynomial
2012-10-20 18:37:03 UTC
view on stackexchange narkive permalink

如果令牌在整個會話中都是相同的,則攻擊者可能會從一頁洩漏令牌並將其用於其他操作。

例如,您可以使用iframe加載頁面,然後使用XSS漏洞提取令牌。從那裡開始,您可以使用該令牌提交密碼更改表單

使用每個請求令牌而不是整個會話範圍的令牌會更加困難,但這不會阻止CSRF。攻擊者可以簡單地利用XSS從頁面讀取令牌,然後將其觸發。但是,如果令牌是全局的,而不是局限於該單個頁面,則攻擊者可以將任何頁面作為目標來竊取令牌。為每個請求使用單獨的令牌會更加困難。

有人無法從iframe中提取任何內容,這會破壞[同一原籍政策](http://en.wikipedia.org/wiki/Same_origin_policy)
-1
即使每次請求都刷新,也應該可以使用XSS提取令牌。我對嗎?
是的,您可以通過XSS將iframe加載到密碼更改表單中,然後可以提取該令牌,如果存在XSS漏洞,則生成新令牌並不能確保任何安全。
-1很抱歉,但我不希望人們想到如果他們使用單個提交令牌,那麼他們會受到XSS的魔法保護,因為那是最不正確的。如果用戶可以在Web瀏覽器中進行操作,則xss可以在Web瀏覽器中進行操作。
@Rook嗯?我從來沒有說過使用單個令牌是好的...
如果您有XSS漏洞,則可以使用XHR讀取任何頁面並提交任何請求。在每個頁面上使用不同的令牌無濟於事。
-1
SilverlightFox
2015-11-30 16:45:14 UTC
view on stackexchange narkive permalink

除其他答案外,如果您的服務器容易受到 BREACH攻擊的影響,那麼刷新令牌也很明智。

這需要滿足以下三個條件:

  • 由使用HTTP級壓縮的服務器提供服務
  • 在HTTP響應正文中反映用戶輸入
  • 反映秘密(例如作為HTTP響應正文中的 CSRF令牌

為減輕破壞,您需要在加載表單的GET請求上刷新CSRF令牌使所有先前的令牌無效。這樣,創建附加請求以發現頁面中令牌的MITM(中間人)每次都會獲得一個不同的令牌。這確實意味著真實用戶在MITM情況下將無法提交表單。

當然,您還需要滿足其他兩個條件。在每個會話中維護CSRF令牌並為任何提供表單的頁面禁用HTTP級壓縮可能會更容易。

user2428118
2015-07-17 15:45:15 UTC
view on stackexchange narkive permalink

這不是一個眾所周知的事實,但是普通的字符串比較容易受到定時攻擊(例如這種。長話短說,普通的字符串比較操作( == === )將兩個字符串從左到右逐個字符地進行比較,一旦在兩個字符串中的給定位置遇到任何不相等的字符,則返回false。 被證明是可檢測的

。通過使用定時攻擊來嘗試每個位置的每個可能字符,可以弄清楚實際令牌是什麼。通過每次提交帶有令牌的請求時都創建一個新令牌,可以防止這種攻擊。

當然,只有在無效時也重新創建令牌的情況下,此攻擊才有效令牌已提交,這可能是不希望的。因此,最好使用時間不敏感的字符串比較功能(例如this)來解決此問題。

好的,但是我必須在示例和論文中指出,您列出了理論上的攻擊者可以非常精確地測量CPU時鐘時間。這台機器沒有其他負擔,許多語言在執行逐字符檢查之前使用預先計算的哈希碼進行字符串比較。
恆定時間比較可以並且應該用來減輕這種情況(循環遍歷所有字符和異或標誌)。
edruid
2015-04-23 20:30:37 UTC
view on stackexchange narkive permalink

每個請求要更改CSRF令牌的原因之一是減輕令牌的壓縮洩漏。我的意思是,如果攻擊者Eve可以在包含令牌的頁面上註入數據,然後向頁面發送壓縮的Eve,則可以猜測字符串的第一個字符,從而為該頁面接收較小的數據集,因為她知道自己猜對了,然後就去了。轉到下一個字符。

這類似於定時攻擊。

目前(我知道)沒有理由僅在HTTP標頭中發送令牌時更改令牌。

另一種方法是在發現失敗的請求後立即更改令牌,但這可能會導致用戶無法提交任何表單。

Bhuvanesh
2015-07-17 12:37:51 UTC
view on stackexchange narkive permalink

如果整個會話使用相同的令牌,那麼攻擊者就有可能使用 XSS 劫持令牌,並使用受害者的會話進行某些惡意活動,例如更改密碼

他們可以通過將iframe拖到您正在使用的網站中來偽裝密碼。

因此,每個請求最好使用一個令牌,以避免攻擊者獲取訪問該令牌。

使用XSS的攻擊者可以訪問新令牌,這就是整個問題所在。另請參閱http://security.stackexchange.com/a/22904/15195上的評論


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...