一、背景說明
昨天領導要求給研發提個單,要求加上X-Frame-Options頭,和他說這個頭部之前客戶已經要求加過了,順帶說了這東西就是為了防范攻擊者通過iframe等引用頁面進行點擊劫持用的。
后來他又詢問說通過iframe引入后是不是用戶在iframe中的輸入及操作的響應結果是否iframe外層都能通過js直接或取到,因為從消息流向來說,消息肯定是先到達瀏覽器再傳到web頁面再傳到web頁面內的iframe;然后他又從另一個角度問,iframe內外層是不同的網站,擴展到網絡上,是不是A站的js也可以請求B站的接口?如果是,那這叫什么同源?
對於前一個問題,沒仔細探究過只好回答說你按客戶端編程的思路來說外層確實可以獲取流向內層的數據,我只能說我的經驗和我看的書都告訴我由於同源策略外層不能訪問內層的數據內層也不能訪問外層的數據,你要問原理我就說不上來。對於后一個問題,后來想了想這就是之前討論過的跨域請的問題了,服務端通過瀏覽器提交的Origin頭決定是否進行響應,瀏覽器通過服務端返回的Access-Control-Allow-Origin頭決定是否進行解析。
二、同源策略
2.1 同源的含義
“同源”這個詞最開始在哪看到已經不太記得了,但這個詞從一開始就覺得很好理解:同IP同端口就是同源,反之就不同源。
現在看網上說,同協議同域名同端口就是同源。由於CDN等機制用域名訪問一個網站並不一定總是一個IP,所以域名+端口這個說法確實更嚴謹一些。至於同域名/同IP難道還有不同協議這個問題,就要說遠一些,最近自己經常說滲透測試的第一步是威脅建模所謂威脅建模就是看系統開放了什么端口各端口下面使用了哪些協議,上周也和一個朋友這樣說她突然問一個端口下會有多套不同的協議嗎然后又接着自己答這種情況應該比較少吧。回頭仔細想自己一個端口下可有多套協議的認知,大概來源於公司產品的私有協議端口既可傳輸控制請求也可傳輸視頻流數據;從原理上而言,一個端口實現多套協議,重點在於數據包協議類型判斷上,只要判斷接收到的數據包類型然后轉發到相應的進程上處理就可以了;從實踐上看,SSLH等就可以實現多套協議只開一個端口。即總的而言,首先一個端口多套協議是有可能的----但確實這種場景比較少;然后我並不確定瀏覽器是否會將同域名/IP同端口不同協議視為不同源,只能說直覺上同協議也是一項標准確實更准確一些。
2.2 同源策略的含義
如前面所說,總的而言“同源”還是比較好理解的,但同源策略具體是什么呢?或者說同源又怎樣不同源又怎樣?總的而言有以下三點限制:
一是來自一個源的js只能讀寫自己源的存儲不能讀寫其他源的存儲,存儲包括Cookie、Session Storage、Local Storage、Cache、Indexed DB等。
二是來自一個源的js只能讀寫自己源的DOM樹不能讀取其他源的DOM樹。即如果開始討論,iframe內外層不同源就不能相互操作,外層想獲取內層的內容只能使用點擊劫持配合;實現原理亦如前所述未知。
三是一般而言來自一個源的js只能向自己源的接口發送請求不能向其他源的接口發送請求。當然其實本質是,一方面瀏覽器發現一個源的js向其他源的接口發送請求時會自動帶上Origin頭標識來自的源,讓服務器能通過Origin判斷要不要向應;另一方面,瀏覽器在接收到響應后如果沒有發現Access-Control-Allow-Origin允許發送請求的域進行請求那也不允許解析。自己之前也抱怨過,又不是服務器不響應服務器響應了不瀏覽器不(允許js)解析是不是沒什么意義的多此一舉;現在看來,通過自己寫python等方法也確實能請求其他服務器並解析其結果,瀏覽器沒有Access-Control-Allow-Origin允許不解析一是說維護了自己同源策略的思想二是說至少可以保證不會在自己身上出現A域可隨便探測B域的情況,所以也不能說完全沒用。
四是來自一個源的js不能隨意操作瀏覽器之外的資源。比如打開命令提示符、執行系統命令等等。倘若你訪問一個網站該網站的js可以直接調用系統命令給你電腦進行添加用戶等操作,那問題就大了。
2.3 同源策略說明
不是說來自A域的js不能操作B域嗎,那我們經常通過<script>標簽從別的網站引入js文件然后用來操作自己網站的內容,這不是明顯不符合同源策略嗎?
對於這個問題,個人是這樣考慮,從其他網站引入的js文件並沒有直接操作本網站的內容,而是需要本網站上寫js調用js文件中的函數引入的js文件才能起作用;所以應該理解為還是本站的js操作本站的內容,至少是本站的js主動要求其他站的js處理本站的內容。
參考:
http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html