網站安全🔒 Same Origin Policy 同源政策 ! 一切安全的基礎

Jayden Lin
程式猿吃香蕉
Published in
12 min readJul 1, 2018

筆者任職 Yahoo ,《經典駭客攻擊教程:給每個人的網站安全入門》線上課程講師 ,粉絲團《程式猿吃香蕉🍌

有一句俗語是這樣說的,「自己家的小孩要自己打」,在網路世界也類似的概念存在,自己網站的資源不能隨便被其他人存取/修改。為了方便讀者理解,本文會以「外星人殖民地球」譬喻的方式來說明同源政策。

這種概念,就是今天所要介紹的「同源政策」(Same Origin Policy)。

網站的資源 ?

那麼,什麼是「網站的資源」呢?舉例來說,當你開啟一個網頁,看到豐富的網頁內容。這是因為瀏覽器會下載來自不同來源的圖片、影片、以及程式碼下來執行。

這些「圖片」、「影片」、以及「程式碼」等等,即是網站的資源(resource)

舉一個更有趣的例子,我們將「瀏覽網頁」比喻成「外星人殖民地球」,如下圖,左邊是「外星人殖民地球」右邊是對應的「瀏覽網頁」情況:

將「瀏覽網頁」比喻成「外星人殖民地球」,外星人「母船」就有如網站主機提供的「網路服務」,「瀏覽器網頁」就有如「地球」

外星人「母船」就有如你的網站主機提供的「網路服務」,你的「瀏覽器網頁」就有如「地球」。

而上圖的「火星人車輛」、「火星人」、「火星人食物」等等,對應到網路世界就是資源 (resource)。由「母船」提供源源不絕的資源,而某些特定的資源,還可以再呼叫母船,請求提供更多資源

在網路世界中,便是由「網路服務」提供許多資源到瀏覽器網頁中。而某些特定的資源(例如:程式碼),可以再次呼叫網路服務,請求提供更多資源。

同源政策 (Same Origin Policy) 的概念

將「瀏覽網頁」比喻成「外星人殖民地球」,外星人「母船」就有如網站主機提供的「網路服務」,「瀏覽器網頁」就有如「地球」

就有如「木星人」不能呼叫「火星人母船」來支援一樣.來自「搞笑圖片網站」的程式碼也不能任意呼叫「遊戲網站網路服務」。因為這樣子的存取會被網站視為「跨來源」的存取,如上圖所示。

基本上, 「同源政策」(Same Origin Policy) 的觀念即為:

「同源」的資源才可相互存取,跨來源的資源則必須在某些特定情況下,才允許存取。

這樣的設計是為了防範駭客的攻擊,因為有了這個限制,在正常的情況下,駭客就不能夠任意用一個惡意的網站,去呼叫 facebook 的網路服務。

萬一沒有這層防護,壞人就可以任意觸發 facebook 的網路服務裡的刪除留言或是新增留言,在你的 facebook 頁面搞破壞了。

「同源政策」(Same Origin Policy) 是網站安全的基礎,又分為兩種(註1.):

  • DOM 的同源政策
  • Cookie 的同源政策

以下就這兩種不同的類型進行說明,詳細定義在什麼情況下,資源之間會被視為「同源」。

DOM 的同源政策

1. 同源的定義

無論是圖片,影片或是程式碼等資源,最終被載入瀏覽器中,會變成 DOM的元素。

以先前的譬喻來說:將「瀏覽網頁」比喻成「外星人殖民地球」,外星人「母船」就有如你的網站主機提供的「網路服務」,你的「瀏覽器網頁」就有如「地球」,如下圖,左邊是「外星人殖民地球」右邊是對應的「瀏覽網頁」情況:

將「瀏覽網頁」比喻成「外星人殖民地球」,外星人「母船」就有如網站主機提供的「網路服務」,「瀏覽器網頁」就有如「地球」

你可以把這些 DOM 元素當作「火星人」、「火星車輛」、和「火星食物」,這些資源他們的「來源」都是來自「火星母船」

