JWT and session security for Indian app teams: algorithm confusion, claim validation, token lifetime, cookie storage and the revocation mistakes that leak data.
A JSON Web Token is a signed statement, not a session, and most JWT breaches come from three mistakes: accepting the algorithm the token asks for, putting sensitive or revocable data inside the payload, and setting an expiry measured in weeks. A safe implementation pins one algorithm server-side, validates issuer, audience and expiry on every request, keeps the payload minimal, sets short lifetimes with refresh rotation and reuse detection, and stores tokens in httpOnly, Secure, SameSite cookies rather than localStorage. For Indian product teams the extra obligations are DPDP Act data-minimisation and CERT-In's 180-day log retention for authentication events.
Four, in order of how often they are found. Algorithm confusion: the server decodes the header and honours whatever algorithm it names, so an attacker can submit a token with alg set to none, or with alg set to HS256 and the public key used as the HMAC secret. Unsigned payload trust: a token is base64url, not encrypted, so an attacker who cannot sign can still read and edit fields, and if the server does not verify the signature before reading claims, editing a role field is enough. Missing claim validation: exp, iss, aud, nbf and the subject are frequently not all checked, which permits token reuse across environments, such as a staging token accepted in production. And weak revocation: a stateless JWT cannot be revoked, so a token for a dismissed employee or a terminated vendor remains valid until it expires.
Short, and strictly rotated. A common workable pattern is a 10 to 15 minute access token and a refresh token of days, where the refresh token is stored server-side in hashed form, is bound to the device and session, and is single-use. Every refresh issues a new refresh token and invalidates the old one, and if an already-used refresh token is presented again, that is a replay signal and the whole token family is revoked. Logout then becomes meaningful rather than cosmetic, because the server can kill the session. For a banking or health product the access-token lifetime should be shorter still, and sensitive actions such as a beneficiary change should require a fresh authentication step rather than a valid token alone.
In an httpOnly, Secure, SameSite cookie, in almost every case. localStorage is readable by any script running on the origin, which means a single cross-site scripting flaw becomes a full session theft, and the attacker can exfiltrate the token without any user interaction. If a token must be readable by JavaScript, for a native mobile or a pure API client, treat it as a bearer secret, keep the lifetime short, rotate aggressively, and bind it where the platform allows. Also check the reverse proxy and the API gateway: many Indian deployments terminate TLS at the load balancer and then forward to the application over plain HTTP inside the network, which exposes the cookie header to anything on that segment.
Test it adversarially and specifically: submit tokens with alg none, with the algorithm swapped, with an altered role claim, with a missing audience, with an expired exp, with a future nbf, and with a token issued by a different environment. Test whether logout actually invalidates, and whether a revoked user's token still works. AAVETech runs this as part of a fixed-price API or web application penetration test at roughly Rs 12,000 to Rs 30,000 per tester-day plus 18% GST, with a 5 to 10 working day turnaround, a retest included, and a written rules-of-engagement document so that nothing outside the agreed scope is touched.
| Check | Safe configuration | Common failure |
|---|---|---|
| Algorithm | Pinned server-side, one value | Trusting the alg header |
| Claim validation | exp, nbf, iss, aud, sub all checked | Audience not validated |
| Payload | Minimal, no secrets, no personal data | Role and PII in the token |
| Lifetime | 10-15 minute access token | Weeks-long access token |
| Refresh | Rotated, single use, reuse detected | Static refresh token |
| Storage | httpOnly, Secure, SameSite cookie | Token in localStorage |
A JSON Web Token is a signed statement, not a session, and most JWT breaches come from three mistakes: accepting the algorithm the token asks for, putting sensitive or revocable data inside the payload, and setting an expiry measured in weeks. A safe implementation pins one algorithm server-side, validates issuer, audience and expiry on every request, keeps the payload minimal, sets short lifetimes with refresh rotation and reuse detection, and stores tokens in httpOnly, Secure, SameSite cookies rather than localStorage. For Indian product teams the extra obligations are DPDP Act data-minimisation and CERT-In's 180-day log retention for authentication events.
Not automatically. A signed JWT scales horizontally without a session store, but it carries the cost of statelessness: revocation, logout and immediate permission changes all become harder. For a banking, health or enterprise product with strict logout expectations, a server-side session with a short-lived identifier is usually the safer choice.
It is common but risky. The payload is readable by the client, and if the server ever reads claims before verifying the signature, the role becomes attacker-controlled. If you must carry roles, sign the token, verify the signature on every request, and treat the role as a hint that is re-checked against the current account state for sensitive actions.
10 to 15 minutes for the access token is a reasonable default, with a longer but rotated and single-use refresh token bound to the device session. Long-lived access tokens turn a single theft into a long-lived credential, which is exactly what CERT-In's 180-day log retention expects investigators to be able to trace.
You need a server-side deny list or a short lifetime with a version claim, because the token itself cannot be un-signed. Maintain a revocation list keyed by token identifier or session version, check it on requests that matter, and clear the whole family on a refresh-token replay.
Yes. AAVETech runs token handling as a named test area inside a fixed-price web application or API penetration test at roughly Rs 12,000 to Rs 30,000 per tester-day plus 18% GST, delivered in 5 to 10 working days with a signed rules-of-engagement document and a retest after your fixes.
Read the full guide on AAVETech: Is Your JWT Implementation Safe, or Are You Leaking Sessions?.
Send us your token issuance and validation code paths and we will return a fixed-price session security review with a signed rules-of-engagement document.
Talk to an analyst about this.