{"id":"CVE-2026-120492","kind":"vulnerability","aliases":["CVE-2026-120492"],"related":[],"title":"Chainlit 2.12.0: semicolon in MCP URLs bypasses path-restricted allowed_urls","description":"Chainlit 2.12.0 contains a server-side request forgery vulnerability that allows unauthenticated attackers to bypass path-scoped MCP allowed_urls entries because validate_mcp_url does not reject the semicolon character. Attackers can submit MCP URLs with '..;' segments to the /mcp endpoint, causing requests to paths outside the operator's grant on origins that strip semicolon path parameters.","summary":"Chainlit 2.12.0 fails to reject semicolons in MCP URLs, so the allowed_urls path restriction can be bypassed with '..;' segments sent to the /mcp endpoint. An unauthenticated attacker can make the server send requests to paths the operator did not grant, on origins that strip semicolon path parameters.","severity":"medium","cvss":6.3,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"chainlit","fixed":[],"affected":"2.12.0","ecosystem":"pypi"}],"ecosystems":[],"tags":["ai-tooling","chainlit","mcp","python","self-hosted","ssrf"],"not_affected_if":["auth-required","default-config","mcp-disabled","no-mcp"],"how_to_check":"Run 'pip show chainlit'; 2.12.0 is the version VulnCheck lists. Then check .chainlit/config.toml: you are exposed only if features.mcp.enabled = true, features.mcp.user_servers.enabled = true, and allowed_urls has a path-restricted entry (e.g. https://host/api) on a server that strips ';' path parameters (Java servlet containers and some proxies do). Also check whether you have no auth callback, since /mcp is then reachable anonymously. Also check 2.11.x and earlier: they have the broader SSRF CVE-2026-45019, fixed in 2.12.0.","fix":"unknown: no patched version published for this bypass in the sources read. Check Chainlit releases after 2.12.0.","status":"open","published_at":"2026-11-02T15:17:31+00:00","first_seen_at":"2026-11-02T15:24:04+00:00","triaged_at":"2026-11-02T15:26:17+00:00","updated_at":"2026-11-02T15:27:08+00:00","category":"ai-tooling","confidence":0.6,"triage":{"at":"2026-11-02T15:26:17Z","model":"claude-haiku-5-5","output":{"fix":"unknown","reach":"internet","title":"Chainlit: MCP URL check lets unauthenticated users reach forbidden server paths","impact":"medium","summary":"Chainlit 2.12.0 fails to reject semicolons in MCP URLs, so the allowed_urls path restriction can be bypassed with '..;' segments sent to the /mcp endpoint. An unauthenticated attacker can make the server send requests to paths the operator did not grant, on origins that strip semicolon path parameters.","audience":"developers","category":"ai-tooling","nicknames":[],"who_cares":["chainlit","mcp","python","self-hosted"],"confidence":0.6,"fix_status":"unknown","needs_auth":"no","worst_case":"server makes requests to internal paths outside the operator's grant","analyst_note":"Confirm the affected version range and fixed version from the vendor advisory on github.com and the VulnCheck advisory.","how_to_check":"- Check the installed Chainlit version with `pip show chainlit` and see whether it is `2.12.0`.\n- Look for MCP configuration with `allowed_urls` entries in the Chainlit config.\n- unknown for whether the app is reachable from the internet.","plain_action":"","needs_analyst":true,"not_affected_if":["no-mcp","default-config"],"who_is_affected":"Teams running Chainlit 2.12.0 with MCP enabled and path-scoped allowed_urls entries are exposed, because the bypass depends on those restrictions. Deployments without MCP servers configured, or on other versions, are not described as affected. The sources do not say which other versions are affected.","user_interaction":"no","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.000719,"input_tokens":4211,"output_tokens":596,"severity_before":"medium"},"analyst_status":"done","analyst_note":"Confirm the affected version range and fixed version from the vendor advisory on github.com and the VulnCheck advisory.","search":"'-120492':15A,18A '-2026':14A,17A '/mcp':53B,120C '2.12.0':2A,31B,79C 'ai':21B 'ai-tool':20B 'allow':11A,41B,89C,98C 'attack':57B,91C,111C 'bypass':7A,47B,93C 'caus':122C 'chainlit':1A,19A,23B,30B,78C 'charact':110C 'contain':80C 'cve':13A,16A 'endpoint':54B,121C 'entri':100C 'fail':32B 'forgeri':86C 'grant':70B,130C 'host':28B 'make':59B 'mcp':5A,24B,37B,97C,103C,114C 'oper':67B,128C 'origin':72B,132C 'outsid':126C 'paramet':77B,137C 'path':9A,43B,65B,76B,95C,125C,136C 'path-restrict':8A 'path-scop':94C 'python':25B 'reject':34B,107C 'request':63B,85C,123C 'restrict':10A,44B 'scope':96C 'segment':49B,117C 'self':27B 'self-host':26B 'semicolon':3A,35B,75B,109C,135C 'send':62B 'sent':50B 'server':61B,83C 'server-sid':82C 'side':84C 'ssrf':29B 'strip':74B,134C 'submit':113C 'tool':22B 'unauthent':56B,90C 'url':6A,12A,38B,42B,99C,104C,115C 'valid':102C 'vulner':87C","nicknames":[],"mitigations":[],"who_affected":"Chainlit 2.12.0 deployments that turned on MCP (off by default) with user-provided servers and a path-limited allowed_urls entry. A client can send '..;' segments to /mcp and reach other paths on the same origin, but only where the target strips semicolon path parameters. With no auth callback the client needs no login. Skip it if MCP is disabled, if allowed_urls entries are whole origins (nothing to escape), or if you are not on 2.12.0.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"none","audience":"developers","plain_action":null,"pkeys":["chainlit"],"ptokens":["chainlit"],"labels":["aitooling","chainlit","mcp","medium","python","selfhosted","ssrf"],"first_public_at":"2026-08-25T17:06:02+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","cvss_by":"disclosure@vulncheck.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-120492","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-120492","severity":null,"published_at":"2026-11-02T15:17:31+00:00","modified_at":"2026-11-02T15:17:31+00:00","first_seen_at":"2026-11-02T15:24:04+00:00","fetched_at":"2026-11-02T15:24:04+00:00","note":null},{"source":"analyst","external_id":"CVE-2026-120492:1379","url":null,"severity":null,"published_at":"2026-11-02T15:27:08+00:00","modified_at":"2026-11-02T15:27:08+00:00","first_seen_at":"2026-11-02T15:27:08+00:00","fetched_at":"2026-11-02T15:27:08+00:00","note":"Only VulnCheck states this bypass (affects 2.12.0). Linked GHSA-hvfh-5mj3-5f3j is the parent advisory for CVE-2026-45019 (fixed in 2.12.0), not this CVE; no Chainlit page for the semicolon bypass found, no fixed version published as far as I saw. Nothing verified."}],"documents":[{"id":52538,"url":"https://github.com/Chainlit/chainlit/security/advisories/GHSA-hvfh-5mj3-5f3j","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-08-25T17:06:02+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"},{"id":52539,"url":"https://www.vulncheck.com/advisories/chainlit-2.12.0-ssrf-via-semicolon-path-segment-in-mcp-allowed-urls","title":"Third-party advisory: www.vulncheck.com","kind":"advisory","source":"nvd","publisher":"research","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Third-party advisory: www.vulncheck.com"}],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}