GHSA-48V2-6JCM-FC99

Vulnerability from github – Published: 2026-11-03 17:27 – Updated: 2026-11-03 17:27
VLAI
Summary
praktor: Path traversal in Telegram file uploads allows writing outside the agent workspace uploads/ directory (stored instruction injection)
Details

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: apply path.Base() to the attacker-controlled filename at both upload sites, stripping directory components and ...
  • internal/container/manager.go: WriteVolumeBytes now rejects any path that escapes /vol after path.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.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.9.0"
      },
      "package": {
        "ecosystem": "Go",
        "name": "github.com/mtzanidakis/praktor"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.9.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-62331"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-22"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-11-03T17:27:25Z",
    "nvd_published_at": "2026-10-30T19:18:33Z",
    "severity": "HIGH"
  },
  "details": "### Impact\n\nA remote Telegram user can write files to arbitrary paths inside an agent\u0027s persistent workspace volume (`praktor-wk-\u003cworkspace\u003e`, mounted at `/workspace/agent`), escaping the documented `uploads/` directory.\n\nThe 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/`.\n\nBecause 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 \u2014 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\u0027s instruction/execution surface (CWE-22 path traversal escalating to stored instruction injection).\n\n### Reachability\n\nBy 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.\n\n### Affected versions\n\nThrough `v0.9.0` (and HEAD `3902d29`).\n\n### Patched versions\n\n`v0.9.1`, containing PR #228.\n\n### Workarounds\n\nRestrict `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.\n\n### Fix (defense in depth)\n\n- `internal/telegram/bot.go`: apply `path.Base()` to the attacker-controlled filename at both upload sites, stripping directory components and `..`.\n- `internal/container/manager.go`: `WriteVolumeBytes` now rejects any path that escapes `/vol` after `path.Join`, protecting future callers.\n\n### Credit\n\nReported privately by [tonghuaroot](https://github.com/tonghuaroot), who provided a detailed root-cause analysis, a deployed end-to-end proof of concept against the real `container.Manager`, and fix verification.",
  "id": "GHSA-48v2-6jcm-fc99",
  "modified": "2026-11-03T17:27:25Z",
  "published": "2026-11-03T17:27:25Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/mtzanidakis/praktor/security/advisories/GHSA-48v2-6jcm-fc99"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-62331"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mtzanidakis/praktor/pull/228"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mtzanidakis/praktor/commit/c3731eeda01c0b3ec1dbd13cccd5a147c3182141"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/mtzanidakis/praktor"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mtzanidakis/praktor/releases/tag/v0.9.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "praktor: Path traversal in Telegram file uploads allows writing outside the agent workspace uploads/ directory (stored instruction injection)"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.