Problem
verify_token (library-manager/backend/dependencies.py) compares the bearer token with hmac.compare_digest(credentials.credentials, LAMB_API_TOKEN) on the raw str values. hmac.compare_digest raises TypeError: comparing strings with non-ASCII characters is not supported whenever the supplied token contains non-ASCII characters. The TypeError is unhandled and surfaces as HTTP 500 Internal Server Error instead of a clean 401.
A malformed/garbage Authorization header — including one with non-Latin-1 / non-ASCII bytes — must always be rejected as unauthorized, never crash the request handler. As-is, a client can trip a 500 on the auth path with a single malformed header.
Expected
Any invalid bearer token — including non-ASCII content — yields 401 Unauthorized. The auth path never returns 500. The valid-token path keeps its constant-time (timing-safe) comparison.
Fix
Compare bytes rather than str (encode both operands, e.g. hmac.compare_digest(provided.encode("utf-8"), expected.encode("utf-8"))), or catch TypeError from compare_digest and treat it as a mismatch → 401. Preserve timing-safe comparison for the success path.
Tests
The bug is pinned by a strict xfail that asserts the correct behaviour:
tests/e2e/test_auth_boundary.py::test_non_latin1_token_is_401_not_500
The fix MUST remove the @pytest.mark.xfail decorator so the test asserts 401 normally (a strict xfail that starts passing is reported as a failure). After the fix, the full suite (./scripts/run_tests.sh) MUST be green with the ≥95% coverage gate satisfied, and tests/e2e/test_auth_boundary.py must pass with no xfails.
Scope
library-manager/backend/dependencies.py only (plus removing the xfail marker in the pinned test).
Problem
verify_token(library-manager/backend/dependencies.py) compares the bearer token withhmac.compare_digest(credentials.credentials, LAMB_API_TOKEN)on the rawstrvalues.hmac.compare_digestraisesTypeError: comparing strings with non-ASCII characters is not supportedwhenever the supplied token contains non-ASCII characters. TheTypeErroris unhandled and surfaces as HTTP 500 Internal Server Error instead of a clean 401.A malformed/garbage
Authorizationheader — including one with non-Latin-1 / non-ASCII bytes — must always be rejected as unauthorized, never crash the request handler. As-is, a client can trip a 500 on the auth path with a single malformed header.Expected
Any invalid bearer token — including non-ASCII content — yields 401 Unauthorized. The auth path never returns 500. The valid-token path keeps its constant-time (timing-safe) comparison.
Fix
Compare bytes rather than
str(encode both operands, e.g.hmac.compare_digest(provided.encode("utf-8"), expected.encode("utf-8"))), or catchTypeErrorfromcompare_digestand treat it as a mismatch → 401. Preserve timing-safe comparison for the success path.Tests
The bug is pinned by a strict xfail that asserts the correct behaviour:
tests/e2e/test_auth_boundary.py::test_non_latin1_token_is_401_not_500The fix MUST remove the
@pytest.mark.xfaildecorator so the test asserts401normally (a strict xfail that starts passing is reported as a failure). After the fix, the full suite (./scripts/run_tests.sh) MUST be green with the ≥95% coverage gate satisfied, andtests/e2e/test_auth_boundary.pymust pass with no xfails.Scope
library-manager/backend/dependencies.pyonly (plus removing the xfail marker in the pinned test).