Skip to content

[Security] Token refresh race condition allows concurrent calls — double-refresh invalidates session #673

Description

@RUKAYAT-CODER

Overview

src/services/api/axios.config.ts handles 401 responses by calling refreshAccessToken(). Two concurrent API requests that both receive 401 simultaneously each dispatch an independent refresh call. The first call succeeds and writes a new token pair; the second call uses the now-invalidated refresh token and receives another 401 — forcing logout despite a valid session.

Specifications

Features:

  • Refresh call deduplicated: if a refresh is in flight, subsequent 401 handlers await the same promise
  • Refresh promise cleared after settlement (success or failure)
  • Failed deduplication refresh routes to logout, not infinite retry

Tasks:

  • Add let refreshPromise: Promise<string> | null = null module-level variable in axios.config.ts
  • In 401 interceptor: if (!refreshPromise) { refreshPromise = doRefresh().finally(() => { refreshPromise = null; }); }
  • Await refreshPromise for all concurrent 401 handlers
  • Retry original request with new token after refresh
  • Add unit test: 2 concurrent 401 responses, assert single refresh call

Impacted Files:

  • src/services/api/axios.config.ts

Acceptance Criteria

  • Two concurrent 401 responses result in exactly one refreshAccessToken() call
  • Both original requests retried with new token after refresh
  • Failed refresh triggers single logout, not two
  • Unit test confirms single refresh invocation via mock call count

Metadata

Metadata

Assignees

No one assigned

    Labels

    Stellar WaveIssues in the Stellar wave programbugSomething isn't workingsecuritySecurity vulnerability or concern

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions