為了防止CSRF的攻擊,我們建議修改瀏覽器在發送POST請求的時候加上一個Origin字段,這個Origin字段主要是用來標識出最初請求是從哪里發起的。如果瀏覽器不能確定源在哪里,那么在發送的請求里面Origin字段的值就為空。
隱私方面:這種Origin字段的方式比Referer更人性化,因為它尊重了用戶的隱私
1、Origin字段里只包含是誰發起的請求,並沒有其他信息 (通常情況下是方案,主機和活動文檔URL的端口)。跟Referer不一樣的是,Origin字段並沒有包含涉及到用戶隱私的URL路徑和請求內容,這個尤其重要。
2、Origin字段只存在於POST請求,而Referer則存在於所有類型的請求。
隨便點擊一個超鏈接(比如從搜索列表里或者企業intranet),並不會發送Origin字段,這樣可以防止敏感信息的以外泄露。
在應對隱私問題方面,Origin字段的方法可能更能迎合用戶的口味。
服務端要做的:用Origin字段的方法來防御CSRF攻擊的時候,網站需要做到以下幾點:
1、在所有能改變狀態的請求里,包括登陸請求,都必須使用POST方法。對於一些特定的能改變狀態的GET請求必須要拒絕,這是為了對抗上文中提到過的論壇張貼的那種危害類型。
2、對於那些有Origin字段但是值並不是我們希望的(包括值為空)請求,服務器要一律拒絕。比如,服務器可以拒絕一切Origin字段為外站的請求。
安全性分析:雖然Origin字段的設計非常簡單,但是用它來防御CSRF攻擊可以起到很好的作用。
1、去掉Origin字段。由於支持這種方法的瀏覽器在每次POST請求的時候都會帶上源header,那么網站就可以通過查看是否存在這種Origin字段來確定請求是否是由支持這種方法的瀏覽器發起的。這種設計能有效防止攻擊者將一個支持這種方法的瀏覽器改變成不支持這種方法的瀏覽器,因為即使你改變瀏覽器去掉了Origin字段,Origin字段還是存在,只不過值變為空了。這跟Referer很不一樣,因為Referer 只要是在請求里去掉了,那服務器就探測不到了。
2、DNS重新綁定。在現有的瀏覽器里面,對於同站的XMLHttpRequests,Origin字段可以被偽造。只依賴網絡連接進行身份驗證的網站應當使用在第2章里提到的DNS重新綁定的方法,比如驗證header里的Host字段。在使用Origin字段來防御CSRF攻擊的時候,也需要用到DNS重新綁定的方法,他們是相輔相成的。當然對於在第四章里提到的CSRF防御方法,也需要用到DNS重新綁定的方法。
3、插件。如果網站根據crossdomain.xml准備接受一個跨站HTTP請求的時候,攻擊者可以在請求里用Flash Player來設置Origin字段。在處理跨站請求的時候,token驗證的方法處理的不好,因為token會暴露。為了應對這些攻擊,網站不應當接受不可信來源的跨站請求。
4、應用。Origin字段跟以下四個用來確定請求來源的建議非常類似。Origin字段以下四個建議的基礎上統一並改進了,目前已經有幾個組織采用了Origin字段的方法建議
$allow_origin = array( 'http://zbvd.com', 'http://sc.com',//將商城域名配置到此處跨域處理 'http://svideo.55jimu.com', ); if(isset($_SERVER['HTTP_ORIGIN']) && in_array($_SERVER['HTTP_ORIGIN'], $allow_origin)){ // 指定允許其他域名訪問 header('Access-Control-Allow-Origin:'.$_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Credentials:true'); // 響應類型 header('Access-Control-Allow-Methods:POST'); // 響應頭設置 header('Access-Control-Allow-Headers:x-requested-with,content-type'); }
