fix(middleware): restore host-port stripping in AllowedHostsMiddleware#4922
fix(middleware): restore host-port stripping in AllowedHostsMiddleware#4922chuenchen309 wants to merge 1 commit into
Conversation
Requests with a Host header that includes a port (e.g. `example.com:8080`) were incorrectly rejected with 400, even when the bare hostname was in `allowed_hosts`. Commit c418961 ("fix: fix typing after merge") changed the walrus assignment to only use `host.split(":")[0]` for a truthiness check, without rebinding `host` to the stripped value — so the full header (with port) was passed to `allowed_hosts_regex.fullmatch()`, which never matches a bare-hostname pattern. Fix: rebind `host` via a second walrus assignment so the stripped value is what's actually used downstream. How verified: traced the regression to c418961 via `git log -p --follow` on this file, reproduced with a standalone ASGI repro script, added a parametrize case to the existing test_middleware_allowed_hosts test (confirmed it fails with the old code: assert 400 == 200), applied the one-line fix, confirmed all 14 tests in this file pass, then ran the full unit/test_middleware/ suite (776 passed, no regressions). mypy clean, pre-commit clean (ruff, unasyncd, typos). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4922 +/- ##
=======================================
Coverage 67.29% 67.29%
=======================================
Files 293 293
Lines 15228 15228
Branches 1728 1728
=======================================
Hits 10248 10248
Misses 4833 4833
Partials 147 147 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Thanks for the review time on this — I found while doing some further digging that #4873 already fixes this exact regression (referencing #4869), opened back on 2026-06-20, well before my independent discovery of it today. Since it's the same root cause and fix, I'll close this one in favor of the earlier PR rather than duplicate the review effort. Apologies for not catching the existing PR before submitting — will be more careful to cross-check open PRs against the exact file path before starting work in the future. |
There was no review |
What
A request whose
Hostheader includes a port (e.g.example.com:8080) is incorrectly rejected with 400 byAllowedHostsMiddleware, even when the bare hostname (example.com) is present inallowed_hosts.Root cause
Commit c418961 ("fix: fix typing after merge") changed:
into:
The walrus assignment now binds
hostto the full header value (including any port), andhost.split(":")[0]is only used for a truthiness check — its result is discarded. Soself.allowed_hosts_regex.fullmatch(host)downstream still receives the port-suffixed value, which never matches a bare-hostname regex pattern.Fix
Rebind
hostvia a second walrus assignment so the stripped (port-free) value is what's actually used for matching:How I verified this
git log -p --follow -- litestar/middleware/allowed_hosts.py.AllowedHostsMiddleware.test_middleware_allowed_hoststest (("http://x.example.com:8080", None, HTTP_200_OK)); confirmed it fails on the current code (assert 400 == 200) before the fix.test_allowed_hosts_middleware.pypass.tests/unit/test_middleware/suite: 776 passed, no regressions.mypy litestar/middleware/allowed_hosts.py— clean.pre-commit runon changed files — clean (ruff check/format, unasyncd, typos).Disclosure
I used AI assistance (Claude) to help investigate and draft this fix, but I personally reviewed the root-cause trace, ran the repro and full test suite myself, and reviewed the final diff before submitting. Happy to answer any questions about the change.
📚 Documentation preview 📚: https://litestar-org.github.io/litestar-docs-preview/4922