Using ENV to handle secrets can lead to sensitive information being disclosed to an inappropriate sphere.

The ENV commands in a Dockerfile are used to configure the container environment. The variables set that way can be used at image build time, during the execution of commands in the container, or at run time.

In most cases, environment variables are used to propagate configuration items from the host to the container. A typical example is the PATH variable, used to configure where system executables are searched for.

Using ENV to propagate configuration entries that contain secrets causes a security risk. Indeed, in most cases, artifacts of those values are kept in the final container image and, thus, disclosed to its users. The secret information leak can happen either in the container environment itself, the image metadata or the build environment logs.

The concrete impact of such an issue highly depends on the secret’s purpose and the exposure sphere:

Ask Yourself Whether

There is a risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Note that, in both cases, the files exposing the secrets should be securely stored and not exposed to a large sphere. In most cases, using a secret vault or another similar component should be preferred. For example, Docker Swarm provides a secrets service that can be used to handle most confidential data.

Sensitive Code Example

FROM example
ARG ACCESS_TOKEN
# Sensitive
ENV ACCESS_TOKEN=${ACCESS_TOKEN}
CMD /run.sh

Compliant Solution

For build time secrets, use Buildkit’s secret mount type instead:

FROM example
RUN --mount=type=secret,id=build_secret ./installer.sh

For runtime secrets, leave the environment variables empty until runtime:

FROM example
ENV ACCESS_TOKEN=""
CMD /run.sh

Store the runtime secrets in an environment file (such as .env) and then start the container with the --env-file argument:

docker run --env-file .env myImage

See