對於這些資源來說,怎麼樣的情況下才是屬於「同源」呢?

同理,我們要怎麼判斷網站資源中的「圖片」、「影片」、和「程式碼」是屬於「同源」呢?

以下為網站用來判定資源是否「同源」的要素,如下圖所示:

DOM 的同源政策 (Same Origin Policy) 示意圖

對 DOM 的同源政策來說,只要 Scheme、Domain 跟 Port 一致的資源,就會被視為同源

以下為一個範例,比較表格內的「資源」,來看是否與下列「HTML檔案」同源:

http://login.game.com/dir/page.html

2. 限定的行為

然而, 「同源政策」(Same Origin Policy) 的規定並不是完全地限制跨來源的存取.在某些情況下是允許的.以下就幾種常見的情況進行說明 (註2.).

(1) 跨來源寫入通常被允許

例如:連結 (links) 、重新導向 (redirect) 、或是表單 (form) 送出等等,是被允許的。這邊要注意的是,跨來源的寫入若是透過 JavaScript 程式碼,例如:XMLHttpRequest 或是 Fetch API是無法跨來源寫入的。

以「瀏覽網頁」比喻成「外星人殖民地球」的方式來說,雖然正常情況下的「木星人」無法「跨來源」呼叫火星母船的資源。但有一種「特殊木星人」是允許這樣做的,如下圖所示。

將「瀏覽網頁」比喻成「外星人殖民地球」,外星人「母船」就有如網站主機提供的「網路服務」,「瀏覽器網頁」就有如「地球」

(2) 跨來源嵌入通常被允許

例如:JavaScript 程式碼<script src="..."></script>、圖片<img>、影片<video>、CSS 樣式表 <link rel="stylesheet" href="..."><frame>以及<iframe>等等,通常被允許。

以「瀏覽網頁」比喻成「外星人殖民地球」的方式來說,有某種「特殊木星車輛」,可以嵌入「火星人大砲」做使用。如下圖所示,搞笑圖片網站的網頁,可以透過 iframe 的方式,嵌入遊戲網站的「遊戲購買頁」。

將「瀏覽網頁」比喻成「外星人殖民地球」,外星人「母船」就有如網站主機提供的「網路服務」,「瀏覽器網頁」就有如「地球」

(3) 跨來源讀取通常不被允許

例如: XMLHttpRequest 或是 Fetch API

這邊要注意的是,跨來源嵌入的內容,會直接顯示在瀏覽器中,但其內容是通常無法被 JavaScript 程式碼「讀取」的。如下圖所示,例如你要用 JavaScript 爬出遊戲購買頁的產品跟價錢等等內容,是無法讀出來的。

以「瀏覽網頁」比喻成「外星人殖民地球」的方式來說,有某種「特殊木星車輛」,雖然可以嵌入「火星人大砲」做使用,但是「火星人大砲」的構成零件,無法被其他「木星人」窺探。

將「瀏覽網頁」比喻成「外星人殖民地球」,外星人「母船」就有如網站主機提供的「網路服務」,「瀏覽器網頁」就有如「地球」

由上述的多個例子,我們可以發現:

「同源政策」(Same Origin Policy) 允許對於 HTML tag 產生的 跨來源寫入/嵌入/讀取,但對於JavaScript 程式碼 產生的 跨來源寫入/嵌入/讀取是有限制的

3. 對 Cookie 存取的怪設計

「同源政策」(Same Origin Policy) 對於「同源」的判定我們可以知道,即使是母網域與子網域也是會被視為跨來源的通訊,而被禁止。在其他類型資源的存取上,確實會被禁止。但對於 Cookie 的存取,出現了例外!

將「瀏覽網頁」比喻成「外星人殖民地球」,外星人「母船」就有如網站主機提供的「網路服務」,「瀏覽器網頁」就有如「地球」

Cookie的同源政策是允許子網域的程式碼修改/覆蓋母網域的 Cookie!

