2012-03-15 122 views
52

我正在開發JSON/REST Web API,我特別希望第三方網站能夠通過AJAX調用我的服務。因此,我的服務正在發送着名的CORS標頭:何時安全啓用CORS?

Access-Control-Allow-Origin: * 

這允許第三方網站通過AJAX調用我的服務。迄今爲止都很好。

但是,我的web api的一個子部分是非公開的,並且需要身份驗證(OAuth和access_token cookie是非常標準的東西)。在我的網站的這一部分啓用CORS是否安全?

一方面,如果第三方網站可能有一個也與我的服務的這部分交互的ajax客戶端,那將是很酷的。但是,首先出現同一起源政策的原因是,這可能是有風險的。您不希望任何後來訪問的網站能夠訪問您的私人內容。

我擔心的情況是,用戶通過網站或通過他信任的網站登錄我的web api,他忘記註銷。這是否允許每個其他網站,他後來利用現有的會話訪問他的私人內容?

所以我的問題:

  • 是以往任何時候都安全,使非公開內容CORS?
  • 如果啓用CORS的服務器通過cookie設置session_token,這個cookie會保存在CORS服務器或主網頁服務器的域下嗎?
+2

請注意,您只能在希望他人從其他來源訪問的資源上發送CORS標頭。而且,您還可以將CORS訪問權限限制爲您期望使用的來源。 – 2012-03-15 03:52:26

+1

Idealy,如果安全許可,我希望所有資源都可以從任何來源訪問。用戶仍然可以提供有效的憑證。我只想確保我不會爲惡意網站的跨站腳本攻擊打開大門。 – Jeroen 2012-03-15 04:23:16

回答

29

在回答第二個問題時(如果啓用了CORS的服務器通過Cookie設置session_token,?),該Cookie將保存在CORS服務器的域下。主網頁的JS代碼無法訪問cookie,即使通過document.cookie。只有在設置了.withCredentials屬性後,纔會將cookie發送到服務器,即使如此,僅當服務器設置Access-Control-Allow-Credentials標頭時纔會接受該cookie。

你的第一個問題是更開放一點。這是相當安全的,但有辦法繞過事情。例如,攻擊者可以使用DNS中毒技術來使預檢請求觸發實際的服務器,但將實際的CORS請求發送給流氓服務器。這裏是CORS安全一些資源:

最後,你關注的是圍繞給任何網站訪問您的數據CORS。爲了防止這種情況發生,您不應該使用Access-Control-Allow-Origin: *標題。相反,你應該回顯用戶的Origin值。例如:

Access-Control-Allow-Origin: http://www.example.com 

此頭將只允許http://www.example.com訪問響應數據。

+2

你能否澄清一下如何回顯'origin'頭部以增加安全性?我認爲任何惡意網站/腳本都可以很容易地設置這個頭文件?或者你的意思是維護某種白名單? – Jeroen 2012-03-15 20:14:54

+3

是的,保持可接受的來源白名單是一個解決方案。另一種方法是將用戶會話ID綁定到特定的來源。這樣,如果不同來源以某種方式用用戶的憑證重新發送請求,它將會失敗。 – monsur 2012-03-15 20:22:20

+0

我想你的意思是說攻擊者會攔截預檢,而不是實際的請求。還要注意GET不是預先運行的。 – csauve 2012-10-12 02:00:51

15

CORS的意圖是允許XHR請求的跨域請求,同時賦予服務器指定哪些源可以訪問哪些資源的權限。特別是,CORS引入了來源標題字段,該標題字段允許服務器區分常規和可能的XHR請求。此標題字段不能由用戶設置或更改,但由瀏覽器爲XHR請求設置。

因此,如果您有一個旨在僅供XHR使用的API,則您可以(也應該)要求該請求符合CORS。特別是如果請求也可以修改服務器上的狀態,否則你會很容易受到CSRF的攻擊。

注意CSRF攻擊是可能的,無論CORS使用其他方法僞造GET和POST請求。如果服務器允許,CORS只啓用訪問服務器對JavaScript的XHR請求的響應。