devcontainers / devcontainers/cli

Dockerfile `ENV` mutates system-wide `/etc/environment`

未关闭
#1,231 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
TypeScript
星标
3k
派生
457
平均合并
13 小时 17 分钟
30 天内合并 PR
6

描述

Problem: Extremely surprising that DevContainers mutates system-wide `/etc/environment` at all.

This is a pretty insane architectural choice for a few reasons:

1. fails rule of lease surprises
2. is a breaking-change compared to other container runners, doesn't match deployment of a target container
3. major security concern for per-user secrets, or build-time only secrets, getting injected into the system environment where every user (e.g. daemon web applications, databases, etc.) now potentially has these secrets in their environment

Reproduce this issue, create a Dockerfile:

```Dockerfile
FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive

# Layer 1: Locale + Timezone
RUN apt-get update && apt-get install -y --no-install-recommends \
locales tzdata \
&& sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen \
&& locale-gen \
&& ln -fs /usr/share/zoneinfo/America/Los_Angeles /etc/localtime \
&& dpkg-reconfigure -f noninteractive tzdata \
&& rm -rf /var/lib/apt/lists/*

ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 TZ=America/Los_Angeles

# Switch to picard user for all per-user tool installs
USER picard
WORKDIR /home/picard

# Layer: Rust (stable via rustup)
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- \
-y --default-toolchain stable --profile default
ENV PATH="/home/picard/.cargo/bin:$PATH"
```

Just opening a container using VsCode will edit the `/etc/environment`:

https://github.com/devcontainers/cli/blob/65f98a518a1f62355a08e6f38e9d6bfb9a0d8ac9/src/spec-common/injectHeadless.ts#L750-L761

```sh
# Open a shell inside the container
docker compose exec claude-dev zsh
```

From the container:

```console
cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"

ANTHROPIC_API_KEY="sk-ant-your-key-here"
OPENAI_API_KEY="sk-your-key-here"
GEMINI_API_KEY="your-key-here"
PATH="/home/picard/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
DEBIAN_FRONTEND="noninteractive"
LANG="en_US.UTF-8"
LC_ALL="en_US.UTF-8"
TZ="America/Los_Angeles"
```

In this repro, it means that every user's Rust bin will be served from the `picard` user's home directory. That's just not how this should work.

I don't believe this is the intention for the `ENV` directive of a Dockerfile!
https://docs.docker.com/reference/dockerfile/#env

When you run `docker exec`, the container runtime reads the same image config and passes the `ENV` vars via `execve` to the new process, regardless of which user it runs as (`--user`). So every docker exec session gets them. But this is very different than injecting it into `/etc/environment` where the change is persisted for any user logging into the container (e.g. `ssh`) and not limited to `docker exec`.

贡献指南

打开贡献指南

调研方向

从 src/spec-common/injectHeadless.ts 第 750-761 行开始,使用提供的 Ubuntu Dockerfile 和环境变量复现该行为。检查 Dockerfile ENV 值如何写入 /etc/environment,然后验证打开容器不再使这些值在系统范围内持久化,同时容器的正常执行仍然能够接收到这些值。

由索引模型根据 Issue 内容生成。

评估

技术栈
docker, typescript
领域
devops, devtools
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
活跃
描述清晰度
基本清楚
新手友好度
55/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。