JWT 安全全解析:最佳實踐與常見漏洞
JSON Web Token(JWT)因能在不依賴集中式 session 儲存的前提下驗證請求,被廣泛用於驗證與授權。本指南以實務角度說明 JWT 安全,涵蓋運作原理、常見漏洞與可在正式環境落地的最佳實踐。
驗證是現代軟體的核心。每當有人登入、呼叫 API,或在應用程式中執行操作時,系統都必須確認他的身分,以及他被允許做什麼。在多個服務彼此溝通的分散式系統中,這件事還必須同時做到快速、穩定且安全。
JSON Web Token(JWT)因可讓系統在不依賴集中式 session 儲存的情況下驗證請求,而被廣泛用於驗證與授權。它在 API、微服務、行動應用,以及單一登入(SSO)場景都很常見。
然而,JWT 在提升效能與可擴展性的同時,也帶來了安全責任。實務上的大多數問題並不是 JWT 規格有缺陷,而是因為實作方式不正確,或缺少必要防護。
本指南會用清楚、實用的方式說明 JWT 安全:它如何運作、為什麼重要、有哪些風險,以及如何在正式環境安全使用。
為什麼 JWT 安全很重要
在傳統 Web 應用中,驗證通常依賴伺服器端 session。伺服器會儲存 session 資料,並在每次請求到來時進行查詢。這在簡單架構中運作良好,但當系統擴展、跨區域部署、或拆分為多服務時,擴展難度就會提高。
JWT 透過把身分資訊放入 token 本身來解決這個問題。每個服務都能獨立驗證 token,不需要每次都查中央資料庫。這能提升效能、降低延遲,並簡化擴展。
但這種設計也改變了安全模型。token 一旦發出:
- 它就等同於身分憑證
- 任何信任該簽發者的系統都可能接受它
- 任何持有 token 的人都可以使用它
如果 token 外洩、被複製或被偽造,在它過期或被撤銷之前,都可能導致未授權存取。因此,保護 JWT 的重要性等同保護密碼或 API 金鑰。
JWT 是什麼?
JSON Web Token 是一種緊湊字串格式,用於在系統間安全傳遞資訊。它由三個以點號分隔的部分組成:
- Header:包含簽章演算法等中繼資料
- Payload:包含 claims(例如使用者 ID 或角色)
- Signature:用來驗證 token 的真實性與完整性
典型 token 長相如下:
xxxxx.yyyyy.zzzzz
每個部分都經過 Base64Url 編碼。以下是 JWT 解碼後的 header 與 payload 範例:
`// Header { “alg”: “RS256”, “typ”: “JWT” }
// Payload { “sub”: “user_123”, “iss”: “https://auth.example.com”, “aud”: “https://api.example.com”, “exp”: 1740000000, “iat”: 1739996400 } `
簽章的作用是確保 token 未被竄改。伺服器收到 JWT 後,必須先驗證簽章,再信任 payload。若簽章無效,token 必須被拒絕。
JWT 通常在登入成功後簽發。客戶端不需反覆傳送帳密,而是每次請求都附帶 token。伺服器驗證 token 合法後才授權存取。
JWT 驗證如何運作
- 使用者以憑證登入
- 伺服器驗證憑證
- 伺服器產生並簽署 token
- 客戶端儲存 token
- 客戶端在每次請求附帶 token
- 伺服器驗證 token
token 一旦簽發,就成為使用者的身分憑證。這代表安全性高度仰賴 token 的簽發、驗證、儲存與傳輸方式。
JWT 系統的核心安全要求
安全的 JWT 實作至少要滿足以下要求:
- token 必須無法被偽造
- 簽章必須被正確驗證
- 過期 token 必須被拒絕
- token 只能被目標系統接受
- token 在儲存與傳輸中都必須受保護
- token 一旦遭竊必須可撤銷
以上是 token 型驗證的最低安全基準。只要忽略其中任一項,就算 token 格式正確,仍可能出現漏洞。
常見 JWT 漏洞
大多數 JWT 安全事件都來自實作錯誤。理解這些風險,能幫助團隊從一開始就設計更安全的系統。
演算法設定錯誤
JWT header 會標示用來簽章的演算法。若系統接受了非預期或不安全的演算法,攻擊者可能操控 token。
最著名案例之一是接受 "none" 演算法。這代表 token 沒有簽章。若驗證邏輯仍接受這類 token,攻擊者就可任意偽造內容。
簽章金鑰過弱
使用弱祕密簽署 token,可能被暴力破解或猜測。一旦攻擊者取得金鑰,就能替任意使用者簽發有效 token。
弱金鑰常見來源:
- 簡單密碼
- 過短字串
- 重複使用測試金鑰
- 將祕密硬編碼在程式碼中
強密碼學金鑰是避免偽造的必要條件。
缺少 claims 驗證
JWT payload 內包含可驗證上下文的標準 claims,常見如:
- 過期時間(
exp) - 簽發者(
iss) - 受眾(
aud)
若系統不檢查這些欄位,就可能接受已過期、來源不明、或本來簽給其他服務的 token。
token 存活時間過長
長效 token 會放大風險。一旦 token 被竊,攻擊者可持續使用到過期。縮短有效期能直接縮小攻擊窗口。
不安全的儲存方式
token 若儲存在不安全位置,容易被竊取,例如:
- 可被腳本讀取的瀏覽器 local storage
- 把 Authorization header 打進日誌
- 在 URL 參數中傳遞 token
攻擊者取得 token 後,就可冒用使用者身分。
缺少撤銷策略
JWT 是無狀態機制,伺服器不會自動追蹤已簽發 token。若沒有撤銷機制,token 會一路有效到過期,即使:
- 使用者已登出
- 使用者憑證已變更
- 帳號已疑似遭入侵
處理敏感資料的系統必須具備失效 token 的方法。
payload 放入敏感資料
JWT payload 是「編碼」不是「加密」。任何人拿到 token 都能解碼。若把敏感資訊放進 payload,就等於曝光給任何取得 token 的人。payload 只應放可被公開閱讀的最小必要資訊。
JWT 安全最佳實務
遵循成熟的最佳實務,可避免多數 JWT 漏洞。以下建議在正式環境中被廣泛採用。
嚴格限制允許演算法
驗證邏輯應只接受明確核准的演算法。任何非預期演算法都要立即拒絕。明確 allowlist 可防止 header 被操控。
使用強簽章金鑰
簽章金鑰應:
- 足夠長
- 足夠隨機
- 由安全方式產生
且不應直接儲存在程式碼內,應使用安全設定系統或 secret manager。
完整驗證每個 claim
每個 token 都應至少驗證:
- 簽章合法性
- 過期時間
- 簽發者身分
- 受眾值
略過任一步驟都是常見安全漏洞來源。
縮短 token 有效期
短效 token 可降低遭竊時的曝險時間。許多系統會採用雙 token 策略:
- Access token:短時效(例如 15 到 60 分鐘)
- Refresh token:較長時效(例如數天到數週)
這能在安全與使用便利間取得平衡。
全程使用 HTTPS
token 傳輸必須透過加密連線。若在未加密網路傳輸,攻擊者可直接攔截。傳輸加密是最低要求。
安全儲存 token
不同平台的建議儲存方式如下:
- Web 應用:
HttpOnlycookie - 行動應用:裝置安全儲存
- 伺服器:記憶體或受保護儲存區
避免把 token 放在腳本或未授權程序可讀取的位置。
規劃撤銷機制
即使是無狀態驗證,也要有撤銷策略。常見做法包括:
- token 黑名單
- token 版本號
- 簽章金鑰輪替
當需要立即回收存取權時,撤銷機制就是關鍵。
避免在 payload 放敏感資料
只放最小必要身分資訊。不要放密碼、祕密、或個資。token 越精簡,外洩後影響越小。
對稱 vs 非對稱簽章
JWT 主要有兩種簽章方式,選擇會影響安全性與可擴展性。
對稱簽章
使用同一把祕密金鑰進行簽章與驗證。
優點:
- 設定簡單
- 效能快速
限制:
- 祕密金鑰必須安全共享
- 多服務環境下較難管理
非對稱簽章
以私鑰簽章、公開金鑰驗證。
優點:
- 更適合分散式系統
- 不需共享簽章祕密
- 金鑰輪替更容易
限制:
- 設定略為複雜
在多服務環境中,非對稱簽章通常更受偏好,因為能降低簽章金鑰暴露面。
可觀測性收益
JWT 也能強化系統可觀測性。若設計得當,工程團隊可藉此:
- 追蹤跨服務請求
- 關聯不同來源日誌
- 辨識異常存取模式
- 更快定位驗證失敗原因
token 不一定只是黑盒憑證,也可成為營運診斷工具。
何時適合 JWT
JWT 特別適合以下需求:
- 無狀態驗證
- 水平擴展
- 分散式服務
- 跨平台客戶端
何時 JWT 未必最適合
JWT 並不總是最佳選擇。以下情境可考慮傳統 session:
- 需要立即撤銷權限
- 需要高度集中控制
- 安全政策要求伺服器追蹤完整狀態
- token 大小需要極小化
是否採用 JWT,應是基於系統需求做出的架構決策。
如何設計安全的 JWT 系統
打造安全 JWT 系統,不只是會簽 token 而已;它牽涉架構、基礎設施與營運決策。
團隊應提早評估:
- 威脅模型
- 法規與合規要求
- 基礎設施規模
- 營運成熟度
越早處理這些問題,驗證系統越能在成長後保持可靠與安全。
JWT 安全實作檢查清單
可用以下清單快速確認系統是否符合最佳實務:
- 使用強簽章金鑰
- 嚴格限制允許演算法
- 完整驗證 claims
- token 有短時效
- token 儲存安全
- payload 不含敏感資料
- 支援 token 撤銷
- 定期金鑰輪替
符合以上條件的系統,發生 token 相關安全事件的機率會顯著降低。
結語
JWT 在現代驗證架構中扮演重要角色。它能支援可擴展的身分驗證、降低伺服器對 session 儲存的依賴,並在分散式環境高效運作。只要實作正確,JWT 能在效能與安全間取得穩健平衡。
大多數 JWT 風險並非來自技術本身,而是來自實作落差,例如驗證不足、儲存不當、或 token 壽命過長。採用強簽章方法、嚴格驗證 token,並執行明確過期政策,能有效降低風險。
把 JWT 安全視為架構層決策,能讓驗證系統在規模成長下仍維持穩定、可擴展與安全。
若你的團隊想更有把握地導入 JWT,Authgear 提供實用的驗證工具,可協助簡化 token 管理、強化驗證流程,並從一開始就建立可上線的身分系統。
探索 Authgear 的 JWT 工具,可用於產生安全 token、正確驗證簽章,並建置能安全擴展的驗證流程。
FAQs
JWT 最大的安全風險是什麼?
最常見風險是驗證不完整。若系統沒有驗簽、檢查過期時間、或核對簽發者,可能會接受偽造或過期 token,導致未授權存取。
JWT 預設就安全嗎?
JWT 在正確實作下是安全的。安全性取決於金鑰強度、驗證完整性、儲存方式與設定是否正確。實作不當才會引入漏洞。
JWT 一定要加密嗎?
只有在 token 內必須放入敏感資料時才需要加密。多數系統更好的做法是根本不要把機密資訊放進 token payload。
金鑰多久輪替一次?
應依組織安全政策與風險等級定期輪替。輪替可限制金鑰外洩時的衝擊,是標準最佳實踐。