一、網站一般在需要共享資源給其他網站時(跨域傳遞數據),纔會設置access-control-allow-origin HTTP頭。而跨域傳遞數據也可以使用jsonp方式
二、如果www.a.com域設置了access-control-allow-origin:* http頭, 其他任何域包括www.b.com域的js就可以使用Ajax技術讀取到www.a.com域的數據
三、根據w3c標準:http://www.w3.org/TR/cors/#resource-requests,如果www.b.com域下js要讀取到www.a.com域下的需要登錄才能訪問的資源,需要www.a.com域同時設置了 Access-Control-Allow-Credentials: true頭(即允許third-party cookie)
並且如果設置access-control-allow-origin爲*星號(任何域),則Access-Control-Allow-Credentials頭是不能設置爲true的,如下圖,參見http://www.w3.org/TR/cors/#resource-requests
所以理論上網站設置了Access-control-allow-origin: *,並沒有實際危害,因爲並不能跨域讀取私密數據(登錄後纔可見數據)
四、然而否存在實際危害取決於瀏覽器是否遵循該標準(chrome、firefox等主流瀏覽器均遵循)
瀏覽器發出跨域請求時,若Ajax沒有setRequestHeader,則會直接發出請求,根據響應頭中的access-control-allow-origin是否設置允許當前域(設置*,即允許任何域),來決定是否將數據交給js處理(其實數據已經返回到瀏覽器,但頁面js無法拿到)
另外若同時設置了星號和withCredentials,瀏覽器也會拒絕將數據返回到js。瀏覽器在這個層面上是安全的
但是瀏覽器插件卻往往會忽略http header的設置,比如postman,不免有其他利用方式。
所以服務器應設置白名單。(使用jsonp跨域共享資源存在更多風險,有機會寫寫jsonp)
五、測試使用的代碼如下http://localhost/test.htm,發送請求到http://127.0.0.1/對於瀏覽器來說就是在跨域,方便測試
ps: setRequestHeader需要在open之後調用。如果調用了setRequestHeader,瀏覽器會先發出OPTION請求到目標網站,確認是否設置Access-Control-Allow-Headers: content-type等
update:發現許多網站會根據請求頭中的Origin值然後設置Access-control-allow-origin,且同時設置了Access-Control-Allow-Credentials爲true,導致可以被黑客利用
Access-control-allow-origin:null 是可以攜帶cookie的
======================分割線=================
六、不攜帶cookie的利用姿勢
以上說的Access-control-allow-origin: *情況,是不能跨域讀取(需cookie認證的)隱私數據。
但也存在特定場景下不需要cookie也能攻擊的:
》基於ip認證的資源跨域讀取
》緩存投毒,增加Vary: Origin http頭可以避免