Description
A clear and concise description of what the bug is.
verifyJwt accepts tampered JWTs and returns the publicKey payload instead of returning null when signature verification fails. This causes the unit test tests/auth-jwt.test.ts > JWT helpers > returns null for a tampered signature to fail in CI.
Steps to Reproduce
- Ensure JWT_SECRET is set (e.g., via vi.stubEnv in tests).
- Run the backend test suite or the specific test file:
pnpm test -- tests/auth-jwt.test.ts or run CI.
- Observe the failing test: tampered signature still validates and verifyJwt returns { publicKey }.
Expected Behavior
verifyJwt should validate the JWT signature and return null for any verification failure (tampered header/body/signature, expired token, malformed token). For valid tokens, it should return { publicKey } extracted from the token "sub" claim.
Actual Behavior
The current implementation decodes the token without verifying its signature (likely using jwt.decode or manual parsing), so tampered tokens can be accepted and the publicKey returned.
Screenshots
N/A
Environment
- FlowFi Version: commit 0fd6620 (from CI job)
- Browser: N/A
- Operating System: CI Linux runner
- Node.js Version: (CI-provided)
- Wallet: N/A
Component
Logs/Error Messages
FAIL tests/auth-jwt.test.ts > JWT helpers > returns null for a tampered signature
→ expected { publicKey: 'GTESTPUBLICKEY123' } to be null
Excerpt from CI logs:
{"level":"warn","message":"[Auth] JWT_SECRET is less than 32 bytes long; consider using a stronger secret","timestamp":"2026-06-10T05:13:35.646Z"}
Test run summary: 39 passed, 1 failed (tests/auth-jwt.test.ts), total 213 tests. See CI job: https://github.com/LabsCrypt/flowfi/actions/runs/80486592390
Additional Context
Related issue referenced during triage: #760
This is security-sensitive: accepting tampered JWTs is a vulnerability. The test suite already includes checks for tampered header, body, signature, expiry, and malformed tokens.
Possible Solution
Use a JWT library's verify function (for example, jsonwebtoken.verify) with the configured JWT_SECRET so the library validates the signature and standard claims (exp, iat). Do not use jwt.decode for validation-only behavior.
Suggested code change (example):
// backend/src/middleware/auth.ts (or .js)
import jwt from 'jsonwebtoken';
export function verifyJwt(token: string): { publicKey: string } | null {
try {
const JWT_SECRET = process.env.JWT_SECRET;
const decoded = jwt.verify(token, JWT_SECRET) as { sub: string; iat?: number; exp?: number };
return { publicKey: decoded.sub };
} catch (error) {
return null;
}
}
Acceptance criteria:
- CI passes with auth-jwt.test.ts (tampered signature test returns null).
- verifyJwt returns null for tampered/expired/malformed tokens and returns { publicKey } for valid tokens.
Notes:
- Ensure JWT_SECRET is present in CI and test environments. If the project uses a custom JWT signing/verification scheme, adapt verification to validate the actual algorithm used.
Description
A clear and concise description of what the bug is.
verifyJwt accepts tampered JWTs and returns the publicKey payload instead of returning null when signature verification fails. This causes the unit test tests/auth-jwt.test.ts > JWT helpers > returns null for a tampered signature to fail in CI.
Steps to Reproduce
pnpm test -- tests/auth-jwt.test.tsor run CI.Expected Behavior
verifyJwt should validate the JWT signature and return null for any verification failure (tampered header/body/signature, expired token, malformed token). For valid tokens, it should return { publicKey } extracted from the token "sub" claim.
Actual Behavior
The current implementation decodes the token without verifying its signature (likely using jwt.decode or manual parsing), so tampered tokens can be accepted and the publicKey returned.
Screenshots
N/A
Environment
Component
Logs/Error Messages
Additional Context
Related issue referenced during triage: #760
This is security-sensitive: accepting tampered JWTs is a vulnerability. The test suite already includes checks for tampered header, body, signature, expiry, and malformed tokens.
Possible Solution
Use a JWT library's verify function (for example, jsonwebtoken.verify) with the configured JWT_SECRET so the library validates the signature and standard claims (exp, iat). Do not use jwt.decode for validation-only behavior.
Suggested code change (example):
Acceptance criteria:
Notes: