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_token → polar/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.
GET/POST /oauth2/userinforeturns a 500 when theAuthorization: Bearer <token>header contains non-ASCII characters.Crash site:
polar/kit/crypto.py:19inget_token_hash:token.encode("ascii")raisesUnicodeEncodeErrorwhen the incoming token isn't ASCII-only.Call chain:
polar/oauth2/dependencies.py:31 get_optional_token(extracts the token via a naivepartition(" ")split, no charset check) →polar/oauth2/service/oauth2_token.py:40 get_by_access_token→polar/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_tokenwith a non-ASCIIAuthorizationheader 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 coverget_token_hash.Suggested fix: validate/catch non-ASCII input in
get_token_hash(or inget_optional_tokenbefore 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.