Skip to content

debug bundle is staged at a predictable path and published world-readable #10195

Description

@udsy19

What happens

src/lib/diagnostics/tarball.ts:28 stages the debug bundle at a path other local users can
predict, and lets tar create it:

const partial = `${output}.partial.${process.pid}`;

Nothing creates that file first, so the spawnSync("tar", ...) at
src/lib/diagnostics/tarball.ts:29 chooses its mode and the success path renames it to output
at src/lib/diagnostics/tarball.ts:51. Two things follow, both observed on main (337c1eed5)
with the default umask 022:

The bundle is published group- and world-readable — bundle mode: 644. That is the file the
command tells users to attach to a GitHub issue
(src/lib/diagnostics/debug.ts:514-517).

tar follows a symlink planted at the staging path. After planting one and letting tar
write, the symlink target began 037 213 — the gzip magic number, i.e. it was overwritten with
tarball content.

Both are reachable because the command's own example writes into a world-writable directory
(src/commands/debug.ts:88):

nemoclaw debug --output /tmp/nemoclaw-debug.tar.gz

There, any local user can read the bundle, or pre-plant a symlink at
/tmp/nemoclaw-debug.tar.gz.partial.<pid> — a small, enumerable space — to have a file of their
choosing overwritten with the tool's privileges.

Why this looks like drift

The repository already stages temp files safely: src/lib/shields/timer.ts:167 uses
fs.openSync(tempPath, "wx", 0o600), src/lib/share-command.ts:233 uses
{ mode: 0o600, flag: "wx" }, and src/lib/shields/index.ts:393 uses O_EXCL | O_NOFOLLOW.

The staging path here arrived in #4506 (f8c85f37e), whose stated goal was to leave no partial
tarball and rename atomically. Permissions and predictability were not in that change's scope.

Environment

macOS 26.5.1 (25F80), Node v26.7.0, main at 337c1eed5.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: cliCommand line interface, flags, terminal UX, or outputarea: observabilityLogging, metrics, tracing, diagnostics, or debug outputarea: securitySecurity controls, permissions, secrets, or hardening

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions