← All casesConfidential · Anonymized
Case
#024
FinTech · Severity: High

API Logic Vulnerability

A multi-step API workflow exposed by the client permitted a state transition that bypassed authentication checks when a specific request-ordering condition was reproduced. The condition was not visible from standard testing paths and required a controlled race window. Once triggered, an unauthenticated caller obtained a session bound to an arbitrary user id.

Industry
FinTech
Scope
API · Infrastructure · Validation
Timeline
R·Q2 → V·Q2 → R·Q3
Closed
Q3
01

Impact

Authenticated identity takeover
Unauthenticated → arbitrary user_id, single request
Backend resource exhaustion
~4× normal DB pool utilization during reproduction
Application instability
p95 latency degraded on 3 of 6 downstream services
Blast radius
Full API surface authorization boundary
Impact vectors
  • Application instability
  • Authentication bypass
  • Backend resource exhaustion
02

Reproduction

Steps below reproduce the finding against a staging replica. Where the reproduction affected a shared component, coordination was arranged before execution.

  1. 01Initiate the multi-step onboarding flow up to the state-transition endpoint.
  2. 02Prepare two concurrent requests: (a) a legitimate state-advance, (b) a crafted state-mutation with a substituted user_id.
  3. 03Dispatch (a) then (b) within a ≤ 40 ms window against the same backend replica.
  4. 04Observe: session established under the substituted user_id; downstream authorization treats caller as authenticated.
  5. 05Repeat across replicas to confirm the race is not replica-local.
03

Vulnerability

Vulnerable pattern (simplified)python
# state-advance handler — trusted transition, no idempotency key
def advance_state(request):
    session = load_session(request)
    incoming = request.json
    # trust boundary: caller can supply user_id on transitions
    session.user_id = incoming.get("user_id", session.user_id)
    session.stage   = next_stage(session.stage)
    save_session(session)
    return ok(session)
04

Mitigation

Client-side mitigation shipped and validated during the engagement. Reference patch below.

Mitigation shipped by clientpython
# state-advance handler — bound, idempotent, authorized
def advance_state(request):
    session = load_session(request)
    expected_user = session.user_id
    if request.json.get("user_id", expected_user) != expected_user:
        return forbidden("user_id may not change on transition")
    with idempotency_key(request):
        session.stage = next_stage(session.stage)
        save_session(session)
    return ok(session)
05

Retest & Verify

  • Reproduction path exercised against staging replicas after fix deployment — 0/2000 attempts succeeded.
  • Production replicas exercised under a controlled window — 0/500 attempts succeeded.
  • Idempotency-key path verified: duplicate concurrent submissions collapse to a single state advance.
  • Downstream service latency returned to baseline within one deployment cycle.
06

Deliverables

  • Technical Report (Markdown + PDF)
  • Reproduction artifacts (request bundle, sequence diagram)
  • Mitigation guidance with reference patch
  • Retesting report (post-fix)
  • Final validation memo
07

Sign-off

Handled by
Epulyx (Lead Security Researcher)
Reviewed by
Nolan (CEO)
Closed
Case closed after final validation memo.
Cookies

We use a minimal set of cookies to keep this site functional. Analytics cookies only with your consent. Cookie Policy.