Skip to content
All writing Part 05 of 07 · 一次 JWT 稽核背後的七個盲點
Engineering · 2 min read

演算法混淆與 none 攻擊

JWT header 的 alg 欄位由客戶端控制。攻擊者能改成 none 或混淆簽章類型。Server 端 pin 演算法就能堵住。

JWT header 有一個 alg 欄位。這個欄位由客戶端控制。如果 server 信任它,攻擊者就控制了驗證路徑。

Token header 寫 alg = ? "none" 不需要簽章 ✗ "HS256" (但 server 預期 RS256) 用公鑰當 HMAC 密鑰來簽 ✗ Server 接受偽造的 token 修復:server 端 pin 演算法 jwt.verify(t, key, {algorithms:['HS256']}) → 忽略 token header ✓

none 攻擊

攻擊者把 header 設成 {"alg":"none"},刪掉簽章。Token 變成兩段加一個空的第三段:

  正常 token:
  eyJhbGci...  .  eyJzdWIi...  .  SflKxwRJ...
    header          payload        signature

  none 攻擊 token:
  eyJhbGci...  .  eyJzdWIi...  .
  {"alg":"none"}  {"sub":"admin"}   ← 沒有簽章

Server 讀到 alg: "none",跳過驗證。空簽章不是問題,server 預期沒有簽章。攻擊者能放入任何 payload。大小寫變體(nOnENONE)能繞過簡單的字串檢查。

演算法混淆

Server 用 RS256(非對稱)。攻擊者把 alg 改成 HS256,用公開的公鑰來簽章。通用的 verify() 函數把公鑰當成 HMAC 密鑰。

  RS256 設定:
  私鑰(保密)→ 簽章
  公鑰(公開)→ 驗證

  攻擊:把 alg 改成 HS256
  HMAC 只需要一把鑰匙
  攻擊者用公鑰當那把鑰匙
  server 也有公鑰
  → HMAC(publicKey, token) 兩邊吻合 ✗

這個攻擊只在 server 有 RSA 金鑰對、且 verify() 同時接受 HS256 和 RS256 時才成立。

警告: jwt.verify(token, secret) 不帶 algorithms 選項就信任 token header。一個選項欄位能堵住兩種攻擊。

稽核中的發現: lobby-service 和 game-server 呼叫 jwt.verify(token, secret) 時沒有 pin 演算法。修復後加上 algorithms: ['HS256']。這個 side project 只用 HS256,所以混淆路徑不適用,但 pin 堵住了 none 攻擊。

alg 欄位由客戶端控制。一個選項把控制權拿回 server。」

參考來源

回到總覽:一次 JWT 稽核背後的七個盲點 · 對稱與非對稱簽章 · 六個標準宣告

Tags #jwt #security #authentication
// connect

Be brave | Be wise | Be grateful

21 BreakinCode

// elsewhere
LinkedInMedium (lang: en)Youtube
wh:~$William Hung· © 2026 Taipei · GMT+8 · Available for collaboration