CVE-2026-52830: Verified Repro With Script Download
CVE-2026-52830: fast-mcp-telegram <=0.19.0 allows bearer token path traversal to authenticate as the default telegram.session, bypassing reserved session name protections and enabling unauthorized access to Telegram MCP tools.
CVE-2026-52830 is verified against fast-mcp-telegram · pip. Affected versions: <= 0.19.0. Fixed in 0.19.1. Vulnerability class: Path Traversal. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00218.
What Is CVE-2026-52830?
CVE-2026-52830 is a critical path-traversal vulnerability (CWE-22, CVSS 9.4) in fast-mcp-telegram that lets a remote HTTP client authenticate as the default Telegram session by supplying a traversal alias as the bearer token. Pruva reproduced it (reproduction REPRO-2026-00218).
CVE-2026-52830 Severity & CVSS Score
CVE-2026-52830 is rated critical severity, with a CVSS base score of 9.4 out of 10.
Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.
Affected fast-mcp-telegram Versions
fast-mcp-telegram · pip versions <= 0.19.0 are affected.
How to Reproduce CVE-2026-52830
pruva-verify REPRO-2026-00218 curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00218/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-52830
- reached the target end-to-end
- on the real production code path
- high confidence
- the upstream fix blocks the same trigger
HTTP Bearer token containing path traversal, e.g., ../fast-mcp-telegram/telegram
- POST /v1/mcp (authenticated MCP endpoint) with the traversal Bearer token
reproduction_steps.sh Alternate traversal alias ./telegram in the Authorization header bypasses the reserved-name check in fast-mcp-telegram <= 0.19.0 and resolves to the default telegram.session, enabling the same authz bypass as the parent CVE. The alias is blocked by the 0.19.1 token whitelist, so it is not a fix bypass.
How the agent worked
Root Cause and Exploit Chain for CVE-2026-52830
fast-mcp-telegram <= 0.19.0 uses the raw HTTP Bearer token as a file-name fragment when building a session-file path. It checks the token against a set of reserved names (e.g. telegram) but never rejects path separators or normalizes the result. A token such as ../fast-mcp-telegram/telegram therefore resolves to the same reserved telegram.session file that the exact name check is meant to protect, while bypassing the name check. A remote HTTP client who knows the target session directory layout can authenticate as the default account and list or invoke the exposed Telegram MCP tools.
- Package/component: fast-mcp-telegram (PyPI), specifically
src.server_components.session_token_verifier.SessionFileTokenVerifierandsrc.server_components.auth_middleware.UrlTokenMiddleware. - Affected versions:
<= 0.19.0. - Patched version:
0.19.1. - Risk level: High. A remote, unauthenticated attacker can bypass bearer-token authentication and gain access to the victim's Telegram MCP tools as the default session without any Telegram credentials.
- Consequences: Unauthorized access to tools such as
get_messages,send_message,send_message_to_phone,invoke_mtproto, etc., under the identity of the defaulttelegramsession.
Impact Parity
- Disclosed/claimed maximum impact: Authorization bypass via HTTP Bearer token path traversal (
api_remote/authz_bypass). - Reproduced impact from this run: Real HTTP auth bypass on a running
fast-mcp-telegram0.19.0 instance. The reserved tokentelegramis rejected (HTTP 401), while the traversal alias../fast-mcp-telegram/telegramis accepted (HTTP 200) and returns the protectedtools/listresponse. The patched 0.19.1 build rejects the same traversal token (HTTP 401). - Parity:
fullfor the claimed auth-bypass surface; the reproduction exercises the actual remote HTTP API and reaches the authenticated MCP path. - Not demonstrated: We did not demonstrate actual Telegram message exfiltration or message sending, because no real Telegram session credentials are configured. However, the auth layer is clearly bypassed and the tool list is exposed, proving the claimed authorization bypass.
Root Cause
In src/server_components/session_token_verifier.py (0.19.0), verify_token() does:
if token.lower() in RESERVED_SESSION_NAMES:
return None
session_path = self._session_directory / f"{token}.session"
if not session_path.is_file():
return None
return AccessToken(token=token, ...)
The reserved-name check is exact and case-insensitive, but the token string is then inserted directly into the path with only a .session suffix. Because pathlib.Path does not normalize .. in the operand, the token ../fast-mcp-telegram/telegram yields:
<session_dir>/../fast-mcp-telegram/telegram.session
When session_dir is the default ~/.config/fast-mcp-telegram, this resolves to ~/.config/fast-mcp-telegram/telegram.session, the same default session file the exact-name check is trying to protect. The same vulnerable path construction is also present in UrlTokenMiddleware, which rewrites the URL token into the Authorization header.
The 0.19.1 fix introduces src/server_components/session_token_validation.py. It validates the token against a strict ^[A-Za-z0-9_-]{43}$ pattern and uses session_file_path(), which resolves the constructed path and verifies it is still inside session_dir with is_relative_to(). Any traversal sequence or reserved name is rejected before the file existence check.
Reproduction Steps
Run the self-contained script:
bash bundle/repro/reproduction_steps.sh
The script:
- Reads
bundle/project_cache_context.jsonand uses the providedproject_cache_dirfor persistent Python venvs. - Creates two virtual environments, installing
fast-mcp-telegram==0.19.0(vulnerable) and==0.19.1(fixed). - Creates a controlled
HOMEand default session directory~/.config/fast-mcp-telegram, then touchestelegram.sessionso the default session exists. - Starts each version in
http-authmode on a different localhost port and waits for/healthto return 200. - Sends a JSON-RPC
tools/listrequest toPOST /v1/mcpwith three different bearer tokens on the vulnerable server:telegram(reserved, expected 401)../fast-mcp-telegram/telegram(traversal alias, expected 200)invalid-token(no matching session file, expected 401)
- Sends the same traversal token to the fixed server (expected 401).
- Writes
bundle/repro/runtime_manifest.jsonand exits 0 only when the expected statuses are observed.
Expected evidence
repro/artifacts/http_vuln_reserved.txtandhttp_vuln_noauth.txt: HTTP 401 response body.repro/artifacts/http_vuln_traversal.txt: HTTP 200 SSE event containing the fulltools/listresult.repro/artifacts/http_fixed_traversal.txt: HTTP 401 response body from the patched version.logs/server_vuln.logandlogs/server_fixed.log: server startup logs showing modehttp-authand the session directory.
Evidence
Captured artifacts:
bundle/repro/artifacts/http_vuln_traversal.txt(HTTP 200, tools list returned)bundle/repro/artifacts/http_vuln_reserved.txt(HTTP 401, reserved token rejected)bundle/repro/artifacts/http_vuln_noauth.txt(HTTP 401, invalid token rejected)bundle/repro/artifacts/http_fixed_traversal.txt(HTTP 401, traversal token rejected on 0.19.1)bundle/logs/server_vuln.logbundle/logs/server_fixed.logbundle/repro/runtime_manifest.jsonbundle/logs/reproduction_steps.logbundle/logs/reproduction_steps_run2.log
Key excerpt from the vulnerable traversal response (first line only for brevity):
event: message\r\n
data: {"jsonrpc":"2.0","id":1,"result":{"tools":[{"name":"search_messages_globally", ...
This demonstrates that the protected tools/list endpoint returned successfully using only the traversal token.
The fixed server log confirms the same traversal token now returns HTTP 401:
{"error": "invalid_token", "error_description": "Authentication failed..."}
Environment details captured in the logs: Python 3.14, uvicorn, fastmcp-slim 3.4.2, fast-mcp-telegram 0.19.0 / 0.19.1, session directory repro/fakehome/.config/fast-mcp-telegram.
Recommendations / Next Steps
- Upgrade to
fast-mcp-telegram >= 0.19.1, which enforces a strict token format and resolves/session-directory containment checks. - Network-level mitigation until patched: restrict access to the MCP HTTP port so only trusted clients can reach it.
- Detection: monitor authentication logs for tokens containing path separators or unusual patterns.
- Testing recommendation: add regression tests that attempt tokens such as
../session,..\\session,telegram, and/etc/passwdand assert they are rejected before any file existence check.
Additional Notes
- The script was run twice consecutively from a clean project-cache state; both runs exited 0 and produced the same status sequence (401, 200, 401 on vulnerable; 401 on fixed), confirming idempotency.
- The GitHub source repository for fast-mcp-telegram was not directly reachable in this environment, so the reproduction relies on the official PyPI wheels. The relevant source code is visible in the installed site-packages and confirms the vulnerable
Pathconcatenation in 0.19.0 and the newsession_token_validation.pycontainment check in 0.19.1. - No real Telegram credentials or network connectivity to Telegram are required for the reproduction; the bypass is demonstrated purely against the local authentication layer.
Variant Analysis & Alternative Triggers for CVE-2026-52830
The patched fast-mcp-telegram 0.19.1 closes the original path-traversal bearer-token bypass. This variant analysis finds a distinct alternate traversal alias on the vulnerable 0.19.0 version: the reserved session name telegram can be addressed as ./telegram in the HTTP Authorization header. Because the vulnerable code only checks the exact lowercase string against a reserved-name set, the relative-path alias ./telegram bypasses the check and resolves to the same telegram.session file, granting unauthorized access to the Telegram MCP tools. The alias reproduces on 0.19.0 but is blocked by the 0.19.1 whitelist, so it is not a bypass of the fix.
Fix Coverage / Assumptions
The 0.19.1 fix assumes that all legitimate bearer tokens are produced by the package’s generate_bearer_token() helper and therefore match the strict regular expression ^[A-Za-z0-9_-]{43}$. It enforces this assumption in a new module (src/server_components/session_token_validation.py) and propagates it to every token-bearing code path:
src/server_components/session_token_verifier.py(FastMCPTokenVerifierfor/v1/mcp)src/server_components/auth_middleware.py(URL-token middleware/v1/url_auth/{token}/mcp)src/server_components/auth.py(Authorization header extraction)src/client/connection.py(TelegramClient session construction and cleanup)src/server_components/web_setup.py(setup, reauthorize, and delete flows)
The fix also resolves the constructed path and verifies it is still inside the configured session directory using is_relative_to().
Variant / Alternate Trigger
Variant: Bearer token ./telegram (and other relative-path aliases of the reserved name) used in the Authorization: Bearer ./telegram header.
Entry point: POST /v1/mcp with the JSON-RPC body {"jsonrpc":"2.0","id":1,"method":"tools/list"}.
Code path:
- FastMCP auth layer calls
SessionFileTokenVerifier.verify_token()insrc/server_components/session_token_verifier.py. - In
0.19.0, the verifier checkstoken.lower() in RESERVED_SESSION_NAMES. The literal string./telegramis not in the set, so it passes. - The verifier builds
session_path = self._session_directory / f"{token}.session". Pathlib normalizes./telegram.sessiontotelegram.session, which exists, so the token is accepted. - The request is authorized as the default session and
tools/listreturns the full tool catalog.
Other equivalent aliases confirmed on 0.19.0 include ../fast-mcp-telegram/telegram (the original reproducer) and fast-mcp-telegram/../telegram. The URL-token entry point (/v1/url_auth/./telegram/mcp) was also tested; Starlette/uvicorn normalize the /./ segment before the vulnerable middleware sees it, so the URL path is rejected as the reserved name telegram. The header-based path remains exploitable with the alias.
- Package/component:
fast-mcp-telegram(PyPI), specificallySessionFileTokenVerifierand the FastMCP HTTP auth layer. - Affected versions:
<= 0.19.0. - Patched version:
0.19.1. - Risk level: High for the vulnerable version. The impact is identical to the original CVE: a remote, unauthenticated attacker who can reach the MCP HTTP port can authenticate as the default
telegramsession and list/invoke tools. - Consequences: Unauthorized access to tools such as
get_messages,send_message,send_message_to_phone, andinvoke_mtprotounder the default session identity.
Impact Parity
- Disclosed/claimed maximum impact: Authorization bypass via HTTP Bearer token path traversal (
api_remote/authz_bypass). - Reproduced impact from this variant run: Real HTTP auth bypass on a running
fast-mcp-telegram 0.19.0instance using the./telegramalias. The reserved tokentelegramis rejected (HTTP 401), the alias./telegramis accepted (HTTP 200) and returns the protectedtools/listresponse, and the patched0.19.1build rejects the alias (HTTP 401). - Parity:
fullfor the claimed auth-bypass surface on the vulnerable version; the variant demonstrates the same impact through a different token string. The variant does not achieve impact on the fixed version. - Not demonstrated: Tool invocation with the bypassed session; only the
tools/listendpoint was exercised. No Telegram credentials were configured, so no actual Telegram RPC was performed.
Root Cause
The root cause is the same as the parent CVE: the bearer token is used as a raw filename fragment without validating that it is a safe token or normalizing the resulting path. The vulnerable SessionFileTokenVerifier.verify_token() only performs an exact reserved-name check:
if token.lower() in RESERVED_SESSION_NAMES:
return None
session_path = self._session_directory / f"{token}.session"
if not session_path.is_file():
return None
This allows any relative-path alias of a reserved name (e.g., ./telegram) to bypass the name check while still resolving to the same file. The same pattern exists in auth_middleware.py, auth.py, and client/connection.py, but the auth-bypass surface is most directly reached through the MCP tools endpoint.
The 0.19.1 fix replaces this logic with a strict whitelist (^[A-Za-z0-9_-]{43}$) and a containment check, so the alias cannot be used.
Reproduction Steps
Run the self-contained variant script:
bash bundle/vuln_variant/reproduction_steps.sh
The script:
- Reads
bundle/project_cache_context.jsonand uses the providedproject_cache_dirfor persistent Python venvs (or installs them locally if absent). - Creates two virtual environments, installing
fast-mcp-telegram==0.19.0(vulnerable) and==0.19.1(fixed). - Creates a controlled
HOMEand default session directory~/.config/fast-mcp-telegram, then touchestelegram.sessionso the default session exists. - Starts each version in
http-authmode on a different localhost port and waits for/healthto return 200. - Sends a JSON-RPC
tools/listrequest toPOST /v1/mcpwith several bearer tokens on the vulnerable server:telegram(reserved, expected 401)./telegram(alternate traversal alias, expected 200)../fast-mcp-telegram/telegram(original traversal, expected 200)invalid-token(no matching session file, expected 401)
- Also sends the
./telegramtoken via the URL-auth entry point (/v1/url_auth/./telegram/mcp) on the vulnerable server to document the normalization behavior (expected 401). - Sends the
./telegramand../fast-mcp-telegram/telegramtokens to the fixed server (expected 401 for both). - Writes
bundle/vuln_variant/runtime_manifest.jsonand exits 1 (the variant is an alternate trigger on the vulnerable version, not a bypass of the fix).
Expected evidence
vuln_variant/artifacts/http_vuln_reserved.txt: HTTP 401 response body.vuln_variant/artifacts/http_vuln_dot_slash.txt: HTTP 200 SSE event containing the fulltools/listresult.vuln_variant/artifacts/http_vuln_original.txt: HTTP 200 SSE event from the original traversal token (sanity check).vuln_variant/artifacts/http_vuln_invalid.txt: HTTP 401 response body.vuln_variant/artifacts/http_vuln_url_dot_slash.txt: HTTP 401 response body (URL normalization/middleware rejection).vuln_variant/artifacts/http_fixed_dot_slash.txtandhttp_fixed_original.txt: HTTP 401 response bodies from the patched version.logs/server_vuln_variant.logandlogs/server_fixed_variant.log: server startup logs.
Evidence
Captured artifacts:
bundle/vuln_variant/artifacts/http_vuln_dot_slash.txt(HTTP 200, tools list returned)bundle/vuln_variant/artifacts/http_vuln_reserved.txt(HTTP 401, reserved token rejected)bundle/vuln_variant/artifacts/http_vuln_original.txt(HTTP 200, original traversal still works)bundle/vuln_variant/artifacts/http_vuln_invalid.txt(HTTP 401, invalid token rejected)bundle/vuln_variant/artifacts/http_vuln_url_dot_slash.txt(HTTP 401, URL entry point rejected)bundle/vuln_variant/artifacts/http_fixed_dot_slash.txt(HTTP 401, alias blocked on 0.19.1)bundle/vuln_variant/artifacts/http_fixed_original.txt(HTTP 401, original traversal blocked on 0.19.1)bundle/vuln_variant/artifacts/http_fixed_url_dot_slash.txt(HTTP 401, alias blocked on 0.19.1)bundle/logs/server_vuln_variant.logbundle/logs/server_fixed_variant.logbundle/logs/variant_reproduction_steps_run2.logbundle/vuln_variant/runtime_manifest.json
Key excerpt from the vulnerable ./telegram response (first line):
event: message\r\n
data: {"jsonrpc":"2.0","id":1,"result":{"tools":[{"name":"search_messages_globally", ...
This demonstrates that the protected tools/list endpoint returned successfully using the ./telegram alias.
The fixed server log confirms the same alias now returns HTTP 401 (token rejected by the whitelist before any file existence check).
Environment details captured in the logs: Python 3.14, uvicorn, fastmcp-slim 3.4.2, fast-mcp-telegram 0.19.0 / 0.19.1, session directory bundle/vuln_variant/fakehome/.config/fast-mcp-telegram.
Recommendations / Next Steps
- Upgrade to
fast-mcp-telegram >= 0.19.1; the whitelist and containment check close this variant as well as the original traversal. - Regression tests: add test cases for relative-path aliases (
./telegram,telegram/../telegram,../fast-mcp-telegram/telegram) and confirm they are rejected before any file existence check. - Network-level mitigation: restrict access to the MCP HTTP port to trusted clients until patched.
- Detection: monitor authentication logs for tokens containing path separators or unusual patterns.
- Hardening: ensure the session directory is not writable by the server process except through the intended setup flows, and avoid placing other sensitive files in the same directory tree.
Additional Notes
- The script was run twice consecutively; both runs produced the same status sequence (401, 200, 200, 401, 401 on vulnerable; 401, 401, 401 on fixed), confirming idempotency.
- The GitHub source repository was not directly reachable in this environment, so the reproduction relies on the official PyPI wheels. The relevant source code is visible in the installed site-packages and confirms the vulnerable
Pathconcatenation in 0.19.0 and the newsession_token_validation.pycontainment check in 0.19.1. - No real Telegram credentials or network connectivity to Telegram are required for the reproduction; the bypass is demonstrated purely against the local authentication layer.
- The URL-token entry point (
/v1/url_auth/...) does not provide a practical variant for./telegrambecause Starlette/uvicorn normalize the/./path segment before the vulnerable middleware can extract the alias. The URL-token path is documented in the reproduction script to show that the alternate input form was considered. - The variant is an alternate trigger, not a fix bypass:
./telegramsucceeds on0.19.0but is rejected by the0.19.1whitelist.
CVE-2026-52830 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
git clone https://github.com/leshchenko1979/fast-mcp-telegram.git /data/pruva/project-cache/1d059d1a-e237-49eb-a82c-16f81b45ee9b/repoCloning into '/data/pruva/project-cache/1d059d1a-e237-49eb-a82c-16f81b45ee9b/repo'... fatal: could not read Username for 'https://github.com': No such device or address
Artifacts and Evidence for CVE-2026-52830
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-52830
Upgrade fast-mcp-telegram · pip to 0.19.1 or later.
FAQ: CVE-2026-52830
How does the CVE-2026-52830 bearer-token bypass work?
Which fast-mcp-telegram versions are affected by CVE-2026-52830, and where is it fixed?
How severe is CVE-2026-52830?
How can I reproduce CVE-2026-52830?
References for CVE-2026-52830
Authoritative sources for CVE-2026-52830 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.