JWT

2 tools

वेब सुरक्षा की मूल बातें

Web security is the practice of protecting web applications and APIs from unauthorized access, data breaches, and attacks. Modern applications use authentication (proving who you are), authorization (proving what you can do), and cryptography to enforce security boundaries.

JSON Web Tokens (JWT) are the dominant stateless authentication mechanism in modern web development. Understanding how JWTs work — including their structure, signing algorithms, and vulnerabilities — is essential for building secure APIs and applications.

JSON Web Tokens (JWT)

A JWT is a compact, URL-safe way to represent claims between two parties. It consists of three Base64url-encoded parts separated by dots. JWTs can be verified without database lookups because the signature covers the entire token.

The Three Parts of a JWT

Header

Contains metadata about the token: the signing algorithm (alg) and token type (typ). Always Base64url-encoded JSON. The algorithm choice here affects the security of the entire token.

Encoded
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Decoded
{
  "alg": "HS256",
  "typ": "JWT"
}
Payload

Contains the claims: statements about the user and additional metadata. Also Base64url-encoded JSON. Anyone can decode this — payload data is NOT encrypted, only signed.

Encoded
eyJzdWIiOiJ1c2VyXzEyMyIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTcxNzIwMDAwMH0
Decoded
{
  "sub": "user_123",
  "role": "admin",
  "exp": 1717200000
}
Signature

A cryptographic signature over the encoded header and payload. Verifying this signature ensures the token was not tampered with. The secret key (HMAC) or private key (RSA/ECDSA) is never included in the token.

Encoded
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Decoded
HMACSHA256(
  base64url(header) + "." +
  base64url(payload),
  secret
)

Standard JWT Claims

The JWT specification defines standard claim names. Using them ensures interoperability between different JWT libraries and services:

ClaimNameDescription
issIssuerIdentifies the principal that issued the token (e.g., your auth server URL)
subSubjectIdentifies the principal that is the subject of the token (e.g., user ID)
audAudienceIdentifies the recipients that the token is intended for (e.g., your API URL)
expExpirationUnix timestamp after which the token must not be accepted for processing
nbfNot BeforeUnix timestamp before which the token must not be accepted for processing
iatIssued AtUnix timestamp at which the token was issued — used to determine age
jtiJWT IDUnique identifier for the token, used to prevent token replay attacks

Signing Algorithms

The signing algorithm is declared in the JWT header. Choosing the right algorithm for your use case is critical for security:

HS256 / HS384 / HS512Symmetric (HMAC)

Uses a shared secret key for both signing and verification. Simple to implement but requires all verifiers to know the secret.

Use when: Internal services where you control all parties. Never use when third parties need to verify tokens.
RS256 / RS384 / RS512Asymmetric (RSA)

Uses a private key to sign and a public key to verify. The private key never leaves the auth server.

Use when: Microservices architectures, third-party token verification, OAuth2 and OpenID Connect.
ES256 / ES384 / ES512Asymmetric (ECDSA)

Like RSA but with smaller keys and faster signing. Provides equivalent security with better performance.

Use when: Mobile and IoT applications where performance matters. Modern alternative to RSA.
"alg": "none"Unsigned — DANGEROUS

No signature at all. A token with alg:none has no integrity guarantee and can be forged by anyone.

Use when: Never use in production. Some JWT libraries historically accepted alg:none, leading to critical vulnerabilities.

Authentication Flows

Password Grant (Direct)
  1. 1.User submits username and password to the login endpoint
  2. 2.Server validates credentials against the user database
  3. 3.Server signs a JWT with user claims and expiration
  4. 4.Client stores JWT (localStorage, cookie, or memory)
  5. 5.Client sends JWT in Authorization: Bearer header for subsequent requests
Authorization Code + PKCE (OAuth2)
  1. 1.Client redirects user to authorization server with code challenge
  2. 2.User authenticates and authorizes the client application
  3. 3.Auth server redirects back with a one-time authorization code
  4. 4.Client exchanges code + verifier for access and refresh tokens
  5. 5.Client uses access token for API calls; refresh token for renewal

Common JWT Vulnerabilities

JWTs are secure when implemented correctly. These are the most common implementation mistakes that lead to security vulnerabilities:

Algorithm confusion (alg:none)Critical

Some libraries accept tokens with alg:none (no signature). An attacker can modify the payload and set alg to none to forge any JWT. Always explicitly specify and validate the allowed algorithm.

HS256 / RS256 confusionCritical

If a library is expected to verify RS256 but accepts HS256, an attacker can sign a token using the public key as the HMAC secret. The library verifies it successfully. Always pin the expected algorithm.

Missing expiration validationHigh

A JWT without an exp claim, or code that does not check exp, allows tokens to be used indefinitely after a user logs out or is banned. Always set short expiration times and validate the exp claim.

Sensitive data in payloadHigh

JWT payloads are Base64-encoded, not encrypted. Anyone who intercepts a JWT can decode and read the payload. Never store passwords, credit card numbers, or other secrets in JWT claims.

Weak secret keys (HS256)Medium

HMAC-signed JWTs with short or predictable secrets can be brute-forced offline. An attacker who obtains a JWT can try billions of keys per second. Use cryptographically random secrets of at least 256 bits.

Missing signature verificationMedium

Accepting JWTs without verifying the signature trusts the payload completely. This is a critical bug that allows any user to craft arbitrary claims. Always verify the signature before trusting any claim.

अक्सर पूछे जाने वाले प्रश्न

Are JWTs encrypted?

Standard JWTs (JWS — JSON Web Signature) are signed but NOT encrypted. The payload is Base64url-encoded, which is trivially reversible. Anyone who obtains a JWT can read its contents. JWE (JSON Web Encryption) provides encryption, but is much less common.

How long should a JWT be valid?

Access tokens should be short-lived: 5–60 minutes is typical. Long-lived tokens are dangerous because they cannot be revoked without a token blocklist. Use refresh tokens (longer-lived, stored securely) to obtain new access tokens.

Where should I store JWTs in the browser?

HttpOnly cookies are the most secure option — they are inaccessible to JavaScript, preventing XSS theft. localStorage is vulnerable to XSS attacks but avoids CSRF. Memory (JavaScript variable) is safest but does not survive page refresh. There is no perfect option.

Can I revoke a JWT before it expires?

Not without server-side state. The stateless nature of JWTs means the server cannot invalidate them. Solutions: short expiration times, a token blocklist (Redis), rotating refresh tokens, or switching to opaque session tokens for sensitive operations.

What is the difference between JWT and session cookies?

Session cookies store a random session ID; the server looks up session data. JWTs are self-contained — the server validates the signature without a database lookup. JWTs scale better across multiple servers but cannot be revoked without extra infrastructure.

What claims should I include in a JWT?

The minimum: sub (user ID), exp (expiration), and iat (issued at). Add iss (issuer) for multi-service setups. Keep payloads small — JWTs are sent with every request. Do not include sensitive data or large profile objects.

Is RS256 better than HS256?

RS256 (asymmetric) is better for most production systems because only the auth server needs the private key. Multiple services can verify tokens using the public key without sharing a secret. HS256 is simpler but requires all verifiers to know the shared secret.

What is PKCE and why is it important?

PKCE (Proof Key for Code Exchange) is an extension to the OAuth2 authorization code flow that prevents authorization code interception attacks. It is required for public clients (SPAs, mobile apps) that cannot securely store a client secret.