Skip to content

UnicodeEncodeError in get_token_hash crashes /oauth2/userinfo on non-ASCII bearer tokens #13251

Description

@stilla

GET/POST /oauth2/userinfo returns a 500 when the Authorization: Bearer <token> header contains non-ASCII characters.

Crash site: polar/kit/crypto.py:19 in get_token_hash:

hash = hmac.new(secret.encode("ascii"), token.encode("ascii"), hashlib.sha256)

token.encode("ascii") raises UnicodeEncodeError when the incoming token isn't ASCII-only.

Call chain:
polar/oauth2/dependencies.py:31 get_optional_token (extracts the token via a naive partition(" ") split, no charset check) → polar/oauth2/service/oauth2_token.py:40 get_by_access_tokenpolar/kit/crypto.py:19 get_token_hash (crash).

No component in this path validates that the bearer token is ASCII before hashing, so any anonymous request to an endpoint depending on get_token/get_optional_token with a non-ASCII Authorization header triggers an unhandled 500 instead of a 401.

This is the same class of bug fixed in #13019 for the rate-limit middleware's _identity_cache_key (also an unguarded .encode("ascii") on a bearer token), but that fix didn't cover get_token_hash.

Suggested fix: validate/catch non-ASCII input in get_token_hash (or in get_optional_token before calling it) and treat it as an invalid token (401) rather than letting the exception propagate as a 500.

Sentry: SERVER-4VG (1 occurrence, 0 users impacted).

Sent by @frankie567 from Stilla investigation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions