題:
我應該在Rest API端點上使用CSRF保護嗎?
Conor Mancone
2017-08-03 23:41:43 UTC
view on stackexchange narkive permalink

快速說明:儘管存在一些重疊,但這不是具有自定義標頭(且沒有驗證令牌)的CSRF保護的重複。那篇文章討論瞭如何在Rest端點上執行CSRF保護,而不討論是否確實必要。確實,我在該站點上閱讀的許多CSRF / Rest問題都涉及通過CSRF令牌保護端點,而沒有實際討論是否有必要。因此就是這個問題。

Rest API端點是否需要CSRF保護?

我已經看到了很多有關保護REST端點不受CSRF攻擊的討論,但是考慮了很多話題之後,我非常確定REST端點上的CSRF令牌會給予零附加保護。因此,在REST端點上啟用CSRF保護只會向您的應用程序引入一些無用的代碼,我認為應該跳過這些代碼。我可能會丟失一些東西,因此這個問題出現了。我認為這將有助於記住為什麼首先需要CSRF保護以及它所針對的攻擊媒介:

為什麼要使用CSRF?

這實際上歸結為瀏覽器通過發送cookie來自動顯示任何請求的登錄憑據的能力。如果會話ID存儲在cookie中,瀏覽器將自動將其與所有返回原始網站的請求一起發送。這意味著攻擊者實際上不必知道身份驗證詳細信息即可採取行動作為受害者用戶。相反,攻擊者只需誘使受害者瀏覽器發出請求,身份驗證請求的憑據將免費使用。

輸入REST API

其他API終結點與其他請求有一​​個非常重要的區別:它們特別是無狀態的,絕不應該接受/使用cookie或會話中的數據。結果,遵循標準的REST API會自動免受此類攻擊。即使瀏覽器發送了cookie,與cookie關聯的所有憑據也將被完全忽略。 REST API調用的身份驗證以完全不同的方式完成。最常見的解決方案是具有某種身份驗證密鑰(OAuth令牌等),該身份驗證密鑰隨標頭一起發送,或者可能在請求主體本身中發送。

由於身份驗證是特定於應用程序的,而且由於瀏覽器本身不知道身份驗證令牌是什麼,因此即使有人被誘騙訪問API端點,瀏覽器也無法自動提供身份驗證證書。結果,無cookie的REST端點完全不受CSRF攻擊。

還是我錯過了一些東西?

某些REST API限制了每個ip的調用,這可能是實現csrf保護有意義的邊緣情況。
感謝您的輸入@Xavier59。您介意澄清一下:為什麼限制速率需要CSRF保護?
因此,我不確定這是否一定適用於您的情況,但是假設您使用google作為oauth提供程序。您的用戶登錄到某些惡意網站,該網站也使用google作為oauth提供程序。惡意網站可能會在您的網站上使用用戶的令牌(ish,取決於客戶端設置等)。看到這裡更多:https://spring.io/blog/2011/11/30/cross-site-request-forgery-and-oauth2
@ConorMancone如果站點“ A”具有一個REST API,將每個ip的調用限制為1 /秒,則攻擊者可能會欺騙Bob進入攻擊者站點“ B”,該站點每秒發送數十個請求。這可能會導致Bob的ip被該REST API禁止,或者阻止他正確使用REST API。我同意這有點牽強,但並非完全不可能。
@Xavier59這在某種程度上等同於嘗試通過在高流量網站上獲取帶有該網站作為其源屬性的img標籤來對網站進行DDoS。它不一定牽強。話雖如此,我不明白為什麼CSRF令牌會採取任何措施來減輕這種攻擊。
感謝@JesseKeilson。我要消化那個。僅僅因為攻擊媒介是安全的,並不意味著它並不危險!
@ConorMancone CSRF將通過不允許(併計數)與正確IP不相關的csrf令牌的請求來緩解此問題。因此,Bob ip不會因為使用rest api而被列入黑名單。希望你明白我的意思。
@JesseKeilson該鏈接的重點是針對OAUTH驗證服務器的CSRF攻擊。這是一個有趣的讀物。總體摘要是我之前學到的:就一般的工作流程而言,OAuth2令人驚訝地是不安全的。為了清楚起見,我專門指的是發行OAuth2令牌的過程。使用這些令牌是另一回事,通常更直接。
七 答案:
Conor Mancone
2017-08-04 18:25:29 UTC
view on stackexchange narkive permalink

我最初的目標不是自我回答,但經過更多閱讀後,我想出了一個我認為是全面的答案,這也解釋了為什麼有些人仍然對REST端點上的CSRF保護感興趣。 / p>

沒有cookie =沒有CSRF

確實就是這麼簡單。瀏覽器發送cookie和所有請求。 CSRF攻擊取決於此行為。如果您不使用Cookie,並且不依賴Cookie進行身份驗證,那麼絕對沒有CSRF攻擊的空間,也沒有理由進行CSRF保護。如果您有cookie,尤其是將它們用於身份驗證,則需要CSRF保護。如果您僅想知道“我的API端點需要CSRF保護嗎?”您可以在這裡停下來並留下答案。

h / t到paj28:雖然cookie是CSRF攻擊的主要攻擊媒介,但是如果您使用HTTP / Basic,也很容易受到攻擊。身份驗證。更一般而言,如果瀏覽器能夠自動傳遞應用程序的登錄憑據,則CSRF很重要。以我的經驗,cookie是使CSRF發生的最常用技術,但是使用其他一些身份驗證方法也可能導致相同的漏洞。

REST =無狀態

如果您問某人“什麼是REST”,您將獲得討論各種不同屬性的各種答案。您可以看到很多,因為有人在堆棧溢出時問了這個問題: https://stackoverflow.com/questions/671118/what-exactly-is-restful-programming

我一直依賴的REST的一個屬性是它是無狀態的。應用程序本身俱有狀態。如果您無法將數據存儲在某個地方的數據庫中,則您的應用程序將受到很大限制。但是,在這種情況下,無狀態具有非常具體且重要的含義:REST應用程序不會跟踪客戶端應用程序的狀態。如果您正在使用會話,那麼(幾乎可以肯定)您正在跟踪客戶端狀態,並且您不是REST完整的應用程序。因此,使用通過cookie跟踪的會話(尤其是登錄名)的應用程序不是REST-full應用程序(IMO),並且即使看起來像REST應用程序,也很容易受到CSRF攻擊。

Rest≠Cookieless

由於這些原因,我最初認為完全兼容的REST應用程序將永遠不需要會話,不需要Cookie,因此也不需要CSRF安全性。但是,至少有一個用例仍然喜歡使用cookie:持久登錄。

考慮一個典型的客戶端(在這種情況下為瀏覽器,而不是移動設備)Web應用程序。從登錄開始,登錄使用REST API來驗證用戶憑據,作為回報,將獲得一個令牌來授權將來的請求。對於單頁應用程序,您可以只將該令牌保留在內存中,但是這樣做會在用戶關閉頁面時有效地註銷用戶。因此,最好將狀態保持在比單個瀏覽器會話持續時間更長的位置。本地存儲是一種選擇,但也容易受到XSS攻擊:成功的XSS攻擊可能導致攻擊者獲取您的登錄令牌並將其發送給攻擊者,以供其自行決定。

為此,原因,我已經看到一些建議使用Cookie來存儲登錄令牌。使用cookie可以設置僅http標誌,這將阻止應用程序在設置cookie後讀取它。因此,在發生XSS攻擊時,攻擊者仍可以代表您撥打電話,但他們無法一起擺脫授權令牌。 Cookie的這種使用不會直接違反REST的無狀態要求,因為服務器仍未跟踪客戶端狀態。

我之所以提及這一點,是因為使用cookie與REST API一起使用可能是合理的理由,儘管它顯然取決於給定的應用程序平衡各種安全性和可用性問題。我個人會嘗試避免將cookie與REST API一起使用,但是很可能還是有理由使用它們。無論哪種方式,總的答案都很簡單:如果您使用Cookie(或瀏覽器可以自動執行的其他身份驗證方法),則需要CSRF保護。如果您不使用Cookie,那麼您就不會使用。

您幾乎可以找到。HTTP基本身份驗證和基於IP的身份驗證等可能會受到CSRF的攻擊。相反,如果Cookie僅是使用該服務的定制客戶端而不是瀏覽器,則它可以是安全的。那可能不會影響您的決定,但值得牢記。我發現人們試圖定義什麼是“適當的REST”,這是IT中建設性最低的討論之一。實際上,大多數服務都需要身份驗證,而會話是進行身份驗證的合理方法。
感謝@paj28。HTTP基本認證值得一提。我認為這很少見(這就是為什麼我忘記提及它的原因),但是當您嘗試提出一個全面的答案時,最好提及例外情況。
我沒有得到您的第三點,如果我將令牌存儲在會話cookie中,是否還需要csrf保護?
@HFA如果您使用cookie(尤其是用於身份驗證),則需要CSRF保護。Cookie中存儲的內容無關緊要:如果Cookie的內容用於通過您的應用對用戶進行身份驗證,則CSRF是必需的,因為瀏覽器會自動將Cookie附加到對您網站的所有請求中。
我將身份驗證令牌存儲在具有會話生存期的cookie內,並使用該cookie的內容來攔截每個http請求並向http請求添加授權標頭,這也算在內嗎?;)
@HFA:要使用該cookie的內容,您需要使該cookie不能為HttpOnly(即JS可訪問)。這樣一來,您可能會將自己暴露於XSS中,就像使用本地存儲一樣。此外,如果您的服務器_does_接受cookie作為身份驗證的方式,那麼您也可以使用CSRF。因此,僅使用本地存儲,並確保防止XSS,僅當您的服務器接受cookie時,cookie才有意義。
@BorisB。LocalStorage不具有會話生存期功能,因此我使用用戶計算機中javascript設置的會話cookie來存儲令牌。我使用授權標頭而非Cookie進行身份驗證。
嗨...如果我已經通過身份驗證並且擁有“ cookies”,怎麼做類似“ Brute Force”的事情?
HTTP實際上是一個無狀態協議。之所以這麼稱呼它是因為到服務器的2個不同的請求(連接)可能來自不同的地方,但是如果請求內容相同,則將獲得幾乎相同的數據(如果服務器狀態沒有變化)。這就是為什麼HTTP是REST的絕佳協議的原因。HTTP Cookie也會在標頭中發送(瀏覽器會自動添加它),而大多數REST API希望它在另一個標頭(如授權)中發送。無論您將令牌存儲在cookie,localStorage還是sessionStorage中,XSS腳本都可以訪問它,但是不能進行簡單的CSRF攻擊。
我正在使用localStorage保存訪問令牌,這容易受到CSRF的攻擊嗎?
@Shashidhara不行。但是它現在的XSS風險比httpOnly cookie還要高(這是一個折衷,不是說localStorage不好,只是威脅模型不同)
一個小小的澄清:“沒有cookie =沒有CSRF”-我也這樣認為,但是在Kerberos / NTLM本機瀏覽器支持(SPNEGO)下,一個kerberos令牌被發送到了一組列入白名單的域。這些案例還應具有CSRF保護,因為它在本質上與cookie相同,即“某些內容會根據請求自動發送內容”,因此我認為如果您提交的表單的目標是使用Kerberos的API端點,內部網絡,這裡也存在CSRF風險,不是嗎?
是的,即使根據OWASP,它也不只是cookie,如果您具有NTLM / Kerberos,也需要CSRF。https://www.owasp.org/index.php/Top_10_2007-Cross_Site_Request_Forgery
另一個關於“沒有cookie =沒有CSRF”的問題-如果您將會話令牌存儲在URL中(不好的主意,但是確實發生了),那麼就可以像欺騙cookie中的會話令牌一樣容易地誘騙用戶提交表單。這將需要事先了解令牌(瀏覽器歷史記錄/代理日誌/服務器日誌),這是一個障礙,但在某些情況下可行。非常具體的情況,但我認為值得一提。
stuartm9999
2018-08-03 13:20:29 UTC
view on stackexchange narkive permalink

”“即使通過某種方式誘使瀏覽器訪問了API端點,瀏覽器也無法自動提供身份驗證憑據” Windows / Kerberos身份驗證。在這種情況下,如果配置為這樣做,則瀏覽器將自動提供憑據(kerberos或NTLM令牌)。

所以-我相信在這種情況下,需要CSRF。

是的https://www.owasp.org/index.php/Top_10_2007-Cross_Site_Request_Forgery“僅基於自動提交的憑據(例如,如果當前登錄到應用程序,則為會話cookie)授權請求,如果未登錄,則“記住我”功能應用程序或Kerberos令牌**,如果Intranet參與與Active Directory集成登錄的部分存在風險。”
an0904
2019-04-23 00:15:17 UTC
view on stackexchange narkive permalink

是否需要CSRF保護基於兩個因素:-

請求是否在執行狀態更改操作(與REST API無狀態不同)-狀態更改動作是將更改應用程序狀態的任何動作。例如,刪除某些內容,添加某些內容,更新某些內容。這些是應用程序用來更改用戶支持狀態的操作。所有“發帖”請求和一些“獲取”請求將屬於此類別。 REST API可以具有狀態更改操作。

是瀏覽器提供的身份驗證(不限於Cookie)-CSRF之所以發生,是因為瀏覽器在請求中包含了身份驗證信息,而不管是否該請求是由用戶或其他打開的標籤頁啟動的。因此,瀏覽器可以自我包含信息的任何身份驗證都需要CSRF保護。這包括基於cookie的會話和基本身份驗證。

對於屬於以上2類的所有請求,都需要CSRF保護。

Charlie Reitzel
2019-09-25 01:06:33 UTC
view on stackexchange narkive permalink

我想在其他答案中添加的一件事是,在所涉及的cookie的域和路徑中,僅 b>才需要CSRF保護。或換種說法:

授權!=身份驗證
Cookies ==身份驗證
令牌==授權

這與持久性登錄的實現有關(您的第三點)。如果將Cookie附加到託管登錄UI和 / authorize 端點的 login.example.com 上,則可以每隔幾分鐘運行一次隱式OAuth流,而無需一個新的登錄名(例如無密碼對話框)。客戶端無需CSRF即可繼續將如此獲取的訪問令牌發送到 api.example.com ,因為不會將Cookie發送到該主機。

因此,您仍然可以安全地避免在您的REST API上處理CSRF。但是您的登錄/身份驗證服務器最好是防彈的(並受CSRF保護)。

John Wu
2017-08-04 01:28:59 UTC
view on stackexchange narkive permalink

Rest API端點與其他請求有一​​個非常重要的區別:它們特別是無狀態的,絕不應該接受/使用cookie或會話中的數據。

如果這是定義“ REST API”的方式,則不可能使用CSRF。 CSRF,也稱為“會話騎馬” [ citation],如果沒有要“騎馬”的會話,顯然將不起作用。

如果您不同意我的部分陳述,我將很高興聽到。IMO,無狀態是REST API的主要目標。會話肯定會使API狀態化。Cookies ...從技術上講,我想您可以使用Cookies而不是在狀態服務器端進行存儲,這取決於您如何使用它們。
好吧,我寧願回答這個問題,也不願爭論術語。但是HATEOS中的S和REST中的S都代表狀態。只要客戶端狀態不保留在服務器上,我認為您就不會“違反” REST方法的精神。
我絕對同意你的看法。我不是想爭論術語。問題的一部分是我對最初的問題還不夠清楚:我是在專門談論客戶端狀態,而不是應用程序狀態。
是的,國家轉移,這是重點。狀態未存儲在服務器端。客戶端將其狀態告知服務器。只有通過常規Web瀏覽器訪問api時,CSRF才有意義。如今的瀏覽器甚至不支持某些HTTP方法(例如DELETE,PUT / PATCH),這使得該API僅可用於獨立的HTTP客戶端。
Raywell
2020-02-07 15:39:47 UTC
view on stackexchange narkive permalink

答案:如果將令牌存儲在localStorage中並使用JS將其附加到您的請求中,它將自動保證CSRF保護(根據攻擊的性質)

附錄:關於使用僅使用HTTP的cookie而不是localStorage是否更安全(在XSS的情況下,使用CSRF保護的方式似乎會產生問題):實際上不是。對於通過漏洞利用XSS來控制您網站上JS的攻擊者來說,這只會變得有點困難。@ bobince用更好的話解釋道:設置httponly是否可以防止使用XSS竊取會話?

XSS是應用程序級別的漏洞,但可以通過使用聲明限制使用令牌的能力(將其限制為最低限度)來減輕其影響

歡迎。作為問答站點,我們不同於討論站點。答案需要獨立作為問題的答案,而不是對其他答案的評論。
@schroeder謝謝。長期潛伏在第一次的海報上,最初我想發表評論,但這要求最低聲譽。但是,該註釋導致我在最後一句中對OP問題做出了最初的回答:“我應該使用csrf保護嗎” =>如果令牌存儲並由JS附加到標題,則否
我只能說:繼續為網站做出貢獻,以獲得足夠的聲望,以釋放發表評論的能力。您已邁出了“潛伏”的第一步。繼續 :)
我建議您刪除對其他答案的評論,並確保該答案直接解決了該問題。
可以,但是我認為這很重要,因為它可以使一切變得不同(推理導致答案)。我將澄清結論
我已經改寫了答案,希望它看起來不像是討論(內容幾乎相同)。我正在等待我的聲譽對已接受答案中的誤導性部分發表評論。 在此期間,我享受著我自動生成的十字記頭像
Dean Valentine
2020-08-13 09:20:55 UTC
view on stackexchange narkive permalink

對於我想添加的現有答案,有一個小的特定警告。儘管Conor認為Cookie是沿著所有請求發送的本地存儲身份驗證數據的唯一形式是正確的,但它們並不是網站使用的本地存儲身份驗證數據的唯一形式。這意味著,如果站點決定將其JWT /會話令牌保留在LocalStorage或SessionStorage之類的內容中,則有時仍可以通過javascript自動將其刪除,然後在無需用戶交互的情況下使用它們。這意味著有時仍然可以通過將用戶重定向到 then 發送憑據的域匹配前端URI來執行“一旦刪除” CSRF攻擊。如果您已經反映了XSS,則可以通過更直接的方式來完成此操作,但是在某些情況下,這是不必要的,並且此類頁面和腳本已經存在。

在這些情況下,問題不是出在REST API上缺少CSRF令牌。不管與之交互的任何前端,端點上都沒有令牌。

哇,太和氣了!如此瑣碎,如果可以以某種方式將JS注入目標站點,則任何會話都可能被盜。
@peterh-ReinstateMonica很可愛,但是正如我在帖子中所說,這不是我的意思。前端位於其餘API的前面並不少見,這些終結點在加載時已經執行了可變操作,而無需您向其中註入代碼,這並不少見。


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...