Secrets are interpolated in cleartext into the executed build shell command, and can leak via error logs on build failure
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 37.4k
- Forks
- 3k
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 73
Description
Affected code
packages/server/src/utils/builders/nixpacks.ts(getNixpacksCommand) — builds thenixpacks build ...command with--env KEY=VALUEpairs, embedding secret values directly in the command string.packages/server/src/utils/builders/docker-file.ts(getDockerCommand) — builds thedocker build ...command with aKEY=VALUE ...shell-prefix, also embedding secret values directly in the command string (in addition to correctly using BuildKit's--secret type=env,id=KEYfor the build itself — the shell-prefix duplication is the issue).packages/server/src/utils/process/execAsync.ts/ExecError.ts— when the generated command fails (non-zero exit, spawn error, SSH failure), the full command string is retained on the thrown error: natively via Node'schild_processerror (.cmd), and explicitly viaExecError.command/ExecError.getDetailedMessage()(Command: ${this.command}).
Impact
Any code path that logs, displays, or serializes one of these errors (deployment logs written to deployment.logPath, the Dokploy service's own process/console logs, or a future error-reporting integration) can end up printing every environment secret for the affected application in cleartext — for anyone with read access to that log surface (server file access, docker service logs, etc.), independent of the Dokploy web UI's own access control.
We observed this concretely: a failed Nixpacks build's error surfaced the full command (all env secrets included) in docker service logs dokploy. Because both build-command generators share the same pattern (interpolating secret values into a shell string rather than passing them via a mechanism that keeps them out of the command string / thrown errors), we believe the Dockerfile build path is equally exposed on a future build failure, not just Nixpacks.
Suggested direction
- Avoid putting secret values into the command string at all where possible — e.g. write them to a short-lived env file consumed by
--env-file/docker build's secret mounting, or pass them via the processenvoption toexec/spawnrather than interpolating into the command text. - If a command string containing secrets must be kept somewhere (e.g. for debugging), ensure
ExecError/getDetailedMessage()and any logging call sites redact known-sensitive env var values before they reach a log sink.
Environment
Reported against the current Dokploy/dokploy main branch source as of 2026-09-05 (read via GitHub, exact commit not pinned — happy to confirm against a specific release if useful).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with getNixpacksCommand in packages/server/src/utils/builders/nixpacks.ts and getDockerCommand in packages/server/src/utils/builders/docker-file.ts, then trace failures through packages/server/src/utils/process/execAsync.ts and ExecError.ts. Check how deployment.logPath and process or console logs receive these errors. Done means build failures and their detailed messages no longer expose environment secret values while the build paths still receive the required secrets.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, typescript
- Domain
- backend, devops, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100