Skip to content

auth.json: a token refresh can resurrect a signed-out session (deleteAuth race) #236

Description

@vreshch

Follow-up from cli#231 / cli#235 (config locking), characterized by the #235 adversarial verifier: 200 iterations of a sign-out (deleteAuth) racing an in-flight token refresh (mutateAuth) -> 94 sign-out-won / 106 resurrected / 0 corrupt.

Root cause (deeper than deleteAuth)

deleteAuth is lock-free, but making it locked only serializes the two ops - it does NOT stop resurrection. The actual cause: when a token refresh's mutateAuth re-reads a null (just-signed-out) auth.json, tryRefresh (src/lib/api.ts) falls back to the IN-MEMORY tokens and writes them back, resurrecting the session the user just ended.

Correct fix

Two parts:

  1. Route deleteAuth through withFileLock (make it async; the single caller setup.ts disconnect already awaits) - removes the torn window, deterministic ordering.
  2. In the refresh path, treat "disk read is null" as "signed out - do not resurrect": mutateAuth's refresh mutator should return null (skip the write) when the fresh disk read is null, instead of folding in-memory tokens. This is the part that actually kills resurrection.

Severity

LOW: no corruption, atomic writes throughout, resurrected content is the user's own freshly-refreshed valid tokens (never stale/foreign), sub-ms window, and it requires an explicit --disconnect racing a background refresh. The lost-update class #231 targeted is fully closed (0/90 with the lock); this is the correctly-scoped-out remainder.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions