Skip to content

[repo-health] Medium: Entry script written to predictable /tmp path — TOCTOU race on multi-user hosts #6

Description

@Liohtml

Summary

session.writeEntryScript() always writes the generated bash entry script to the fixed, predictable path /tmp/agentbox-entry.sh. On multi-user hosts, any local user can create a symlink or replace this file between the write and the docker run invocation, causing Docker to bind-mount and execute attacker-controlled shell code inside the container.

Category

Security

Severity

Medium

Location

  • File: src/cli/config.ts, line 51
  • File: src/session/index.ts, lines 113-121

Details

The entry script path is hardcoded to path.join(os.tmpdir(), "agentbox-entry.sh") — always /tmp/agentbox-entry.sh. The write in writeEntryScript uses writeFileSync with no O_EXCL flag and no randomisation:

// src/cli/config.ts:51
entryScriptPath: path.join(os.tmpdir(), "agentbox-entry.sh"),

// src/session/index.ts:114
writeFileSync(config.entryScriptPath, script, { encoding: "utf8" });

The file is then bind-mounted as /agentbox/entry.sh inside the container and executed with bash. A malicious local user can:

  1. Pre-create /tmp/agentbox-entry.sh as a symlink pointing to their payload.
  2. Wait for writeFileSync to write through the symlink to the payload path.
  3. Or replace the file between write and docker run.

The impact is container-level code execution with bind-mounted host credentials (~/.claude).

Suggested Fix

Use a per-invocation unique path instead of a fixed name:

import { mkdtempSync } from "node:fs";
// ...
entryScriptPath: path.join(
  mkdtempSync(path.join(os.tmpdir(), "agentbox-")),
  "entry.sh"
),

mkdtempSync creates a directory with a random suffix with mode 0700, so only the owning user can read or replace files inside it. Clean up the temp dir on exit (or after container stops) with fs.rmSync.

Effort Estimate

15 min


Automated finding by repo-health-agent v1.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions