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

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