Severity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L
Remote unauthenticated token bypass (AV:N/PR:N/UI:N); AC:L since the traversal token is deterministic against the documented default session; full account read/write gives C:H/I:H with limited availability impact.
Primary rating from Vendor (https://github.com/leshchenko1979/fast-mcp-telegram).
CVSS VectorVendor: https://github.com/leshchenko1979/fast-mcp-telegram
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L
Lifecycle Timeline
3DescriptionCVE.org
Summary
fast-mcp-telegram validates HTTP Bearer tokens by joining the raw token string into a session-file path. The verifier rejects the exact reserved token telegram, but it does not reject path separators or normalize the path before checking whether the session file exists. A remote HTTP client can therefore authenticate as the default legacy session with a token such as ../fast-mcp-telegram/telegram when the documented default session file ~/.config/fast-mcp-telegram/telegram.session exists.
This bypasses the reserved session name control that is intended to prevent HTTP multi-user sessions from colliding with the default stdio or legacy account. With account-prefixed MCP tools enabled, the attacker still sees and calls the prefixed tools for the default account, so the prefix middleware does not stop the session selection bypass.
Impact
An unauthenticated network client can access the Telegram account represented by the default telegram.session file without knowing a generated bearer token, if that legacy or default session file is present on a server running HTTP auth. The attacker can then call Telegram MCP tools as that account, including message reading, message sending, MTProto API calls, and attachment-producing tool surfaces available to the session.
Technical details
SessionFileTokenVerifier.verify_token() strips whitespace and rejects exact reserved names:
if token.lower() in RESERVED_SESSION_NAMES:
return NoneIt then appends .session to the raw token and checks the resulting path:
session_path = self._session_directory / f"{token}.session"
if not session_path.is_file():
return NoneNo check rejects /, \\, .., absolute paths, or resolved paths outside the configured session directory. The session client path is built the same way in src/client/connection.py:
session_path = SESSION_DIR / f"{token}.session"
client = await _build_telegram_client_for_token(session_path, token)With the default session directory, the token ../fast-mcp-telegram/telegram resolves as follows:
~/.config/fast-mcp-telegram/../fast-mcp-telegram/telegram.session
= ~/.config/fast-mcp-telegram/telegram.sessionThe exact token telegram is denied, but the traversal alias reaches the same file and is accepted. This is especially important because telegram is the documented default session_name, and the security documentation says reserved names are blocked to prevent conflicts with stdio and HTTP no-auth sessions.
The vulnerable code is present on current master commit 167ab705f1cd09b21e85c370570471fe75a4f8c9 and in release tag 0.19.0 commit 77bdf6d7e5c6a84d87acc423db613e6c6ba30094.
Reproduction
The following proof uses stub session files and stub Telegram clients, so it does not need real Telegram credentials. It validates the auth decision and the eventual session path used by the client builder.
Run on current master:
git clone https://github.com/leshchenko1979/fast-mcp-telegram.git
cd fast-mcp-telegram
python validation_token_traversal.pyThe local proof script created for validation is attached below for reference:
# High-level proof outline
# 1. Create a temporary session directory containing telegram.session and a random token session.
# 2. Instantiate SessionFileTokenVerifier with that directory.
# 3. Verify denied controls: token `telegram` is rejected, and a traversal token to a missing file is rejected.
# 4. Verify allowed control: a normal random token with a matching session file is accepted.
# 5. Verify bypass: token `../fast-mcp-telegram/telegram` is accepted and the client builder receives the default telegram.session path.
# 6. Verify prefix behavior: account-prefixed tools are listed for the traversal-authenticated default account, a prefixed call reaches send_message, and an unprefixed call is still denied.Key controls from the current-master run:
{
"reserved_default_token_denied": true,
"normal_random_token_allowed": true,
"missing_traversal_token_denied": true,
"traversal_alias_to_reserved_default_allowed": true,
"traversal_access_token_value": "../fast-mcp-telegram/telegram",
"client_builder_used_default_session_file": true,
"prefixed_tool_listed_for_traversal_token": "defaultalice_send_message",
"prefixed_tool_call_reached_handler_as": "send_message",
"unprefixed_tool_call_denied_when_prefix_resolved": true
}Interpretation:
- Denied control: the exact reserved token
telegramis rejected. - Allowed control: a normal random session token is accepted when its matching session file exists.
- Denied control: a traversal token pointing to a missing file is rejected.
- Bypass:
../fast-mcp-telegram/telegramauthenticates and the client builder receives the resolved default session path. - Prefix control: once authenticated through the traversal token, account-prefixed tools are listed and a prefixed
tools/callreaches the internalsend_messagehandler. An unprefixed call is rejected when the prefix resolves, so the confirmed bug is the session selection and authentication bypass, not a missing-prefix execution bypass.
Why this crosses the auth boundary
A production HTTP auth deployment is expected to require high-entropy per-session bearer tokens. Reserved names are explicitly blocked because common names such as telegram can collide with the default session. The traversal alias turns the public token namespace back into a filesystem namespace and bypasses that reserved-name policy.
The account-prefix middleware is downstream of authentication. It labels tools based on the resolved Telegram account for the token that was accepted. Because the traversal token is accepted as a valid FastMCP AccessToken, the middleware correctly exposes the default account's prefixed tools to the attacker. It cannot recover the lost authentication boundary.
Remediation
Reject bearer tokens that are not strict opaque token identifiers before using them in file paths. Recommended checks:
- Accept only a safe token alphabet, for example
^[A-Za-z0-9_-]{32,128}$, matching generated URL-safe base64 tokens. - Reject
/,\\,.,.., empty segments, and absolute paths for both header auth and URL auth. - Resolve the final session path and require it to remain directly under the configured session directory:
session_dir = self._session_directory.resolve()
session_path = (session_dir / f"{token}.session").resolve()
if session_path.parent != session_dir:
return None- Apply the same validation in
SessionFileTokenVerifier, URL auth middleware, setup flows, cleanup code, and any code that opens session files by token. - Add regression tests for exact reserved names, traversal aliases such as
../fast-mcp-telegram/telegram, absolute paths, URL-encoded traversal if any route decodes path components, Windows separators, and normal generated tokens.
Articles & Coverage 1
AnalysisAI
Authentication bypass via path traversal in the fast-mcp-telegram MCP server (Python, PyPI package fast-mcp-telegram, master through release 0.19.0) lets a remote client hijack the default Telegram account without a valid bearer token. The SessionFileTokenVerifier blocks the exact reserved token 'telegram' but fails to normalize path separators, so a token like '../fast-mcp-telegram/telegram' resolves back to the default ~/.config/fast-mcp-telegram/telegram.session file and is accepted. …
Unlock full vulnerability intelligence
- Risk assessment & exploitation conditions
- Attack chain visualization
- Remediation with exact patch versions
- Threat intelligence from 22 sources
- Personal watchlist & email alerts
Free forever · No credit card required
Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata
Vulnerability AssessmentAI
| Exploitation | Exploitation requires the server to be deployed in HTTP authentication mode (SessionFileTokenVerifier active) AND the default/legacy session file ~/.config/fast-mcp-telegram/telegram.session to exist in the configured session directory - the traversal token '../fast-mcp-telegram/telegram' only succeeds because it resolves to that specific existing file. … Additional conditions and limiting factors are described in the full assessment. |
| Risk Assessment | The signals are largely consistent toward high severity but the real-world footprint is small. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in. |
| Exploit Scenario | An attacker discovers an internet-reachable fast-mcp-telegram HTTP endpoint that requires bearer-token auth and, without knowing any generated token, sends a request with the bearer token '../fast-mcp-telegram/telegram'; the verifier normalizes this back to the default telegram.session file, which exists on the host, and accepts the request as a valid session. The attacker then calls account-prefixed MCP tools (e.g. … |
| Remediation | No vendor-released fixed version was identified in the provided data (the advisory GHSA-rxw2-pc8j-vxwm describes the flaw and recommended code fix but no tagged patched release is confirmed here), so treat the fix as an upstream code remediation to apply or verify against a patched build before deploying. … Detailed patch versions, workarounds, and compensating controls in full report. |
Recommended ActionAI
Within 24 hours: Identify all systems running fast-mcp-telegram ≤0.19.0; restrict network access via firewall rules or immediately uninstall the package. …
Sign in for detailed remediation steps and compensating controls.
Threat intelligence, references, and detailed analysis are available after sign-in.
Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t
BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser
pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi
The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python
BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica
OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph
pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.
In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne
Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301
Cross-user flow execution in Langflow (< 1.9.1) lets any authenticated API-key holder run another user's flow by passing
Same weakness CWE-22 – Path Traversal
View allSame technique Authentication Bypass
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-41438
GHSA-rxw2-pc8j-vxwm