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
- Client polls
/oauth/token with device code in "pending" state
- Server checks
dc.state == "pending" - passes
- User clicks "deny" in browser, updating state to "denied"
- 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
Issue
There is a race condition in the device code token issuance flow. Between checking
dc.stateand issuing the token, the device code could be modified by another request.Scenario
/oauth/tokenwith device code in "pending" statedc.state == "pending"- passesImpact
Location
campus/auth/routes/oauth.py:175-240-_handle_device_code_grant()Recommendation
Use atomic update with state check:
Or issue token only once per device code by checking if token was already issued.
Priority
High - Incorrect token issuance
Related