Skip to content

Make refresh token rotation atomic#321

Open
damilolaedwards wants to merge 1 commit into
ethpandaops:masterfrom
damilolaedwards:fix/refresh-token-rotation-race
Open

Make refresh token rotation atomic#321
damilolaedwards wants to merge 1 commit into
ethpandaops:masterfrom
damilolaedwards:fix/refresh-token-rotation-race

Conversation

@damilolaedwards

Copy link
Copy Markdown

Summary

The refresh handler read the session under a brief lock, released it, then
validated and rotated separately. Two concurrent requests presenting the
same refresh token could both pass the initial lookup before either one
rotated, so a single token could fork into two independently valid refresh
families instead of being single use. That defeats org-based revocation:
removing someone from the allowed org only kills one of the two forked
chains.

The same gap let one request read session fields through a pointer into
the shared session map while another request mutated that object in
place, a data race on the login and org fields.

Copies every field needed out of the session while the lock is held
instead of keeping the pointer around, and makes rotation check that the
presented token is still live and consume it in the same critical section
as the delete and insert. A token already rotated by another request is
now rejected as invalid rather than rotated again.

Test plan

  • go test -race ./pkg/auth/...
  • New test presents the same refresh token from two concurrent
    requests and confirms exactly one succeeds and exactly one live
    session remains afterward; confirmed it fails on the old code
  • go build ./..., go vet ./...

The refresh handler read the session under a brief lock, released it,
then validated and rotated separately. Two concurrent requests
presenting the same refresh token could both pass the initial lookup
before either one rotated, so a single token could fork into two
independently valid refresh families instead of being single use.

The same gap let one request read session fields through a pointer
into the shared session map while another request mutated that same
object in place, a data race on the login and org fields.

Copy every field needed out of the session while the lock is held
instead of keeping the pointer around, and make rotation check that
the presented token is still live and consume it in the same critical
section as the delete and insert. A token already rotated by another
request is now rejected as invalid rather than rotated again.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant