2014-02-27 106 views
1

我想爲我的應用程序實現一個CSRF阻止機制,方法是設置一個cookie併發送每個POST/PUT/DELETE請求具有相同值的HTTP頭。在我閱讀的各處,最佳實踐表明,應該從服務器設置csrf cookie。我使用AngularJS構建單頁面應用程序,他們還建議出於安全考慮,cookie應該由服務器在第一個GET請求上發送。在客戶端設置XSRF cookie

我的問題是 - 爲什麼服務器應該發送cookie,而不是隻使用簡單的javascript和生成的隨機uuid值在客戶端上設置它?另外,如果你有一個公共應用程序可以被所有人訪問,並且仍然需要從csrf中保護它,服務器端如何記住它向哪個用戶發送了什麼標記,如果他們沒有會話cookie?

+0

_「如果服務器端會記住它向哪個用戶發送什麼令牌(如果他們沒有會話cookie的話)?」 - - 它首先必須有其他一些標準來識別用戶,你覺得呢? – CBroe

+0

以什麼方式將CSRF令牌從服務器傳遞到客戶端並返回並不重要。 – CBroe

回答

0

擁有CSRF令牌的重點在於讓一些惡意用戶或程序不會模仿其他用戶。傳統上,CSRF令牌由服務器生成並存儲在該用戶的會話中。這將自動爲該用戶創建一個cookie,並且您的後端代碼應該爲CSRF令牌添加隱藏的表單字段以便於表單提交。因此,無論何時用戶向您的服務器發送POST/PUT/DELETE請求,您都會檢查服務器中的CRSF令牌是否與用戶提交的令牌相匹配。

另外,如果你有一個可以由大家 訪問和公共應用程序仍然需要保護它免受CSRF,如何將服務器端記得 什麼記號發送給哪些用戶,如果他們沒有會話cookie?

那麼,服務器並不在乎用戶是否通過身份驗證。對於任何訪問您的網站的用戶,您應該應該創建一個CSRF令牌並將其添加到任何形式或任何創建一個非冪等請求到您的網站。在會話中爲用戶添加CSRF令牌只會創建一個cookie並將其提供給瀏覽器,這不需要登錄。同樣,這將使攻擊者的生活變得艱難,因爲首先,他們沒有正確的cookie發送,其次,他們不會猜測用戶生成的CSRF令牌。

2

爲什麼要把服務器發送cookie ...

,使服務器能夠知道(驗證),從你的應用程序中的第二個請求從您的應用程序來精確地(因爲相同的應用程序是隻有第一個請求的響應的接收者)。我說該令牌不用於授權,因爲它直接從令牌映射到的用戶派生。例如,您不能使用該令牌來刪除其他用戶。但是,您的代碼仍然可以被利用,並且該令牌會受到惡意代碼的危害,但我們稍後再考慮。

...而不是僅僅將其設置在客戶端上...

任何事先溝通的設置用於不同的用途,看看https://en.wikipedia.org/wiki/Shared_secrethttps://en.wikipedia.org/wiki/Symmetric-key_algorithm。您的應用程序是公開的,它解釋了爲什麼不提前將其設置在客戶端上。

使用簡單的javascript和生成的隨機uuid值?

設置uuid是毫無意義的,因爲任何人都可以這樣做:您的服務器無法區分uuid與應用程序和黑客的區別。

另外,如果你有一個公共的應用程序,每個人都可以訪問,還是需要保護它免受CSRF ...

但是,如果你的應用程序(和其中的API)是公開的,你不應該保護它,對吧?試試curl https://api.github.com/users/mongodb/repos。我最近了解到,您可以通過提供cookie atl.xsrf.token=no-check(也可以通過頭文件工作,請注意JSESSIONID仍用於實際身份驗證)來禁用Bamboo api的XSRF保護。

服務器端如何記住它向什麼用戶發送的令牌,如果他們沒有會話cookie?

XSRF令牌通常會作爲自定義X- HTTP標頭進來。甚至作爲路徑/查詢參數,不需要cookie。

XSRF僅用於通過使用您的API向其應用發送最後一個請求(或免費獲得新標記的初始GET)的令牌來驗證您的應用的下一個請求。正如其他答案正確指出的那樣,服務器可以決定使用每個冪等請求來更改標記。標準做法是對每個請求都有一個新的標記,但它們很便宜。

最後但並非最不重要的,想想一些利用情況:

  • 如果我管理注入一些JavaScript,並獲得您的應用程序的餅乾,其中令牌(或DOM或JS命名空間或通過一些訪問令牌js getter),然後我可以驗證DELETE對您的api的請求
  • 如果我設法將您的應用程序重定向到我的服務器(任何欺騙您的DNS,沒有SSL等),我得到您的令牌,我的下一個DELETE請求可能會被拒絕,如果:
    • 您的服務器要求每個請求一個新的令牌,並...
    • 你設法比我更快地使之間的要求,我會再試一次或...
    • 服務器是足夠聰明地看到,用同樣的多個請求來自不同IP的,並至少給你喜歡的Gmail
  • 警告如果我管理重定向服務器API的響應(意思是我有一個新的令牌),我DELETE請求將會成功,但你下一個請求會給你一個警告,說你正在訪問一個陳舊的資源(我的請求已被修改)。我認爲這是對會議的樂觀鎖定。

總之,不要爲您的公共API使用csrf。在渲染數據時使用它,在你的代碼或冪等通話中包含遠程資源,但保持良好。希望這一切都有道理。