fix(api-server): reject a non-ASCII bearer token with 401 instead of crashing - #65305
fix(api-server): reject a non-ASCII bearer token with 401 instead of crashing#65305Drexuxux wants to merge 3 commits into
Conversation
…crashing _check_auth gates every OpenAI-compatible API server endpoint. It compared the client's raw bearer token against the configured key with hmac.compare_digest on two str values. compare_digest raises TypeError on a str containing non-ASCII characters, and the token comes straight from the Authorization header — so a request with a single non-ASCII byte in the key (a stray unicode char, a smart quote, a pasted BOM) crashed the handler with an unhandled TypeError. Every endpoint calls _check_auth without a try/except, so the framework turned that into a 500 Internal Server Error instead of the intended 401 Invalid API key. Compare as bytes, matching web_server.py's dashboard-token check (hmac.compare_digest(auth.encode(), expected.encode())). Encoding both sides keeps the timing-safe comparison and its semantics identical for valid keys while making a non-ASCII token fail closed with a clean 401. Adds regression tests: a non-ASCII bearer token returns 401 (no raise), and a non-ASCII configured key still authenticates against its exact value.
|
Thanks for the focused API-server regression fix. The premise is verified on current main: Problems
Suggested changes
Automated hermes-sweeper review. |
…ii-bearer-crash # Conflicts: # scripts/release.py
…g sites Same bug class as the salvaged #65305/#65307: hmac.compare_digest (and secrets.compare_digest) raise TypeError when given a str containing non-ASCII characters, and these call sites feed it raw request input. Compare as UTF-8 bytes everywhere: - gateway/platforms/msgraph_webhook.py: clientState from request body - gateway/platforms/whatsapp_cloud.py: hub.verify_token query param + X-Hub-Signature-256 header (comment claimed 'works on str' — it doesn't for non-ASCII) - plugins/platforms/feishu: verification token + x-lark-signature - plugins/platforms/raft: bridge token header - plugins/platforms/line: X-Line-Signature - plugins/platforms/sms: X-Twilio-Signature - tools/code_execution_tool.py: sandbox RPC token (both loops) Regression tests for the two gateway-core sites (msgraph, whatsapp).
|
Merged via PR #65697 — your commits from this PR and #65307 were cherry-picked onto current main with your authorship preserved in git log (rebase-merge). We widened the same fix to the remaining sibling compare_digest sites (msgraph clientState, WhatsApp Cloud verify-token + signature, feishu/raft/line/sms plugin adapters, code_execution RPC token) in a follow-up commit so the whole bug class is closed. Thanks! |
…g sites Same bug class as the salvaged NousResearch#65305/NousResearch#65307: hmac.compare_digest (and secrets.compare_digest) raise TypeError when given a str containing non-ASCII characters, and these call sites feed it raw request input. Compare as UTF-8 bytes everywhere: - gateway/platforms/msgraph_webhook.py: clientState from request body - gateway/platforms/whatsapp_cloud.py: hub.verify_token query param + X-Hub-Signature-256 header (comment claimed 'works on str' — it doesn't for non-ASCII) - plugins/platforms/feishu: verification token + x-lark-signature - plugins/platforms/raft: bridge token header - plugins/platforms/line: X-Line-Signature - plugins/platforms/sms: X-Twilio-Signature - tools/code_execution_tool.py: sandbox RPC token (both loops) Regression tests for the two gateway-core sites (msgraph, whatsapp).
…g sites Same bug class as the salvaged NousResearch#65305/NousResearch#65307: hmac.compare_digest (and secrets.compare_digest) raise TypeError when given a str containing non-ASCII characters, and these call sites feed it raw request input. Compare as UTF-8 bytes everywhere: - gateway/platforms/msgraph_webhook.py: clientState from request body - gateway/platforms/whatsapp_cloud.py: hub.verify_token query param + X-Hub-Signature-256 header (comment claimed 'works on str' — it doesn't for non-ASCII) - plugins/platforms/feishu: verification token + x-lark-signature - plugins/platforms/raft: bridge token header - plugins/platforms/line: X-Line-Signature - plugins/platforms/sms: X-Twilio-Signature - tools/code_execution_tool.py: sandbox RPC token (both loops) Regression tests for the two gateway-core sites (msgraph, whatsapp).
What?
_check_authgates every OpenAI-compatible API server endpoint. It compared the client's raw bearer token against the configured key withhmac.compare_digeston twostrvalues:hmac.compare_digestraisesTypeError: comparing strings with non-ASCII characters is not supportedwhen given astrcontaining non-ASCII characters, andtokencomes straight from theAuthorizationheader. So a request with a single non-ASCII byte in the key (a stray unicode char, a smart quote, a pasted BOM) raised an unhandledTypeError. Every endpoint calls_check_authwithout atry/except, so the framework turned that into a 500 Internal Server Error instead of the intended 401 Invalid API key — a legitimate client with a mistyped key gets an inscrutable 500, and any request can force a 500 on the auth path.Solution
Compare as bytes, matching
web_server.py's dashboard-token check (hmac.compare_digest(auth.encode(), expected.encode())):Encoding both sides keeps the timing-safe comparison and its semantics identical for valid keys, while a non-ASCII token now fails closed with a clean 401 instead of crashing.
How to test
pytest tests/gateway/test_api_server.py::TestAuth -q_check_authdirectly:Bearertoken containing a non-ASCII byte must return a 401 response (and must not raise);TypeErrorthere.Test results
tests/gateway/test_api_server.py::TestAuth— 7 passed (5 existing + 2 new); existing valid/invalid/missing/malformed-header cases unchanged.TypeError: comparing strings with non-ASCII characters is not supportedat the_check_authcomparison; post-fix they return a clean 401 / authenticate correctly.tests/gateway/test_api_server.py(full file) — 197 passed, 1 skipped, no new failures.