Skip to content

Security: Race condition in device code state transition during token issuance #356

@nycomp

Description

@nycomp

Issue

There is a race condition in the device code token issuance flow. Between checking dc.state and issuing the token, the device code could be modified by another request.

Scenario

  1. Client polls /oauth/token with device code in "pending" state
  2. Server checks dc.state == "pending" - passes
  3. User clicks "deny" in browser, updating state to "denied"
  4. Server continues and issues token for "authorized" state

Impact

  • Token could be issued after user denial
  • Multiple tokens potentially issued for one device code

Location

campus/auth/routes/oauth.py:175-240 - _handle_device_code_grant()

Recommendation

Use atomic update with state check:

# Update only if still pending, return updated record
result = device_code_storage.update_by_id(
    dc.id, 
    {"state": "claimed"},
    condition={"state": "pending"}  # only if pending
)
if not result.modified_count:
    raise token_errors.InvalidGrantError("Device code already used or expired")

Or issue token only once per device code by checking if token was already issued.

Priority

High - Incorrect token issuance

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions