mtzanidakis/praktor · Security
praktor: Path traversal in Telegram file uploads allows writing outside the agent workspace uploads/ directory (stored instruction injection)
- GHSA ID
- GHSA-48v2-6jcm-fc99
- CVE ID
- CVE-2026-62331
- Severity
- high
- Published
- Updated
- CVSS
- 8.2 · CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
- CVSS v3
- 8.2 · CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Description
Impact
A remote Telegram user can write files to arbitrary paths inside an agent's persistent workspace volume (praktor-wk-<workspace>, mounted at /workspace/agent), escaping the documented uploads/ directory.
The attacker controls the Telegram document filename, which was concatenated into the destination path without sanitization (internal/telegram/bot.go, at both upload sites) and resolved with path.Join, which collapses ../ sequences. A filename like ../../../CLAUDE.md resolved to the root of the agent workspace volume, outside uploads/.
Because the agent workspace is the persistent working directory the Claude agent reads from and operates on across runs, writing outside uploads/ lets an attacker plant or overwrite files the agent later consumes — e.g. CLAUDE.md, agent instruction/skill/hook files, or other config under /workspace/agent. This turns a file upload into a stored injection into the agent's instruction/execution surface (CWE-22 path traversal escalating to stored instruction injection).
Reachability
By default the bot has no user allowlist (allow_from: [] means "allow all"), so the only precondition is that a user can message the bot. No authentication or prior privilege is required.
Affected versions
Through v0.9.0 (and HEAD 3902d29).
Patched versions
v0.9.1, containing PR #228.
Workarounds
Restrict telegram.allow_from to trusted user IDs to limit who can send uploads to the bot. Upgrading to v0.9.1 is the recommended fix.
Fix (defense in depth)
internal/telegram/bot.go: applypath.Base()to the attacker-controlled filename at both upload sites, stripping directory components and...internal/container/manager.go:WriteVolumeBytesnow rejects any path that escapes/volafterpath.Join, protecting future callers.
Credit
Reported privately by tonghuaroot, who provided a detailed root-cause analysis, a deployed end-to-end proof of concept against the real container.Manager, and fix verification.
CWEs
- CWE-22 · Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
References
- https://github.com/mtzanidakis/praktor/security/advisories/GHSA-48v2-6jcm-fc99 ↗
- https://nvd.nist.gov/vuln/detail/CVE-2026-62331 ↗
- https://github.com/mtzanidakis/praktor/pull/228 ↗
- https://github.com/mtzanidakis/praktor/commit/c3731eeda01c0b3ec1dbd13cccd5a147c3182141 ↗
- https://github.com/mtzanidakis/praktor/releases/tag/v0.9.1 ↗
- https://github.com/advisories/GHSA-48v2-6jcm-fc99 ↗