A JSON Web Token (JWT) is a standardized format for transmitting claims as JSON between parties. JWTs are commonly used for access and ID tokens in APIs, OAuth 2.0 and OpenID Connect. The format alone makes an application neither stateless nor secure.
How is a JWT structured?
The compact representation typically consists of three Base64url-encoded parts: header, payload and signature, separated by dots. The header identifies an algorithm and key ID, for example. The payload contains claims such as issuer (iss), audience (aud), subject (sub) and expiration (exp). In a JWS, the signature protects the integrity of header and payload.
Are JWTs encrypted?
Usually not. Base64url is only an encoding; anyone holding the token can read its header and payload. A signed JWS prevents unnoticed modification, not inspection. Encrypted JWTs use JWE, but are less common. Sensitive data belongs in a token only when exposure, logging and persistent copies have been explicitly considered.
What are JWTs used for?
| Token | Purpose |
|---|---|
| Access token | Allows a client to access an API and must target the specific resource server. |
| ID token | Tells an OpenID Connect client about authentication; it is not a general API token. |
| Refresh token | Obtains new access tokens, needs especially protected storage and need not be a JWT. |
| Application token | Transports signed state or short-lived actions where a protocol defines this carefully. |
Which JWT vulnerabilities exist?
- The application decodes the token but fails to verify its signature reliably.
- Unexpected or unsafe algorithms are accepted, including algorithm confusion.
- Weak HMAC secrets can be guessed offline.
kid,jkuor embedded keys influence key selection without sufficient control.iss,aud,exp,nbfor token type are not validated.- Tokens leak into URLs, logs, browser storage or the wrong service.
- Long lifetimes and missing revocation extend the impact of theft.
How are JWTs used securely?
A maintained library must verify with an explicitly permitted algorithm. Keys are generated with sufficient strength, managed separately, rotated and obtained through trusted metadata. Issuer, audience, time claims, intended use and signature are validated together. Access tokens stay short-lived; refresh tokens receive rotation and reuse detection. Every object and function still requires server-side authorization.
Code example: decoding is not verification
Vulnerable pseudocode:
claims = base64url_decode(token.payload)
currentUser = claims.sub
Safer flow:
claims = verifyJwt(token, {
algorithms: ['RS256'],
issuer: 'https://identity.example',
audience: 'orders-api',
requiredClaims: ['sub', 'exp', 'iat']
})
currentUser = loadActiveUser(claims.sub)
Library APIs differ, but the security decision does not: algorithm, key, issuer, audience, time claims and token type are verified together. Token roles must also not permanently replace a more current server-side authorization decision.
JWT or conventional session?
JWTs help when several services need standardized, independently verifiable claims. A server-side session is often easier to revoke and keeps current authorization data centralized. A conventional website login does not automatically gain security or scalability by adopting JWT. Architecture and threat model should drive the choice, not the popularity of a format.
Thank you for your feedback! We will review it and optimize this content.
Do you have feedback on JSON Web Token (JWT)? Tell us!
Additional Services
Comprehensive IT security solutions for complete protection
Red Teaming
Simulation of real attacks on your company including people, infrastructure and processes. A comprehensive approach to testing your entire security strategy.
Learn morePhishing Exercises
Practical phishing simulations to raise employee awareness. Increase awareness and reduce the risk of successful email-based attacks.
Learn more