Skip to content

Previous tokens remain valid indefinitely, bypassing batch window throttle #1659

@leightjohnson93

Description

@leightjohnson93

The token_is_current? method in DeviseTokenAuth::Concerns::User module contains a security vulnerability that allows previous tokens to remain valid indefinitely, effectively bypassing the batch request buffer throttle setting.

Current Implementation
In the current implementation, token_is_current? checks if the token matches either the current token OR the previous token without any time window restriction for the previous token:

def token_is_current?(token, client)
  # ...
  return true if (
    # ensure that expiry and token are set
    expiry && token &&
    # ensure that the token has not yet expired
    DateTime.strptime(expiry.to_s, '%s') > Time.zone.now &&
    # ensure that the token is valid
    (
      # check if the latest token matches
      does_token_match?(token_hash, token) ||
      # check if the previous token matches
      does_token_match?(previous_token_hash, token)
    )
  )
end

While there is a separate token_can_be_reused? method that properly enforces the batch window throttle:

def token_can_be_reused?(token, client)
  # ...
  result = (
    updated_at && last_token_hash &&
    Time.zone.now - updated_at.to_time < DeviseTokenAuth.batch_request_buffer_throttle &&
    does_token_match?(last_token_hash, token)
  )
  # ...
end

Security Problem
This implementation creates a situation where:

The previous_token remains valid indefinitely without any time window restriction
The batch_request_buffer_throttle setting is effectively bypassed for previous tokens
Token rotation security is undermined since old tokens remain valid forever

How to Reproduce

# create first token
first_token = User.first.create_new_auth_headers('test')
# create new token
User.first.create_new_auth_headers('test')

# Observe that the credentials from first_token are valid

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions