2012-05-24 89 views
40

特別是,我正在編寫一個Django RESTful API來支持iOS應用程序,並且每當我編寫處理POST請求的方法時,我都會繼續參與Django的CSRF保護。CSRF攻擊是否適用於API?

我的理解是,由iOS管理的cookie不會被應用程序共享,這意味着我的會話cookie是安全的,並且其他應用程序無法使用它們。這是真的?如果是這樣,我可以將我的所有API函數標記爲CSRF豁免嗎?

回答

41

這不是CSRF的目的。 CSRF將防止直接發佈數據到您的網站。換句話說,客戶必須實際上通過批准的路徑,即查看錶格頁面,填寫表格,提交數據。

API幾乎排除了CSRF,因爲它的全部目的通常是允許第三方實體訪問和操作您網站上的數據(CSRF中的「跨站點」)。所以,是的,我認爲任何API視圖都應該是CSRF豁免。但是,仍然遵循最佳實踐並保護實際上通過某種形式的身份驗證(例如OAuth)進行更改的每個API端點。

+4

什麼用戶註冊?這是我最大的一個,因爲我在寫現在,沒有CSRF和(顯然)沒有登錄了,還有什麼能夠阻止從虛假註冊充斥我的服務的人。 – Alex

+11

簡單。你不允許。我所知道的任何API都不允許您使用API​​實際創建帳戶*。您可以通過他們的網站創建該帳戶,然後使用API​​密鑰來驗證您的請求。 –

+4

那麼Twitter等人如何呢?支持通過本機iOS視圖註冊?我的直覺告訴我這是一個API調用,但安全原因讓我覺得事情並非如此。 – Alex

15

如果您也在使用API​​來支持網站,則可以應用它們。

在這種情況下,您仍需要某種形式的CSRF保護,以防止某人在其他站點中嵌入請求,從而對經過身份驗證的用戶的帳戶產生駕車影響。

Chrome似乎在默認情況下拒絕了交叉源POST請求(其他瀏覽器可能不是那麼嚴格),但允許GET請求跨源,因此您必須確保API中的任何GET請求都沒有副作用。

+3

您可以通過使用javascript提交表單來完成跨源文章。 –

+2

@NickRetallack幸運的是,沒有任何表單可以使用任何自定義標題進行跨域POST。所以,所有需要做的事情都需要POST的自定義標題。 – thesmart

34

CSRF攻擊依賴於cookie與所有請求隱式發送到特定域。如果你的API端點不允許基於cookie的認證,你應該是好的。

即使您確實使用基於cookie的身份驗證,您的Cookie也是安全的,因爲iOS apps do not share cookies。但是,除非您通過要求不尋常的用戶代理頭來故意阻止Web瀏覽器,否則另一方可能會構建使用您的API的基於瀏覽器的應用程序,並且如果您的API支持基於Cookie的身份驗證,並且該應用程序容易受到CSRF攻擊不適用CSRF保護。

+0

好了! @nick –

+2

這應該是被接受的答案 –

8

目前接受的答案(2012年5月)基本上是正確的,除了當您使用基於會話的身份驗證時。還值得一提的是CORS的作用。

簡單的情況是,您訪問foo.com並且網站執行Javascript以基於AJAX的DELETE請求到api.com/users/123並最終以您的名義刪除用戶。由於CORS,現在並不總是可能的 - 瀏覽器將阻止foo.comapi.com發出請求,除非api.com明確列入白名單foo.com。這也假定您正在使用基於會話的身份驗證而不是基於令牌的身份驗證。在基於會話的身份驗證中,登錄到api.com的任何用戶都可以在它們保持登錄狀態時執行請求。如果您具有基於令牌的身份驗證(每個請求都必須使用包含身份驗證令牌的HTTP Authorization標頭製作),那麼您是安全的。基於會話的身份驗證通過cookie隱式發送身份驗證令牌。

略差的情況是,如果你的信任CORS的領域之一被泄露 - 說你有不消毒的Javascript形式和用戶管理通過形式注入JS到您的網站。如果您使用基於會話的身份驗證,則訪問該頁面的已驗證用戶將看到Javascript運行併發出API請求。如果您使用基於會話的身份驗證來執行API,這可能是災難性的並且是非常現實的可能性。

1

根據DRF documentation, API是容易受到CSRF攻擊,只要服務器使用認證會話(而不是要求每一個一次性密碼)

的解決方案是

  1. 確保「安全」的HTTP操作如GETHEADOPTIONS不能被用於改變任何服務器端狀態。
  2. 確保任何'不安全'HTTP操作(例如POST,PUT,PATCHDELETE)始終需要有效的CSRF令牌。