程序员应对浏览器同源策略的姿势
同源策略
瀏覽器最基本的安全規范——同源策略(Same-Origin Policy)。所謂同源是指域名、協議、端口相同。不同源的瀏覽器腳本(javascript、ActionScript、canvas)在沒明確授權的情況下,不能讀寫對方的資源。
同源策略規定了瀏覽器腳本互操作web數據的基本原則,若沒有這一基本原則,那么:
某域下DOM元素被另一方任意操作、篡改,導致頁面顯示失控
某域下的cookie等與該域相關的數據片段可以隨意讀取,導致與該域密切相關的瀏覽器cookie片段可能失真
惡意網站能隨意執行Ajax腳本偷取隱私數據,導致該域下核心業務數據被抓取。
同源策略在實施中面臨的問題
默認的同源策略 限制了腳本互操作其他域的能力,大棒一揮, 關閉了A站腳本正常訪問B站數據的需求。有以下變通方法:
實現CORS (Cross-Origin Resource Sharing)
使用JSONP (JSON Padding)
建立一個本地代理服務器,這樣先同源訪問,由代理服務器轉發請求
方案1:CORS是w3C對于跨域請求推出的明確方案;方案2、3均是Hack行為。
CORS跨域請求方案
W3C推出的跨域請求方案:讓web服務器明確授權非同源頁面腳本來訪問自身,以Response特定標頭Access-Control-*******-體現;目前現代瀏覽器均認可并支持這些標頭。
CORS特定HTTP標頭,為瀏覽器提供了授權腳本跨域訪問其他域名頁面數據的通道。
常規的帶Cookie Ajax跨域請求
const invocation = new XMLHttpRequest(); const url = 'http://bar.other/resources/credentialed-content/'; function callOtherDomain(){if(invocation) {invocation.open('GET', url, true);invocation.withCredentials = true; // Ajax請求默認不會發送憑據, 這里設定在Ajax跨域請求中發送憑據invocation.onreadystatechange = handler;invocation.send(); } }CORS規范
瀏覽器發起CORS或POST請求,瀏覽器會自動攜帶Origin標頭(指示請求來自于哪個站點)
Web服務器實現跨域訪問授權邏輯, 授權結果在Response中以Access-Control--******* 標頭體現
最常見的Access-Control-Allow-Origin標頭包含 ?* / Origin /null三種響應值;當請求是攜帶憑據的跨域請求,不可囫圇吞棗地指定為*通配符,而必須指定特定Origin
瀏覽器會遵守Access-Control--*******-- 標頭值所施加的跨域限制
以上表示了一個常見的攜帶cookie跨域Ajax Get請求,其中Access-Control-Allow-Credentials: true指示瀏覽器可以將跨域請求的Response結果暴露給頁面。
預檢Preflight
對于非簡單Ajax請求(通常是GET以外的HTTP方法,或者某些MIME類型的POST用法),CORS規范要求發起"預檢"請求。
“不過,預檢請求不需要你手動發起,瀏覽器會自動使用OPTIONS請求方法從服務器請求支持的方法,然后在服務器“批準”時,使用實際的HTTP請求方法發送實際請求。
下圖顯示 瀏覽器判斷 非簡單請求的邏輯圖:下面使用POST動作發起Ajax跨域請求,同時自定義request header:X-PINGOTHER,該請求觸發瀏覽器預檢行為
const invocation = new XMLHttpRequest(); const url = 'http://bar.other/resources/post-here/'; const body = '<?xml version="1.0"?><person><name>Arun</name></person>';function callOtherDomain(){if(invocation){invocation.open('POST', url, true);invocation.setRequestHeader('X-PINGOTHER', 'pingpong');invocation.setRequestHeader('Content-Type', 'application/xml');invocation.onreadystatechange = handler;invocation.send(body); } }程序員調試CORS的苦惱
跨域請求發生在A--->B 兩站,作為某一方開發人員,調試CORS相對麻煩。經過本StackOverFow工程師的檢索,curl 工具可優雅高效模仿Ajax跨域請求:
# http://example.com 向谷歌站點發起一個跨域Get請求 curl -H "Origin: http://example.com" --verbose \ https://www.googleapis.com/discovery/v1/apis?fields=從瀏覽器Network,將請求以cUrl格式拷貝出來,改改。
總結
瀏覽器同源策略限制對象是瀏覽器腳本;
存在跨域請求的場景,某些方案是Hack行為;
W3C推出的CORS 是標準的跨域請求方案,思路是在服務端Response標頭體現 授權, 瀏覽器遵守該授權標頭。
對于非簡單的腳本跨域請求,瀏覽器會自動發起 Option請求預檢, 大部分時候無需關注
提供curl 工具幫助高效、優雅調試CORS。
后續會聊聊瀏覽器的另一個有用的安全策略:Cookie SameSite策略,盡請關注.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
https://stackoverflow.com/questions/12173990/how-can-you-debug-a-cors-request-with-curl/12179364#12179364
https://curl.haxx.se/docs/manpage.html
推薦閱讀
●?修復搜狗、360等瀏覽器不識別SameSite=None 引起的單點登錄故障
●? MongoDB副本集自動故障轉移機制、客戶端監控
●?HTTP Strict Transport Security (HSTS) in ASP.NET Core
●?解讀docker swarm能力,實戰演練Docker Swarm集群編排
●?全網最深刻的ASP.NET Core跨平臺技術內幕
●?AspNetCore結合Redis實踐消息隊列
●?TPL Dataflow組件應對高并發,低延遲要求
????轉載是一種動力,分享是一種美德? ~~..~~
如果你覺得文章還不賴,您的鼓勵是原創干貨作者的最大動力,讓我們一起激濁揚清。
長按二維碼
關注我們
總結
以上是生活随笔為你收集整理的程序员应对浏览器同源策略的姿势的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EntityFramework Core
- 下一篇: .net core 整洁架构入门