JWT

API Securityintermediate

// Definition

JSON Web Token — a compact, URL-safe token format for transmitting claims between parties. A JWT has three Base64URL-encoded sections separated by dots: header (signing algorithm), payload (claims like `sub`, `exp`, `roles`), and signature. Because the payload is encoded but not encrypted, any holder of the token can read the claims — never store secrets in a JWT payload. Test JWTs by checking expiry enforcement, algorithm validation (reject `alg: none`), and rejection of tampered signatures.

// Why it matters

JWTs carry signed claims (who you are, what you can do) so the server can trust a request without a session lookup. The QA risk is that the token is only as good as its validation: skip the signature check, accept alg: none, or ignore expiry, and the whole auth model collapses.

// How to test

// A tampered payload must be rejected (signature check enforced)
cy.request({ url: '/api/me', headers: { Authorization: `Bearer ${validJwt}` } })
  .its('status').should('eq', 200)

const tampered = forgeJwt({ ...claims, role: 'admin' }) // re-signed with wrong key / alg:none
cy.request({
  url: '/api/me',
  headers: { Authorization: `Bearer ${tampered}` },
  failOnStatusCode: false,
}).its('status').should('eq', 401)

// Common mistakes

  • Accepting alg: none or letting the token dictate its own algorithm
  • Not checking exp (expired tokens still work)
  • Storing the JWT where XSS can read it (localStorage) instead of an HttpOnly cookie

// Related terms