89

當應用程序依賴無狀態身份驗證(使用類似HMAC)時,是否有必要使用CSRF保護?使用無狀態(= Sessionless)身份驗證時需要CSRF令牌嗎?

例子:

  • 我們已經有了一個單頁的應用程序(否則我們不得不追加每條鏈路上的標記:。<a href="...?token=xyz">...</a>

  • 用戶驗證自己使用POST /auth身份驗證成功服務器將返回一些令牌

  • 令牌將通過JavaScript存儲在單個頁面應用內的某個變量中

  • 此令牌將用於訪問受限制的URL,如/admin

  • 令牌將始終在HTTP頭中傳輸。

  • 沒有Http Session,也沒有Cookies。

據我瞭解,應該有(?!)是沒有可能利用跨站攻擊,因爲瀏覽器不會存儲令牌,因此它不能自動將其發送到服務器(這是使用Cookies/Session時會發生什麼)。

我錯過了什麼嗎?

+5

請注意基本身份驗證。許多瀏覽器會自動發送會話剩餘部分的基本身份驗證標頭。這可以使基本身份驗證容易受到CSRF作爲cookie身份驗證的影響。 – phylae

回答

121

我發現了大約CSRF +使用沒有 cookie進行認證的一些信息:

  1. https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
    「因爲你不是靠餅乾,你並不需要,以防止跨站點請求」

  2. http://angular-tips.com/blog/2014/05/json-web-tokens-introduction/
    「如果我們走下來的餅乾方式,你真正需要做的CSRF避免交叉站點的請求,這是我們不能忘記當你使用智威湯遜時你會看到。「
    (JWT = JSON網絡令牌,無國籍應用基於令牌的認證)

  3. http://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services
    「做認證,而不用擔心CSRF漏洞的最簡單的方式就是避免使用cookie來識別用戶」

  4. http://sitr.us/2011/08/26/cookies-are-bad-for-you.html
    「CSRF最大的問題在於,cookies絕對無法防禦此類攻擊,如果您使用cookie身份驗證,還必須採取額外措施來防止CSRF,最基本的precaut您可以採取的措施是確保您的應用程序不會響應GET請求執行任何副作用。「

如果您不使用cookie進行身份驗證,則有更多頁面指出您不需要任何CSRF保護。當然,你仍然可以使用cookies來處理其他事情,但是避免在裏面存儲任何類似session_id的東西。


如果你需要記住的用戶,有2個選項:

  1. localStorage:一個在瀏覽器的鍵值存儲。存儲的數據即使在用戶關閉瀏覽器窗口後也可用。數據不能被其他網站訪問,因爲每個網站都有自己的存儲空間。

  2. sessionStorage:另外一個在瀏覽器中的數據存儲。區別在於:當用戶關閉瀏覽器窗口時,數據被刪除。但如果你的web應用程序由多個頁面組成,它仍然很有用。所以,你可以做到以下幾點:

    • 用戶登錄,那麼你存儲在sessionStorage
    • 用戶令牌點擊一個鏈接,它加載了新的一頁(=一個真正鏈接,沒有JavaScript的內容 - 替換)
    • 您仍然可以從sessionStorage
    • 訪問令牌要註銷,您可以手動從sessionStorage刪除令牌或等待用戶關閉瀏覽器窗口,它會清除所有存儲的數據。

(針對看看這裏:http://www.w3schools.com/html/html5_webstorage.asp


是否有令牌身份驗證任何官方標準? (Json Web Token):我認爲它仍然是一個草案,但它已被很多人使用,並且這個概念看起來簡單而安全。 (IETF:http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25
也有很多可用的框架庫。只需谷歌!

+18

關於CSRF的偉大總結!我會注意到,將您的令牌存儲在localStorage或sessionStorage中容易受到XSS攻擊,並且數據可以通過頁面上的腳本進行查看 - 因此,如果您從CDN提供受損腳本,或者您的某個惡意代碼JS庫,他們可以從這些存儲位置盜取令牌。請參閱:https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/我認爲最安全的方法是在Cookie中存儲JWT + CSRF令牌,然後將您的計算JWT與CSRF令牌一起放入請求頭中。 –

+0

關於:「您可以採取的最基本的預防措施是確保您的應用程序不會響應GET請求執行任何副作用。」 CSRF攻擊可能僞造POST請求嗎? – Costa

+0

根據服務器端應用程序,它是可能的。有Web框架,它使用類似'http://.../someRestResource?method = POST'。所以它基本上是一個GET請求,但服務器應用程序將它解釋爲POST請求,因爲它被配置爲使用'method'參數而不是HTTP頭。 '...'關於常見的Web瀏覽器,他們強制使用同源策略,並且只對外部服務器執行GET請求。雖然如果**網頁瀏覽器不適用這些網絡標準(錯誤,惡意軟件),它可能*可能執行'POST'請求​​*。 –

33

JWT,如果使用沒有Cookie,否定CSRF令牌的需要 - 但!通過將JWT存儲在session/localStorage中,如果您的站點存在XSS漏洞(相當常見),則會暴露JWT和用戶的身份。最好向JWT添加一個csrfToken密鑰,並將JWT存儲在一個包含securehttp-only屬性的cookie中。

閱讀這篇文章,有一個很好的說明更多的信息 https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage

可以使這個CSRF保護無國籍由包括xsrfToken JWT要求:

{ "iss": "http://galaxies.com", "exp": 1300819380, "scopes": ["explorer", "solar-harvester", "seller"], "sub": "[email protected]", "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e" }

所以你會需要將csrfToken存儲在localStorage/sessionStorage以及JWT本身(存儲在http-only和安全cookie中)。然後爲了保護csrf,請驗證JWT中的csrf標記是否與提交的csrf-token標頭匹配。

+0

這似乎是我最常識的安全方法 - 尤其是如果JavaScript應用程序被授予刷新令牌。你真的不是csrf的攻擊者能夠僞造成令牌刷新方法。 –

+2

應該在用戶的api驗證過程中豁免csrf令牌的使用情況嗎? – user805981

+1

值得指出的是(正如其他人在源代碼鏈接的評論中也提到的那樣)任何使用a)不是http-only的cookie或者b)將CSRF令牌存儲在本地存儲中的CSRF緩解容易受到XSS的影響。這意味着所提出的方法可能有助於保持JWT對使用XSS的攻擊者的祕密,但是攻擊者仍然能夠在您的API上執行惡意請求,因爲他能夠提供有效的JWT(通過cookie,感謝您的瀏覽器)和CSRF令牌(通過從本地存儲/ cookie中注入的JS讀取)。 –

相關問題