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

Jayden Lin
Jul 1, 2018 · 11 min read

筆者目前任職於 Yahoo ,粉絲團:《Hey, 軟體知識沒有你想得那麼難》 | 線上課程:《經典駭客攻擊教程:給每個人的網站安全入門》

有一句俗語是這樣說的,「自己家的小孩要自己打」,在網路世界也類似的概念存在,自己網站的資源不能隨便被其他人存取/修改

這種概念,就是今天所要介紹的「同源政策」(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 有加上一些特別的設定,便需要判斷 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

    Written by

    Yahoo 資深軟體工程師,負責搜尋廣告系統的開發工作。曾擔任樂天市場前端開發組經理,負責從零建立樂天台灣前端開發團隊。同時也是 《Hey, 軟體知識沒有你想得那麼難》團隊創辦人,致力於提供優質的、入門的、科普性質的軟體知識給大家。

    Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
    Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
    Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade