爲什麼要把服務器發送cookie ...
,使服務器能夠知道(驗證),從你的應用程序中的第二個請求從您的應用程序來精確地(因爲相同的應用程序是隻有第一個請求的響應的接收者)。我說該令牌不用於授權,因爲它直接從令牌映射到的用戶派生。例如,您不能使用該令牌來刪除其他用戶。但是,您的代碼仍然可以被利用,並且該令牌會受到惡意代碼的危害,但我們稍後再考慮。
...而不是僅僅將其設置在客戶端上...
任何事先溝通的設置用於不同的用途,看看https://en.wikipedia.org/wiki/Shared_secret或https://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。在渲染數據時使用它,在你的代碼或冪等通話中包含遠程資源,但保持良好。希望這一切都有道理。
_「如果服務器端會記住它向哪個用戶發送什麼令牌(如果他們沒有會話cookie的話)?」 - - 它首先必須有其他一些標準來識別用戶,你覺得呢? – CBroe
以什麼方式將CSRF令牌從服務器傳遞到客戶端並返回並不重要。 – CBroe