Engineering · 2 min read
時間安全比對:防範旁道攻擊
嚴格等號在第一個不匹配字元就停下,洩漏正確字元數。timingSafeEqual 走完整個長度,時間固定。
嚴格等號在第一個不匹配的字元就停下。回應時間洩漏了多少字元正確。
有漏洞的寫法:
if (credentials === expectedToken) { ... }
安全的寫法:
import { createHash, timingSafeEqual } from 'node:crypto';
const digest = (v) => createHash('sha256').update(v).digest();
const safeEqual = (a, b) =>
timingSafeEqual(digest(a), digest(b));
先做 hash 能產生固定長度的 buffer。timingSafeEqual 要求兩邊等長。Hash 也防止長度不同時提前退出。
這個模式適用於:API key 比對、webhook 簽章驗證、token 比對、HMAC digest 比對。
警告: 比對函數只是一層。速率限制和一致的認證路徑才能完成防禦。
稽核中的發現: game-server 的
authenticateCredentials用嚴格等號比對憑證。修復後換成crypto.timingSafeEqual。
「時間是一種資訊。固定時間的比對讓時間變成噪音。」
參考來源
Related
回到總覽:一次 JWT 稽核背後的七個盲點 · 六個標準宣告