Litestar has an AllowedHosts validation bypass due to unescaped regex metacharacters in configured host patterns
Description
Litestar is an Asynchronous Server Gateway Interface (ASGI) framework. Prior to 2.20.0, in litestar.middleware.allowed_hosts, allowlist entries are compiled into regex patterns in a way that allows regex metacharacters to retain special meaning (e.g., . matches any character). This enables a bypass where an attacker supplies a host that matches the regex but is not the intended literal hostname. This vulnerability is fixed in 2.20.0.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Litestar’s AllowedHosts middleware prior to 2.20.0 permits regex metacharacters in host allowlist entries, enabling host validation bypass.
Vulnerability
In Litestar versions before 2.20.0, the AllowedHosts middleware compiles allowlist entries (e.g., *.example.com) into regular expressions without properly escaping user-controlled input. This allows regex metacharacters, such as . matching any character, to retain their special meaning, leading to unintended matching of hosts beyond the intended literal domain. [1][3]
Exploitation
An attacker can supply a crafted Host header that, while not matching the literal intended hostname, matches the compiled regex pattern due to unescaped metacharacters. For example, *.example.com would not only match foo.example.com but also examplex.com because . matches any character. [1] This bypass is possible without authentication if the application relies solely on the host validation.
Impact
Successful exploitation allows an attacker to bypass host whitelist restrictions, potentially enabling host header injection or accessing resources intended only for approved domains. In scenarios where the host is used for routing or security decisions, this could lead to further attacks.
Mitigation
The vulnerability is fixed in Litestar 2.20.0 by properly escaping regex metacharacters in allowlist entries. [4] Users should upgrade to version 2.20.0 or later. There are no known workarounds; the fix is included in the 2.20.0 release.
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
litestarPyPI | >= 2.19.0, < 2.20.0 | 2.20.0 |
Affected products
2- Range: <2.20.0
- litestar-org/litestarv5Range: < 2.20.0
Patches
106b36f481d1bfix(allowed hosts): Ensure host names are always properly escaped when used in a regex
2 files changed · +18 −22
litestar/middleware/allowed_hosts.py+2 −1 modified@@ -37,7 +37,8 @@ def __init__(self, app: ASGIApp, config: AllowedHostsConfig) -> None: return allowed_hosts: set[str] = { - rf".*\.{host.replace('*.', '')}$" if host.startswith("*.") else host for host in config.allowed_hosts + rf".*\.{re.escape(host.replace('*.', ''))}$" if host.startswith("*.") else re.escape(host) + for host in config.allowed_hosts } self.allowed_hosts_regex = re.compile("|".join(sorted(allowed_hosts))) # pyright: ignore
tests/unit/test_middleware/test_allowed_hosts_middleware.py+16 −21 modified@@ -33,14 +33,14 @@ def handler() -> None: ... allowed_hosts_middleware, *_ = unpacked_middleware assert isinstance(allowed_hosts_middleware, AllowedHostsMiddleware) - assert allowed_hosts_middleware.allowed_hosts_regex.pattern == ".*\\.example.com$|moishe.zuchmir.com" # type: ignore[union-attr] + assert allowed_hosts_middleware.allowed_hosts_regex.pattern == r".*\.example\.com$|moishe\.zuchmir\.com" # type: ignore[union-attr] def test_allowed_hosts_middleware_hosts_regex() -> None: config = AllowedHostsConfig(allowed_hosts=["*.example.com", "moishe.zuchmir.com"]) middleware = AllowedHostsMiddleware(app=DummyApp(), config=config) # type: ignore[abstract] assert middleware.allowed_hosts_regex is not None - assert middleware.allowed_hosts_regex.pattern == ".*\\.example.com$|moishe.zuchmir.com" + assert middleware.allowed_hosts_regex.pattern == r".*\.example\.com$|moishe\.zuchmir\.com" assert middleware.allowed_hosts_regex.fullmatch("www.example.com") assert middleware.allowed_hosts_regex.fullmatch("other.example.com") @@ -65,33 +65,28 @@ def test_allowed_hosts_middleware_redirect_regex() -> None: assert middleware.redirect_domains.fullmatch("yada.bada.bing.io") -def test_middleware_allowed_hosts() -> None: +@pytest.mark.parametrize( + "base_url,expected_status_code", + [ + ("http://x.example.com", HTTP_200_OK), + ("http://x.y.example.com", HTTP_200_OK), + ("http://moishe.zuchmir.com", HTTP_200_OK), + ("http://moisheAzuchmir.com", HTTP_400_BAD_REQUEST), + ("http://x.moishe.zuchmir.com", HTTP_400_BAD_REQUEST), + ("http://x.example.x.com", HTTP_400_BAD_REQUEST), + ], +) +def test_middleware_allowed_hosts(base_url: str, expected_status_code: int) -> None: @get("/") def handler() -> dict: return {"hello": "world"} config = AllowedHostsConfig(allowed_hosts=["*.example.com", "moishe.zuchmir.com"]) with create_test_client(handler, allowed_hosts=config) as client: - client.base_url = "http://x.example.com" + client.base_url = base_url response = client.get("/") - assert response.status_code == HTTP_200_OK - - client.base_url = "http://x.y.example.com" - response = client.get("/") - assert response.status_code == HTTP_200_OK - - client.base_url = "http://moishe.zuchmir.com" - response = client.get("/") - assert response.status_code == HTTP_200_OK - - client.base_url = "http://x.moishe.zuchmir.com" - response = client.get("/") - assert response.status_code == HTTP_400_BAD_REQUEST - - client.base_url = "http://x.example.x.com" - response = client.get("/") - assert response.status_code == HTTP_400_BAD_REQUEST + assert response.status_code == expected_status_code def test_middleware_allow_all() -> None:
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-93ph-p7v4-hwh4ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-25479ghsaADVISORY
- docs.litestar.dev/2/release-notes/changelog.htmlghsax_refsource_MISCWEB
- github.com/litestar-org/litestar/commit/06b36f481d1bfea6f19995cfb4f203aba45c4aceghsax_refsource_MISCWEB
- github.com/litestar-org/litestar/releases/tag/v2.20.0ghsax_refsource_MISCWEB
- github.com/litestar-org/litestar/security/advisories/GHSA-93ph-p7v4-hwh4ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.