什麼是 Cookie 呢?在本篇文不特別做探討,可以將 Cookie 也視為一種「資源」,以「瀏覽網頁」比喻成「外星人殖民地球」的方式來說,可以根據該 Cookie 的來源當成 「火星母船食物」或是「火星子船食物」,如下圖所示:

將「瀏覽網頁」比喻成「外星人殖民地球」,外星人「母船」「子船」就有如網站主機提供的「網路服務」,「瀏覽器網頁」就有如「地球」

子網域的 JavaScript 程式碼可以修改/覆蓋母網域的 Cookie

就有如,來自火星子船的人可以處理火星母船的食物。這樣的做法的危險之處,在於火星子船的人可以處理火星母船的食物後,火星母船的人有可能再將這些食物拿去使用,造成安全性的疑慮

子網域修改過的 Cookie,會被母網域不知情地拿去使用,萬一子網域被駭客攻陷,那麼母網域的 Cookie 也會被惡意破壞

Cookie 的同源政策

1. 同源的定義

以「瀏覽網頁」比喻成「外星人殖民地球」的方式來說,相較於 DOM 的同源政策是限制對母船的呼叫,Cookie 的同源政策是限制 Cookie 這項資源回傳給母船的規範

將「瀏覽網頁」比喻成「外星人殖民地球」,外星人「母船」就有如網站主機提供的「網路服務」,「瀏覽器網頁」就有如「地球」

如上圖所示,我們已知「火星人食物」是不能回傳到「木星母船」的,應該被視為跨來源那麽問題來了,我們要怎麼分辨食物是屬於火星人還是木星人的呢 ?

同理,我們要怎麼知道 Cookie 的來源是哪裡呢?是屬於「遊戲網站」來的Cookie 還是屬於「搞笑網站」的Cookie 呢 ?

以下是用來判定 Cookie 是否「同源」的要素:

Cookie 的同源政策 (Same Origin Policy) 示意圖

只要連上的網站其 Domain 跟 Path 與 Cookie 一致,就會被視為同源.拜訪該網站時,Cookie 就會被送出。若是 Cookie 有加上一些特別的設定,便需要判斷 Scheme 是 HTTPS 或是 HTTP 才會送出 Cookie。

例如: Cookie 加上 secure 設定之後,限定 Cookie 只能以 HTTPS 傳輸

2. 限定的行為

(1) 不同源的 Cookie ,在傳輸時會送到各自來源的主機

(2) 經過設定,子網域與母網域的 Cookie 可以共用

當 Cookie 的 domain 被設定為:

Set-Cookie: name=value; domain=game.com

此時的 Cookie 不會與子網域(例如:login.game.com)共用.但若是設定為:

Set-Cookie: name=value; domain=.game.com

則該 Cookie 可以在瀏覽器連上子網域時,也會一並回傳到網站主機

潛在的安全議題

  • DOM 的同源政策規範對於連結(links)、重新導向(redirect)、或是表單(form)等等的跨來源存取是寬鬆的,這樣的特性會被駭客利用在 CSRF 等類型的攻擊上
  • DOM 的同源政策並沒有限制子網域去修改或是覆蓋母網域的 Cookie

以上,便是對同源政策的說明,若是要了解更多實做的細節,例如:「簡單請求」或是「預檢請求」等等,可以參考這篇MDN的「跨來源資源共用CORS」文章(連結),文內會有細節的定義,希望對大家有幫助

參考資料

  1. Cookie Security: https://crypto.stanford.edu/cs142/lectures/10-cookie-security.pdf
  2. Same Origin Policy: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

若是喜歡我分享的內容,歡迎幫我按個拍手,可拍 50下,給我一點鼓勵,若對資訊安全有興趣,也可以參考我的線上課程《經典駭客攻擊教程:給每個人的網站安全入門》

--

--

Jayden Lin
程式猿吃香蕉

曾在 Yahoo 擔任 Lead Engineer,負責廣告系統,帶團隊做跨國開發,現任職區塊鏈產業。也是《程式猿吃香蕉》團隊創辦人,喜歡將實用的軟體知識以簡單生動的方式講給大家聽 😄😄😄