iT邦幫忙

2025 iThome 鐵人賽

DAY 15
0

截至目前為止,關於JWT的教學我們已經完成了:

  • Day 12:用 JWT 做 Access Token 與 Spring Security 整合
  • Day 13:引入 Refresh Token
  • Day 14:黑名單與強制登出

今天,我們要進一步拉高層級,探討 JWT 的安全性問題,以及常見的防禦策略。

很多人會說「JWT 不安全」,但其實大多是「使用不當」造成的漏洞。

1. 金鑰管理(Secret / Key Management)

JWT 的安全基礎就是「簽章演算法 + 金鑰」。

  • 對稱加密 (HMAC)HS256 常見,簽發與驗證用同一把密鑰。

    風險是如果密鑰外洩,任何人都能簽 Token。

  • 非對稱加密 (RSA / ECDSA)RS256 常見,私鑰簽發,公鑰驗證。

    可以公開驗證,不怕公鑰外洩,但私鑰必須嚴格保護。

實務建議

  • 把金鑰放在 環境變數雲端 KMS(Key Management Service),不要寫死在程式碼。
  • 定期輪替金鑰。
  • 使用非對稱簽章(RS256 / ES256)會更安全,尤其是微服務架構。

2. Token 過期時間(Expiration)

JWT 最大的風險就是「一旦簽發就不可撤銷」。

所以 過期時間 (exp) 的設定非常重要。

  • Access Token:建議幾分鐘(2–15 分鐘)。
  • Refresh Token:幾天到幾週,但要搭配旋轉(Day 13 提過)。

案例

如果 Access Token 設定 7 天,那麼一旦外洩,攻擊者就有 7 天完全自由使用。

→ 所以才要搭配 Refresh Token,把 Access Token 壽命壓短。

3. 避免把敏感資訊放進 Payload

JWT Payload 是 Base64Url 編碼,不是加密。任何人拿到 Token 都能解碼看到裡面的資料。

這邊先來說明一下錯誤的作法跟建議的做法。

錯誤做法

{
  "username": "eric",
  "role": "admin",
  "creditCard": "4111-1111-1111-1111"
}

建議做法

  • 只放必要的資訊(sub, role, exp)。
  • 敏感資料放資料庫,透過 ID 查詢。

4. Token 傳輸方式

  • Authorization HeaderAuthorization: Bearer <token>

    → 避免存放在 localStorage(容易被 XSS 攻擊)。

  • HttpOnly Cookie:把 Token 存在 HttpOnly + Secure Cookie,比較不怕 XSS,但要注意 CSRF。

防禦建議

  • 如果用 Header,前端要做好 CSP、防範 XSS。
  • 如果用 Cookie,請加上:
    • HttpOnly(JS 讀不到)
    • Secure(只在 HTTPS 傳送)
    • SameSite=Lax/Strict(防止 CSRF)

5. 防範常見攻擊

現在的資安有很多弱點攻擊,這也是許多人不敢使用雲端的原因,就怕一個不小心就讓資料外洩。我們自己在開發雲端程式的時候,也需要針對這些常見攻擊來進行防護。

我整理了以下幾點比較常見的JWT的攻擊給大家參考。

(1) 演算法混淆攻擊

早期有些 JWT 函式庫會允許 alg=none 或從 HS256 切到 RS256 ,這個就容易被攻擊者利用。

防禦方法

  • 永遠在伺服器端固定演算法,不要信任 Header 裡的 alg
  • 使用最新版本的 JWT 函式庫。

(2) 重放攻擊(Replay Attack)

攻擊者竊取了一張合法 Token,再重複使用。

防禦方法

  • Access Token 壽命短。
  • Refresh Token 旋轉(Day 13 提過)。
  • 重要操作加上 二次驗證(例如 OTP、重新輸入密碼)。

(3) Token 洩漏

  • XSS 竊取 Token(如果放在 localStorage)。
  • 傳輸時被攔截(如果沒用 HTTPS)。

防禦方法

  • 全站 HTTPS
  • Token 儲存在 Cookie + HttpOnly。
  • 後端加上 IP/Fingerprint 綁定(例如 Refresh Token 只能從同一裝置使用)。

(4) 過期 Token 仍被使用

如果後端沒有檢查 exp,就會讓過期 Token 繼續通過。

防禦方法

  • 後端必須嚴格驗證 exp。
  • 可搭配黑名單(Day 14)提前撤銷。

6. 登出與撤銷機制

JWT 本身是無狀態的,但實務上還是要有「可控性」。

  • 黑名單(Day 14 提過)。
  • Refresh Token 旋轉與撤銷。
  • 版本號策略(Token 帶一個 tokenVersion,使用者密碼改變或登出時版本升級 → 舊 Token 自動失效)。

7. 審計與監控

安全不只是技術設計,也要有 **觀測能力,**簡單來說,我們需要更多的log。

  • 記錄所有登入/刷新/登出行為。
  • 偵測異常行為(同一 Refresh Token 在不同地區短時間使用)。
  • 設定告警:例如 Refresh Token 過度重用 → 自動停權。

小結

JWT 在正確使用下是非常好用的工具,但有幾個安全性要點必須遵守:

  1. 金鑰管理要嚴格(不要寫死在程式碼)。
  2. Access Token 壽命短,Refresh Token 搭配旋轉。
  3. 不要把敏感資訊放在 Payload。
  4. Token 儲存與傳輸要防範 XSS/CSRF。
  5. 防範常見攻擊(演算法混淆、重放攻擊、洩漏)。
  6. 提供登出與撤銷機制(黑名單 / tokenVersion)。
  7. 加強監控與審計,才能在問題發生時即時處理。

希望這些整理出來的資料會對大家有幫助,在開發JWT相關的程式時,可以先看看這個頁面,讓自己多加幾道防護。

所有關於JWT的知識就到這裡了,明天我們會來到新的篇章,就是更加近代的OAuth了。

那今天的教學就到這裡,我們明天見!


上一篇
Day 14 JWT 黑名單與強制登出
系列文
「站住 口令 誰」關於資安權限與授權的觀念教學,以Spring boot Security框架實作15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言