---
id: 2026-10-praktor-claude-code-telegram-orchestrator-upload-traversal-stored-instruction-injection-cve-2026-62331-fixed-0-9-1
title: "praktor, a Telegram-driven Claude Code orchestrator: an upload filename writes CLAUDE.md into the agent workspace, no auth by default (CVE-2026-62331, 8.2); fixed 0.9.1"
date_disclosed: 2026-10-30
last_updated: 2026-11-04
severity: high
status: patched
ecosystems: [go, claude-code, telegram, docker, ai-agents]
tools_affected: ["praktor before 0.9.1 (github.com/mtzanidakis/praktor), self-hosted with Docker Compose", "the Claude Code agents it runs: their persistent workspace volumes, CLAUDE.md, skills, hooks and configuration", "any operator who left telegram.allow_from empty"]
tags: [path-traversal, stored-prompt-injection, claude-code, telegram-bot, agent-orchestrator, default-no-auth, cwe-22, github-cna, vulncheck-listing, patched]
---

## TL;DR
praktor, a self-hosted Go service that routes Telegram messages to Claude Code agents running in Docker containers, wrote uploaded Telegram documents to a path built from the attacker-controlled filename, so a filename with `..` segments landed anywhere in the agent's persistent workspace volume, including `CLAUDE.md`, skill, hook and configuration files the agent reads on every run. With the default `allow_from: []` every Telegram user can message the bot, so no authentication is needed. The vendor advisory (2026-06-26) and CVE-2026-62331 (GitHub CNA, 2026-10-30, CVSS 3.1 8.2) say the fix is 0.9.1. The GitHub Advisory Database reviewed it on 2026-11-03. Upgrade, and set `telegram.allow_from` to the user ids you trust.

## What happened

**The vendor advisory.** GHSA-48v2-6jcm-fc99, published 2026-06-26 by the maintainer, describes praktor as an agent system with a Telegram bot interface where each agent runs a Claude agent against a persistent workspace volume mounted at `/workspace/agent`. Two upload sites in `internal/telegram/bot.go` concatenated the attacker-controlled filename into the destination path, and `path.Join` collapsed the `../` sequences, so a filename such as `../../../CLAUDE.md` resolved to the root of the workspace volume instead of `uploads/`. "Because the agent reads from and operates on this workspace across runs, an attacker can plant or overwrite files it later consumes", which the advisory calls stored instruction injection into the agent's execution surface. Reachability: "By default, `allow_from: []` means all users are allowed. The only precondition is that a user can message the bot." The fix in PR 228 applies `path.Base()` to the filename at both sites and makes `WriteVolumeBytes` reject any path that escapes the volume. The workaround is to restrict `telegram.allow_from`. The reporter is credited as tonghuaroot, who the advisory says supplied the root-cause analysis and verified the fix.

**The record.** CVE-2026-62331 (GitHub_M CNA, published 2026-10-30 19:00 UTC, four months after the vendor advisory) carries the same description, affected `< 0.9.1`, CVSS 3.1 8.2 `AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N`, CWE-22, and references the advisory, PR 228, the fix commit and the v0.9.1 release tag. The database row appeared on 2026-11-03 in the `agent` and `claude` queries as a reviewed Go advisory for `github.com/mtzanidakis/praktor`. The repository has 45 stars and 10 forks when read. The README describes a single Go binary deployed with Docker Compose, with the agent image built locally because it cannot be distributed pre-built, and a Mission Control UI on port 8080.

**Why it is here.** The scale is small. The shape is not: a chat-channel front end to a coding agent, with no allowlist by default, where a file upload becomes the agent's instructions on its next run. The corpus has the same shape at larger scale in the [AGENTS.md-in-Downloads](2026-10-agents-md-in-downloads-folder-hijacks-coding-agents-started-there-function-color-npm.md) and [GitSpawn](2026-09-gitspawn-git-config-agent-rce-cluster.md) files. This one adds the remote write primitive. A workspace that persists across runs is the agent's memory, and anything that can write into it writes the agent's future behaviour.

## Am I affected?

1. **Version:** the praktor binary or image you built; anything before 0.9.1 (the advisory lists 0.9.0 and earlier, including HEAD at commit `3902d29`).
2. **Config:** `telegram.allow_from` in `config/praktor.yaml`. An empty list means every Telegram user who finds the bot can message it and upload to it.
3. **Workspace:** list the root of each `praktor-wk-<workspace>` volume for files outside `uploads/` that your team did not create, in particular `CLAUDE.md`, `.claude/` skills and hooks, and any file whose name starts with `..`.

## If you are affected

- Upgrade to 0.9.1 or later and set `telegram.allow_from` to explicit user ids.
- Treat any workspace with an unexplained file at its root as a compromised agent: read the planted instructions, assume every run since the file's modification time followed them, and review what those agents had credentials for. See [if your local AI agent was exploited](../playbooks/if-your-local-ai-agent-was-exploited.md).
- Rotate the Claude Code credentials and any tokens mounted into the agent containers.

## Prevention

- A chat bot that drives a coding agent is an internet-facing API. Allowlist senders before the first run. See [agent sandboxing](../prevention/agent-sandboxing.md).
- Do not let uploads land in the directory the agent reads instructions from. Keep `uploads/` on a separate mount.

## Sources
- [mtzanidakis/praktor — GHSA-48v2-6jcm-fc99](https://github.com/mtzanidakis/praktor/security/advisories/GHSA-48v2-6jcm-fc99) — fetched 2026-11-04: published 2026-06-26, the mechanism, the `allow_from` default, the fix and workaround, credit tonghuaroot, references.
- [CVE Services — CVE-2026-62331](https://cveawg.mitre.org/api/cve/CVE-2026-62331) — fetched 2026-11-04: GitHub_M CNA, published 2026-10-30, affected `< 0.9.1`, CVSS 3.1 8.2 and vector, CWE-22, the four references.
- [GitHub Advisory Database — `agent` query, newest first](https://github.com/advisories?query=agent+sort%3Apublished-desc) and [`claude` query](https://github.com/advisories?query=claude+sort%3Apublished-desc) — fetched 2026-11-04: the reviewed row dated 2026-11-03, High, Go.
- [mtzanidakis/praktor](https://github.com/mtzanidakis/praktor) — fetched 2026-11-04: the description, 45 stars, 10 forks, the README's deployment notes; the releases section rendered empty, so the 0.9.1 date is taken from the CNA's reference to the tag, not read.
- Related in this corpus: [AGENTS.md in the Downloads folder](2026-10-agents-md-in-downloads-folder-hijacks-coding-agents-started-there-function-color-npm.md), [GitSpawn git-config agent RCE cluster](2026-09-gitspawn-git-config-agent-rce-cluster.md).
