userEnvProbe (and --secrets-file) put container env values, incl. secrets, on the host `docker exec` argv
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 68/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- docker, typescript
Hướng nghiên cứu
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.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- TypeScript
- Star
- 3k
- Fork
- 463
- Merge trung bình
- 13 giờ 28 phút
- Pull request đã merge (30 ngày)
- 2
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của devcontainers/cli
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 92/100
devcontainers/cli#1203 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 68/100
devcontainers/cli#1178 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
devcontainers/cli#1308 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
build rejects valid tag@digest image references during registry inspectionCó thể đã có người làm @v-Kaniska244 đã nhận 9 ngày trước. Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 78/100
devcontainers/cli#1307 · 2 bình luận · 1 reaction · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
devcontainers/cli#1305 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của devcontainers/cli
Issue tương tự
-
[Bug] The shared instance selector's placeholder and no-match text ignore the display languageCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 90/100
apache/rocketmq-dashboard#5561 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
CopilotKit/OpenDots#69 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
sendDefaultPii is reported as deprecated on ReactNativeOptions although dataCollection is hiddenĐang mởBug React-Native Waiting for: Product Owner
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
getsentry/sentry-react-native#6830 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
OSCI'26
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
GauravKarakoti/SecureFlow#1215 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[quality] bundle e2e never drives plain /close or the /milestone refusals through dist/index.jsCó thể đã có người làm @hivecommons-hive đã nhận hôm nay. Đang mởagent/quality hive/covered-by-pr hive/hosted-available-lke648397-260827-5q9t kind/cleanup quality testing
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
cncf/prow-github-actions#295 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày