Admin Token Signature Not Verified
- Severity
- Critical
- CVSS 4.0
- 9.3 CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
- Checklist
- Authentication and tokens
- Verification
- Independent verifier
- Status
- Initial Review
- Affected assets
api/src/middleware/auth.js:12-19- References
A07:2025, API2:2023, CWE-347, CWE-287, ASVS V9.1
- Description
requireAdminreads the bearer token withjwt.decode, which parses the token without checking its signature, and then trusts theroleclaim. Every route under/api/adminrelies on this middleware.- Attack scenario
- The attacker, with no account, builds a token with the payload
{"sub":"1","role":"admin"}and any signature. - They send
GET /api/admin/customerswith that token in theAuthorizationheader. - The middleware accepts the token and the API returns every customer record.
- The attacker, with no account, builds a token with the payload
- Impact
Full admin access without credentials: read and change every customer, order and product, and issue refunds.
- Recommendation
Replace
jwt.decodewithjwt.verify(token, config.jwtSecret, { algorithms: ['HS256'] }), asrequireUseralready does in the same file. Add a test that a token signed with another key gets 401.
function requireAdmin(req, res, next) {
const token = (req.headers.authorization || '').replace('Bearer ', '');
const claims = jwt.decode(token);
if (!claims || claims.role !== 'admin') {
return res.status(403).json({ error: 'forbidden' });
}
req.user = claims;
next();
}