我正在爲一組網站設計API。這些站點非常相似(有點像StackOverflow,SuperUser和ServerFault),並且他們有一個共享的後端是合理的。因此,我們決定嘗試使用一個很好的REST API作爲後端,以及一些使用API的非常相似但不同的前端。前端應該最好全部是靜態的,但如果事實證明這是不可能的,那麼這並不是一個硬性要求。如何保護瀏覽器從CSRF攻擊中使用的RESTful API?
我正在設計API,我擔心安全問題,特別是CSRF。從我對CSRF攻擊的基本理解來看,它們包含兩個重要組件:
能夠命名資源和請求正文。
欺騙用戶/瀏覽器使用環境認證(如會話)向該資源尋求認證的請求。
很多修復CSRF攻擊的經典方法都基於會話。由於我的REST API並沒有真正執行會話,因此它們都會阻止很多向量,並且幾乎可以解決所有這些問題。例如,雙提交沒有意義,因爲沒有什麼可以提交。
我最初的方法是攻擊CSRF攻擊的第2部分。如果我對所有請求進行了身份驗證(比如使用HTTP Basic Auth),並且瀏覽器不保存這些證書(例如,某些JS發出請求),那麼只有擁有憑證的JS才能發出請求,並且我們完成了。明顯的缺點是應用程序需要知道用戶的憑據。另一個稍微不太明顯的缺點是,如果我想在API端安全地存儲憑據,那麼驗證密碼應該花費固定的,不重要的時間量。如果安全地驗證密碼需要100ms,那麼其他每個請求至少需要100ms + eps,並且這會讓一些聰明的客戶端欺騙手段使其不那麼慢。我可能能夠緩存這些信息(因爲證書總是相同的),如果我非常小心,我可能會設法做到這一點,而不會引入定時漏洞,但這聽起來像是一個黃蜂巢。
OAuth 2.0似乎有點過分了,但我想這可能是最好的解決方案,以免我最終實施得不好。我想我現在可以做HTTP基本身份驗證的事情,當我們有第三方應用程序開發人員時,轉到OAuth。
OAuth有一點阻抗不匹配。基本上,OAuth真的想幫助應用程序訪問另一個應用程序的內容。我希望用戶在這樣一個帳戶存在之前註冊其中一個前端。
我也考慮過攻擊點1,通過使URL隨機化 - 即將標記添加到查詢字符串。這肯定會起作用,它與表單中傳統的隨機化令牌非常接近,並且給予HATEOAS它應該甚至是相當RESTful,儘管這提出了兩個問題:1)您從哪裏開始?在使用HTTP Basic Auth進行登錄時,是否有必要的API起始點? 2)如果他們不能事先預測URL,HATEOAS會被定罪嗎?
我看過How to prevent CSRF in a RESTful application?,但我不同意這樣一個前提,即隨機化的URI必然是不可靠的。另外,這個問題並沒有真正的答案,也沒有提到OAuth。此外,會話雙提交解決方案是無效的,正如我上面提到的(靜態前端的不同域比API端點)。
我意識到我從根本上試圖在這裏做的是試圖允許來自一個域的跨站點請求,並禁止從另一個域請求,這並不容易。當然必須有一些合理的解決方案?
的問題,就像你說的,是要既防止和允許跨站點請求。問薛定諤。 –
這並不意味着沒有辦法解決問題。我甚至提供了一個,儘管有點慢。 – lvh