Carry-over P1 findings from codex review of #260 and #262 (both merged as critical bypass fixes — these items are hardening of an already-correct fix, not unfixed bypasses).
From #260 (vllm_mlx/routes/health.py)
From #262 (vllm_mlx/middleware/auth.py)
Why follow-up, not block-merge
None of these are exploitable bypasses. The base merged PRs close active CRITICAL bypasses (anyone could DELETE the cache, anyone could call Anthropic routes); the bypass cost > the residual hardening cost. These items are tracked here so the security posture keeps improving.
Refs: #189 (closed by #260), #188 (closed by #262), and the new SOP §0–§9 in docs/development/pr_merge_sop.md.
Carry-over P1 findings from codex review of #260 and #262 (both merged as critical bypass fixes — these items are hardening of an already-correct fix, not unfixed bypasses).
From #260 (
vllm_mlx/routes/health.py)--api-keyis set, k8s/Docker liveness probes callingGET /healthand/health/readywill now get 401. Updatedocs/guides/server.mdto document this and provide probe-config examples (Bearer token inhttpHeadersfor k8s liveness probes, or split unauthenticated liveness from authenticated management/cache routes).test_health_router_accepts_valid_api_key: replaceassert r.status_code != 401with explicit per-route expected status codes — the current assertion would pass on 5xx or a broken handler.From #262 (
vllm_mlx/middleware/auth.py)_extract_bearer_tokenshould.strip()the token afterpartition(\" \"). CurrentlyBearer test-secretandBearer test-secretare auth-equivalent (HTTPBearer normalizes for auth) but route to different rate-limit buckets.x-api-keyheader:request.headers.get(\"x-api-key\")only evaluates one value. Userequest.headers.getlist(\"x-api-key\")and either require exactly one value or require all to match — the "both must match" rule should extend to multi-valued headers._verify_api_key_values()filters falsy values, soAuthorization: Bearer test-secretplusx-api-key:(empty) is accepted. If the rule is "if a credential header is present, it must be valid," presence needs to be checked separately from extracted credential value.all(secrets.compare_digest(...))short-circuits on first mismatch, leaking which header failed via timing. Replace with non-short-circuit accumulation (valid &= compare_digest(...)).secrets.compare_digest(str, str)raisesTypeErrorfor non-ASCII strings. An invalidx-api-keywith non-ASCII bytes can produce a 500 instead of 401. Encode to bytes with strict policy or catchTypeErrorand reject as 401.tests/test_anthropic_route_auth.pyanthropic_clientfixture restoressys.modulesand parent attrs only afteryield. If an import or setup step fails beforeyield, parent module attributes can remain monkeypatched. Wrap setup intry/finallyor usemonkeypatchfor parent attrs too.Why follow-up, not block-merge
None of these are exploitable bypasses. The base merged PRs close active CRITICAL bypasses (anyone could DELETE the cache, anyone could call Anthropic routes); the bypass cost > the residual hardening cost. These items are tracked here so the security posture keeps improving.
Refs: #189 (closed by #260), #188 (closed by #262), and the new SOP §0–§9 in
docs/development/pr_merge_sop.md.