userEnvProbe (and --secrets-file) put container env values, incl. secrets, on the host `docker exec` argv
Mantenedores costumam responder em até 1 dia
@v-Kaniska244 já está trabalhando nisso.
Desde 6/10/2026.
Avaliação
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Facilidade para iniciantes
- 68/100
- Tipo de issue
- Bug
- Clareza
- Claramente especificada
- Status de atividade
- Ativa
- Stack de tecnologia
- docker, typescript
Direção de pesquisa
Start in src/spec-shutdown/dockerUtils.ts at toDockerExecArgs, then trace remoteEnv from probeUserEnv and the secrets merge in src/spec-common/injectHeadless.ts. Run the supplied Docker reproduction for both userEnvProbe and --secrets-file. Done means lifecycle hooks and devcontainer exec still receive their environment while secret values no longer appear in host docker exec argv.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Summary
When userEnvProbe is enabled (the default, loginInteractiveShell), the CLI reads the container user's whole environment (cat /proc/self/environ) and passes every variable back to docker exec as a -e NAME=VALUE argument. This happens on every lifecycle hook (onCreateCommand, postCreateCommand, postStartCommand, …) and on every devcontainer exec.
So any secret that is already in the container's environment ends up in plaintext on the host process command line, where any local user can read it with ps. That includes secrets injected with runArgs: ["--env-file", …], containerEnv or an image ENV. Those variables are already part of the container's Config.Env, which docker exec inherits, so re-sending them on the command line gains nothing.
The --secrets-file feature has the same problem, even with "userEnvProbe": "none". Lifecycle commands merge the secrets into the exec env (const env = { ...(await remoteEnv), ...(await secrets) }), so each secret appears as -e NAME=VALUE on the host argv while the hook runs.
Where
On main (3e363f63a712d30a741174f6d1a7e75f47fe3fc1):
src/spec-shutdown/dockerUtils.tstoDockerExecArgs(~L400-415):Object.keys(env).forEach(key => execArgs.push('-e',${key}=${env[key]}))src/spec-common/injectHeadless.tsprobeUserEnv(~L777-789,cat /proc/self/environ) feedsremoteEnv.runLifecycleCommand(~L518) mergesremoteEnvandsecretsinto thatenv.- In the published 0.89.0 bundle (
dist/spec-node/devContainersSpecCLI.js) the same logic is the minified functionKN:r&&Object.keys(r).forEach(a=>g.push("-e",${a}=${r[a]})).
Repro (dummy values only)
@devcontainers/cli 0.89.0, Docker Desktop on macOS, image alpine:3.
mkdir probe && cd probe
umask 077
printf 'ARGV_PROBE_VAR=DUMMY_NOT_SECRET\n' > dummy.env
printf '{"image":"alpine:3","overrideCommand":true,"runArgs":["--env-file","%s/dummy.env"]}\n' "$PWD" > .devcontainer.json
devcontainer up --workspace-folder .
devcontainer exec --workspace-folder . sleep 6 &
sleep 3; ps -axww -o command | grep '^docker exec'
Observed (other values elided):
docker exec -i -u root -e HOSTNAME=… -e SHLVL=… -e HOME=… -e PAGER=… -e LC_COLLATE=… -e PATH=… -e LANG=… -e CHARSET=… -e ARGV_PROBE_VAR=DUMMY_NOT_SECRET -w /workspaces/probe <id> sleep 6
| Arm | docker exec argv contains ARGV_PROBE_VAR=DUMMY_NOT_SECRET |
Var visible inside the container |
|---|---|---|
default userEnvProbe |
yes (1 process) | yes |
"userEnvProbe": "none" |
no (0) | yes (inherited from Config.Env) |
--secrets-file arm: config {"image":"alpine:3","overrideCommand":true,"userEnvProbe":"none","postStartCommand":"sleep 8"} with --secrets-file secrets.json containing {"SECRETSFILE_PROBE_VAR":"DUMMY_NOT_SECRET_2"}. While the hook ran, the host showed docker exec -i -u root -e SECRETSFILE_PROBE_VAR=DUMMY_NOT_SECRET_2 -w /workspaces/probe-secretsfile <id> /bin/sh -c sleep 8.
We found this in a real setup where Doppler secrets were injected with --env-file. Every secret showed up in the host process table during devcontainer up and devcontainer exec.
Suggested fix
Any of these, in order of preference:
- Pass variables by name, not by value. Use
docker exec -e NAME(no=), so docker reads the value from the CLI process's own environment, and spawn thedockerchild with{ ...process.env, ...env }. Values never appear on argv. This also covers--secrets-fileandremoteEnv. - Or use
docker exec --env-file <tmpfile>, written mode 0600 and removed after the exec starts. - At minimum, don't re-send probed variables whose value already equals the container's
Config.Envvalue.docker execinherits those, so dropping them changes nothing. Only the delta the login shell adds would remain (e.g.PATH), which is rarely sensitive.
Workaround for users: set "userEnvProbe": "none" and run commands that need the login environment through bash -lc. This does not help with --secrets-file.
- Linguagem predominante
- TypeScript
- Estrelas
- 3k
- Forks
- 463
- Merge médio
- 13h 28min
- PRs com merge (30d)
- 2
Preparar o ambiente
Inicia o contêiner de desenvolvimento do projeto no navegador, com a sua própria conta do GitHub.
- Sem Dockerfile nem arquivo Docker Compose
- Sem modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de devcontainers/cli
-
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 92/100
devcontainers/cli#1203 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 1/5 1-3 horas Facilidade para iniciantes 68/100
devcontainers/cli#1178 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 5/5 Mais de uma semana Facilidade para iniciantes 25/100
devcontainers/cli#1308 · 1 comentário · 1 reação ·
Mantenedores costumam responder em até 1 dia
-
build rejects valid tag@digest image references during registry inspectionTalvez já em andamento @v-Kaniska244 assumiu há 11 dias. Aberta
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 78/100
devcontainers/cli#1307 · 2 comentários · 1 reação · 1 responsável ·
Mantenedores costumam responder em até 1 dia
-
Feature request: devcontainer build --build-output-folderTalvez já em andamento @pstoeckle assumiu há 13 dias. Aberta
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 55/100
devcontainers/cli#1305 ·
Mantenedores costumam responder em até 1 dia
Todas as issues de devcontainers/cli
Issues semelhantes
-
triage
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
github/docs#46222 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
agent-ready area: config area: skills type: chore upstream: brain-kit
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 95/100
-
enhancement priority:low ready-for-dev
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
Mantenedores costumam responder em até 1 dia
-
bug escritorio mapa
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
marcosferr/reporte-ciudadano#4 · 1 comentário ·
-
area: material/sort gemini-triaged needs triage
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 70/100
angular/components#33933 ·
Mantenedores costumam responder em até 1 dia