Improper JWT Validation Leading to Full Account Takeover

7 min read

Overview

While reviewing the application’s authentication and session management mechanisms, I identified a critical weakness in how JSON Web Tokens (JWTs) were being validated. The issue allowed attackers to forge authentication tokens and gain unauthorized access to user accounts without valid credentials.

Further to the JWT signature validation flaw, I also identified other gaps related to token lifecycle management within the application.

What I Looked At

I focused on how the application:

My goal was to confirm that trust decisions were being enforced server-side and not delegated to user-controlled inputs.

Primary Finding: Flawed JWT Signature Verification

JWTs rely on cryptographic signatures to ensure their integrity. By design, servers typically do not store JWTs and instead trust them based on successful signature verification.

I identified that the JWT service accepted tokens without a valid signature.

Although the application expected JWTs signed using the HS256 algorithm, the server trusted the alg value supplied within the token header itself. By setting the algorithm to none, it was possible to submit an unsigned JWT that the server accepted as legitimate.

As a result:

Impact: Full Account Takeover

This issue enabled full account takeover.

An attacker could:

No valid credentials, password compromise, or prior authentication was required.

Other gaps in the JWT Service

Weak Token Lifecycle Controls

Modern applications typically use short-lived access tokens combined with longer-lived refresh tokens to balance security and usability. Alongside the signature validation issue, I also observed weaknesses in token lifecycle management:

While not the root cause of the account takeover, these weaknesses increased the blast radius of the issue by allowing forged or leaked tokens to remain valid for longer than intended.

Remediation Recommendations

I recommended the following corrective actions:

Key Takeaways


✦ nzesi

© 2026

𝕏 GitHub