Bug
Two independent issues in WS token handling:
-
Replay window — tokens are an HMAC over slab:timestamp with no nonce and no binding to client IP or connection ID. An observed valid token is replayable by any party within the 5-minute freshness window.
-
Empty-secret fallback — WS_AUTH_SECRET || "" keys HMACs with the empty string when the env var is unset. Production exits on a missing secret (ws.ts:61-64), but a misconfigured non-production deploy with WS_AUTH_REQUIRED=false accepts tokens signed with "", which are trivially forgeable.
Source
src/routes/ws.ts
76 const WS_SECRET = WS_AUTH_SECRET || ""; // empty string when unset
313 function verifyWsToken(token: string, expectedSlab?: string) {
322 // window: 5 minutes + 30s clock-skew tolerance, no nonce
324 if (now - timestamp > 5 * 60 * 1000 || timestamp > now + 30_000) ...
Note: the Number.isNaN guard at :319-320 that precedes the window comparison is correct and handles the NaN-comparison bypass class — do not change it.
Fix
- Bind tokens to the connecting client IP (include it in the HMAC payload and reject on mismatch at verification).
- Refuse all HMAC operations when
WS_AUTH_SECRET is empty, regardless of WS_AUTH_REQUIRED. Throw at module load for non-development environments; emit a critical log warning in development.
Bug
Two independent issues in WS token handling:
Replay window — tokens are an HMAC over
slab:timestampwith no nonce and no binding to client IP or connection ID. An observed valid token is replayable by any party within the 5-minute freshness window.Empty-secret fallback —
WS_AUTH_SECRET || ""keys HMACs with the empty string when the env var is unset. Production exits on a missing secret (ws.ts:61-64), but a misconfigured non-production deploy withWS_AUTH_REQUIRED=falseaccepts tokens signed with"", which are trivially forgeable.Source
src/routes/ws.tsNote: the
Number.isNaNguard at:319-320that precedes the window comparison is correct and handles the NaN-comparison bypass class — do not change it.Fix
WS_AUTH_SECRETis empty, regardless ofWS_AUTH_REQUIRED. Throw at module load for non-development environments; emit a critical log warning in development.