ACCOUNT TAKEOVER // SESSION STORAGE // AUTHZ BYPASS
WEB APPLICATION SECURITY

Account Takeover via SessionStorage Authorization

REACT // COOKIE AUTH // CLIENT TRUST

researcher
Naveen Jagadeesan
published
2023-03-30
platform
Financial Web Application

Summary

A financial collaboration app authenticated with cookies but authorized with mutable browser sessionStorage. Combined with a verbose user-lookup API and OSINT-friendly employee emails, an attacker could mint another user’s client identity object and inherit their invoices, org data, and admin-capable UI workflows.

Theory

Modern SPAs often cache a “user profile” object client-side for snappy UX. The dangerous pattern:

Authentication = HttpOnly cookie / token (good)
Authorization = whatever is in sessionStorage.user (bad)

If the server does not re-resolve identity from the session on every sensitive read/write — or if APIs accept client-asserted user IDs — the SPA becomes an identity editor.

Secondary theory: pre-login “lookup user by email” endpoints frequently overshare (role, status, userId), giving attackers a perfect template for the storage object they need to forge.

Application context

Recon: the lookup oracle

GET /api/v1/user?email=researcher@example.com HTTP/2
Host: www.target.example
Cookie: session=<valid-or-empty-as-applicable>
{
  "status": true,
  "message": "Successfully Retrieved",
  "result": [
    {
      "UserId": 601XXX,
      "EmailId": "researcher@example.com",
      "RoleName": "Admin",
      "CountryName": "India",
      "Status": "Approved",
      "IsActive": true
    }
  ]
}

That response is already a finding: user enumeration + excessive data exposure. It also hands the exact schema of the client identity blob.

Hypothesis test with two accounts

  1. Create Account A and Account B.
  2. Log in as A; dump sessionStorage.
  3. Observe profile keys matching the lookup API fields.
  4. Call lookup for B’s email; copy B’s object into A’s sessionStorage slot.
  5. Refresh.

Result: UI and subsequent client-driven calls behaved as B — account takeover relative to the SPA’s trust model, including financial records visible to B.

Weaponization with OSINT

Corporate emails harvested from:

Intruder-style probing against /api/v1/user?email= using content-length / body differences identified valid staff accounts. Lookup returned Admin-capable metadata for some identities. Injecting those objects completed takeover against real organizational users (in authorized testing scope).

Impact

Root causes

  1. Authorization decisions influenced by client-writable storage
  2. User lookup API returns rich identity material
  3. Missing server-side binding between session principal and requested resources
  4. Enumeration-friendly email oracle

Fixes that actually work

Takeaway

If you can edit who you are in DevTools and the app believes you, you do not have an authorization system — you have a suggestion box. Pair that with a chatty user oracle and ATO becomes an operational process, not a research moonshot.