#911 Token endpoint leaks caught exception text into client 500 responses (str(e) in details, f-string in raise)
Description
EditEARS SPEC:
- When a token endpoint fails, the API shall return a generic error code and message to the caller;
the underlying exception text shall be logged server-side only, never included in the response body.
- No error response shall interpolate a caught exception into a client-visible field.
FOUND DURING #880 (split of api/blueprints/v1/tokens.py). PRE-EXISTING - the split was pure-move and
left it byte-identical, correctly. Not introduced by the refactor.
DEFECT:
- api/blueprints/v1/tokens.py `_get_jwt_config` raises with an f-string interpolating the caught
exception: f"JWT configuration missing in Vault: {e}"
- Several handlers in the same module return details={"error": str(e)} to the CALLER.
WHY IT MATTERS: this is the token-issuance path, and its exceptions come from Vault lookups and JWT
config. A 500 body can therefore carry secret-store paths, connection strings, or internal state to
an unauthenticated or low-privilege caller. #851 showed exactly how much a Vault error message can
reveal about internal topology.
REPRODUCTION (do NOT assume - exercise it):
Break the Vault path or revoke the token so _get_jwt_config raises, then call the token endpoint and
inspect the RESPONSE BODY, not the log. Confirm the exception text appears in the body. That is the
known-positive; only then is a fix's absence-of-leak meaningful.
FIX: log the exception with logger.exception / logger.error("...: %s", e) server-side, and return a
fixed error code + generic message. Sweep the module for every str(e) / {e} that reaches a response.
SCOPE NOTE: check whether the same pattern exists in the other auth-adjacent blueprints
(api_keys.py, secrets.py, oauth_handlers/) - if so, widen this ticket rather than fixing one file.
Comments
Loading comments...
Context
Loading context...
Audit History
View AllLoading audit history...