OAuth 2.0 Security Best Current Practice
RFC 9700 是 OAuth 2.0 的安全最佳實踐指南,於 2025 年 1 月正式發布。它的前身是 2013 年的 RFC 6819,但 RFC 9700 大幅更新了威脅模型,並將過去十年在實作與部署中發現的安全問題系統化整理成規範。
RFC 9700 本身不定義新的協定機制,而是明確哪些做法是必須的(MUST)、哪些是建議的(SHOULD),以及哪些已不應再使用(MUST NOT)。
RFC 9700 在 §3 定義了五種攻擊者類型,用來描述安全建議所針對的威脅情境:
| 類型 | 能力描述 |
|---|---|
| A1 網路攻擊者 | 可架設任意伺服器、誘導使用者造訪惡意連結 |
| A2 中間人攻擊者 | 除 A1 外,還可竊聽與竄改未加密的網路流量 |
| A3 授權回應讀取者 | 可讀取(但不能修改)授權回應的內容 |
| A4 授權請求讀取者 | 可讀取(但不能修改)授權請求的內容 |
| A5 Token 取得者 | 可透過各種手段取得已核發的 Access Token |
重點安全建議
Section titled “重點安全建議”Redirect URI 驗證
Section titled “Redirect URI 驗證”Authorization Server 在比對 redirect URI 時,必須使用完全字串比對(exact string matching),不得使用前綴比對、萬用字元或正規表達式。唯一的例外是 localhost 的埠號可以不比對,以方便原生應用開發。
不嚴謹的 redirect URI 驗證是 OAuth 攻擊中最常見的漏洞來源之一,攻擊者可藉此將授權碼或 Token 導向惡意端點。
此外,Authorization Server 與 Client 不得提供任何開放式重新導向(open redirector)端點。
PKCE 與授權碼注入防護
Section titled “PKCE 與授權碼注入防護”§2.1.1 明確要求:
- Public Client 必須使用 PKCE,以防止授權碼注入攻擊
- Confidential Client 建議使用 PKCE,OpenID Connect 的
nonce參數亦可作為替代方案 - Authorization Server 必須支援 PKCE,且必須防止 PKCE downgrade 攻擊(即攻擊者移除
code_challenge參數以繞過保護)
PKCE 的 challenge 值必須針對每次授權流程單獨產生,不可重複使用。
Token 受眾限制
Section titled “Token 受眾限制”§2.3 建議對 Access Token 的使用範圍加以限制:
- Access Token 應限定給特定的 Resource Server(audience restriction)
- Access Token 應進一步限定可執行的資源與操作
- 遵循最小權限原則,只授予本次請求所需的最低 scope
這些措施可以降低 Token 洩漏或被盜用後的損害範圍。
Sender-Constraining(Token 綁定)
Section titled “Sender-Constraining(Token 綁定)”§2.2 建議將 Token 綁定到特定的 Client,使竊取的 Token 無法被其他人使用:
- Access Token:建議使用 sender-constraining 機制(如 DPoP 或 Mutual TLS)
- Refresh Token:Public Client 的 Refresh Token 必須使用 sender-constraining 或 refresh token rotation 其中一種機制
Client 認證
Section titled “Client 認證”§2.5 建議:
- Authorization Server 應在可行的情況下強制 Client 進行認證
- 建議使用非對稱加密(asymmetric cryptography)進行 Client 認證,例如 private key JWT,而非共享的 client secret
Client secret 容易在原始碼、日誌或設定檔中洩漏;非對稱金鑰只需保管私鑰,安全性更高。
Refresh Token 保護
Section titled “Refresh Token 保護”Refresh Token 的有效期較長,一旦洩漏影響範圍更大。除了前述的 sender-constraining 外,§2.2.2 建議:
- 對 Public Client 使用 Refresh Token rotation:每次使用 Refresh Token 換發新 Token 時,同時核發新的 Refresh Token 並作廢舊的
- 若偵測到同一個 Refresh Token 被使用超過一次,應視為可能的 Token 竊取,立即撤銷所有相關 Token
廢棄的授權流程
Section titled “廢棄的授權流程”- Implicit Grant(
response_type=token):Access Token 直接暴露於瀏覽器的 URL fragment,容易被竊取,應改用 Authorization Code + PKCE - Resource Owner Password Credentials(ROPC):要求使用者直接將帳號密碼交給 Client,根本上違反 OAuth 的委派授權設計,禁止使用