跳到內容

OAuth 攻擊者模型

RFC 9700§3 定義了一套正式的攻擊者模型,作為所有安全建議的共同基礎。

安全建議不能只列清單,還必須說明「針對什麼攻擊者」。

在 OAuth 流程中,一個 Access Token 可能跨越多個環節傳遞——從 Client 發出授權請求、Authorization Server 核發 Token,到 Client 持 Token 存取 Resource Server。每個環節的威脅情境都不同,沒有精確的威脅描述,就無法回答:

  • 為什麼一定要用 HTTPS?
  • 為什麼不能把 Token 放在 URL fragment 裡?
  • 為什麼要做 PKCE
  • 為什麼 sender-constraining 可以降低洩漏後的損害?

透過定義五種能力各異的攻擊者類型,RFC 9700 讓每條安全建議都能對應到具體威脅,而不只是「安全最佳實踐」的籠統說法。

最基本的攻擊者模型。A1 可以:

  • 架設任意的惡意伺服器與網站
  • 誘導或欺騙使用者造訪惡意連結
  • 接收被導向至其伺服器的請求與回應

能力邊界:只能控制自己的伺服器,無法攔截或修改他人的網路流量。

典型攻擊場景:利用 redirect URI 驗證不嚴謹,讓 Authorization Server 將授權碼導向攻擊者的惡意伺服器;或透過開放式重新導向(open redirector)達到相同效果。

對應防護:Redirect URI 精確比對、禁止 open redirector


A2:中間人攻擊者(Network / MitM Attacker)

Section titled “A2:中間人攻擊者(Network / MitM Attacker)”

在 A1 的基礎上,A2 還可以:

  • 竊聽未加密或弱加密的網路通訊
  • 竄改傳輸中的 HTTP 請求與回應
  • 降級 HTTPS 連線(若 Authorization Server 未啟用 HSTS)

能力邊界:只能攔截未受 TLS 保護、或 TLS 設定不當的流量。

典型攻擊場景:在公共 Wi-Fi 上竊聽明文傳輸的 Token;透過 SSL stripping 攻擊將 HTTPS 降級為 HTTP 後讀取 Token。

sequenceDiagram
    participant Client
    participant 攻擊者 A2
    participant Authorization Server
    Client ->> 攻擊者 A2: HTTP 明文請求(帶 Token)
    攻擊者 A2 ->> Authorization Server: 轉發(並竊取 Token)

對應防護:強制 TLS、Authorization Server 啟用 HSTS


A3:授權回應讀取者(Authorization Response Reader)

Section titled “A3:授權回應讀取者(Authorization Response Reader)”

A3 可以讀取(但不能修改)授權回應的內容,包括:

  • 跳轉 URL 的 query string 或 fragment(?code=...#token=...
  • 瀏覽器自動附帶的 Referer Header(可能洩漏含有授權碼的前一頁 URL)
  • 瀏覽器歷史記錄、代理伺服器 log 中留存的跳轉網址

能力邊界:不需要控制網路流量,只需要能「看到」授權回應。這使 A3 的威脅更廣——許多非攻擊性的基礎設施(日誌系統、第三方 JavaScript、瀏覽器外掛)都可能成為洩漏管道。

典型攻擊場景

  • 同源的惡意 JavaScript 讀取 URL fragment 中的 Token(Implicit Flow 的核心問題)
  • 含有授權碼的跳轉 URL 透過 Referer Header 洩漏給頁面中的第三方資源

對應防護:廢除 Implicit Flow(避免 Token 出現在 URL 中);使用 PKCE,即使授權碼被讀取也無法兌換 Token


A4:授權請求讀取者(Authorization Request Reader)

Section titled “A4:授權請求讀取者(Authorization Request Reader)”

A4 可以讀取(但不能修改)授權請求的內容,包括:

  • 授權請求 URL 中的參數(client_idscoperedirect_uri 等)
  • PKCE 的 code_challenge(公開附在授權請求中的雜湊值)

能力邊界:只能「看到」請求,不能竄改。A4 的主要意義是確認 PKCE 的設計是否能在 code_challenge 公開的情況下仍然安全。

典型攻擊場景:攻擊者取得 code_challenge 後,嘗試逆推 code_verifier,以便在攔截到授權碼後自行換取 Token。

對應防護PKCE 使用 S256 方法(SHA-256 單向雜湊),從 code_challenge 在計算上無法還原 code_verifier


A5 能夠透過各種手段取得已核發的 Access Token,例如:

  • 利用 A1~A4 的任意組合竊取 Token
  • 入侵 Resource Server、日誌系統或監控平台
  • 利用 Client 端儲存 Token 的漏洞(如 localStorage 的 XSS 風險)

能力邊界:A5 代表的是「Token 已經洩漏」這個事實,而不是特定的攻擊手法。它的存在承認了現實:即使前四種攻擊者的威脅都已妥善防禦,Token 仍可能因為其他意外或設定錯誤而洩漏。

典型攻擊場景

  • 伺服器日誌意外記錄了 Bearer Token
  • 第三方依賴套件的 XSS 漏洞導致 Token 從 localStorage 洩漏
  • 遭入侵的 Resource Server 中留存的有效 Token

對應防護:sender-constraining(DPoPMutual TLS)——即使 Token 已洩漏,沒有對應的金鑰就無法使用

攻擊者核心能力典型威脅主要防護
A1 網路攻擊者架惡意站、誘導點擊竊取被錯誤導向的授權碼Redirect URI 精確比對、禁止 open redirector
A2 中間人攻擊者竊聽與竄改明文流量攔截 Token 或竄改回應強制 TLS、HSTS
A3 授權回應讀取者讀取授權回應內容從 URL、Referer 洩漏授權碼或 Token廢除 Implicit Flow、PKCE
A4 授權請求讀取者讀取授權請求內容嘗試逆推 code_verifierPKCE S256
A5 Token 取得者取得已核發的 Token任何管道的 Token 洩漏Sender-constraining(DPoP / mTLS)

這五種攻擊者不是從低到高的等級制,而是能力維度不同的獨立威脅類型:

  • A3 不需要 A1 的能力(不需要自架惡意站,只要能讀到授權回應就夠了)
  • A4 不需要 A3 的能力(只讀請求,不讀回應)
  • 真實的攻擊者可能同時具備多種類型的能力

實作時要思考的不是「這個攻擊者能做什麼」,而是「我的系統在哪個假設被違反時會失守」。

RFC 9700 明確說明,如果攻擊者入侵了 Client 本身(取得了 Client 的私鑰或 credentials),這已超出威脅模型的範圍——OAuth 協定本身無法防禦。

這設定了一個重要前提:OAuth 的安全假設 Client 的實作是可信的。保護 Client 端的安全(例如金鑰管理、程式碼安全)是另一個層次的課題。