Authentication Bugs

JWT Contains Sensitive Data

A JSON Web Token's payload contains sensitive information — full personal data, internal flags, or secrets. Because a JWT is signed but not encrypted, anyone holding the token can decode and read the payload, so anything placed there is effectively exposed to the client and to anyone who captures the token.

MediumBeginnerSecurity testingAPI testingManual testing

// UNDERSTAND

// Symptoms

  • Decoding the JWT payload reveals fields like full name, email, address, phone or date of birth beyond what's needed
  • The payload contains internal flags, roles, or secrets not meant for the client
  • The token includes a password, API key, or another credential
  • The payload is large because it carries data that should come from an API call instead

// Root Cause

  • Developers treat the JWT as encrypted storage and put profile data in it for convenience
  • Misunderstanding that base64url encoding is not encryption — the payload is readable by anyone
  • Copying a whole user record into the token instead of a minimal id + roles
  • No review of what claims the token actually needs

// Where It Appears

  • Login and session flows that issue JWT access tokens
  • APIs using OAuth 2.0 / OpenID Connect bearer tokens
  • Single sign-on and federated identity integrations
  • Mobile apps storing tokens locally

// REPRODUCE & TEST

// How to Reproduce

  1. 01Log in as a test user and capture the JWT access token from the Authorization header or storage
  2. 02Decode the token's payload (use a non-production decoder for test tokens only)
  3. 03Review the claims present in the payload
  4. 04Confirm whether any sensitive personal data, secrets, or internal-only fields appear

// Test Data Needed

  • A test user account that produces a JWT (no real personal data)
  • A JWT decoder for inspecting non-production test tokens

// Manual Testing Ideas

  • Decode the token and list every claim; flag anything beyond id, roles, issuer, audience and expiry
  • Check whether the same data is also available from a normal authenticated API call (it should be)
  • Confirm no password, card number or full personal record is present
  • Verify the token is sent over HTTPS only and is not logged in plain text

// API Testing Ideas

  • Assert in an automated test that the decoded payload contains only an allowlist of expected claims
  • Fail the test if any disallowed field (email, address, secret) appears in the payload

// Automation Idea

Add a test that decodes a freshly issued test token and asserts its claims against an allowlist (id, roles, iss, aud, exp). Any extra sensitive field fails the build. Keep it on non-production tokens only.

// Expected Result

The JWT payload carries only the minimum claims needed (a user id, roles/permissions, and standard metadata). Sensitive personal data and secrets are fetched from authorised APIs, never embedded in the token.

// Actual Result (Example)

The decoded payload includes the user's full name, email, postal address and an internal `is_staff` flag — all readable by anyone who decodes the token.

// REPORT IT

Example Bug Report

Title
Access-token JWT payload exposes full personal data
Severity
Medium
Environment
Staging · build 2026.06.03
Steps to Reproduce
  1. 01Log in as a test user and capture the access token
  2. 02Decode the token payload in a non-production decoder
  3. 03Review the claims
Expected Result
Payload contains only id, roles, iss, aud, exp.
Actual Result
Payload also contains full name, email, address and an internal staff flag.
Impact
Any party that captures the token (logs, browser storage, a proxy) can read users' personal data without calling a protected API.

// RELATED