Skip to content

[Yun Tianming] src/commands/secrets.ts: .env bundle written with umask default mode #273

Description

@Fermionic-Lyu

Location: src/commands/secrets.ts:109-110 in secrets(): const out = opts.output ?? '.env'; await writeFile(out, serializeEnv(bundle)).

Kind: secrets written to disk with permissive mode; symlink follow on write.

Evidence: the bundle is every secret for the branch (GET /projects/:id/secrets via fetchSecretBundle). writeFile is called with no mode and no chmod, so a freshly created .env is 0644. The command then prints “credentials must never be committed” and gitignores the file, guarding git but not the filesystem. Contrast src/commands/storage.ts:127-129, which preserves a 0600 mode when replacing a download. writeFile also follows symlinks, so --output pointed at a link writes through it, while the repo already has writeFileAtomicSync/resolveThroughSymlink in src/util.ts for exactly this.

Impact: every project credential readable by any local user on creation.

A fix would touch: the write in secrets() (mode 0600 on create, or reuse writeFileAtomicSync), and test/run-secrets.test.ts or a new test asserting the mode.


Found by Yun Tianming: nightly sweep 2026-09-23-1000 at 3cac58008fcb. Report only; no code was changed for this finding.

🤖 Generated with Claude Code


Issue cleanup — 2026-09-29

Duplicate of cli#240. The underlying issue remains open there; this closure does not mean it has been fixed. The original report is preserved above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions