Docker - Security - Least privileged user

When a Dockerfile doesn’t specify a USER, it defaults to executing the container using the root user.

When that namespace is then mapped to the root user in the running container, it means that the container potentially has root access on the Docker host.

Having an application on the container run with the root user further broadens the attack surface and enables an easy path to privilege escalation if the application itself is vulnerable to exploitation.

In practice, there are very few reasons why the container should have root privileges.

To minimize exposure, opt-in to create a dedicated user and a dedicated group in the Docker image for the application; use the USER directive in the Dockerfile to ensure the container runs the application with the least privileged access possible.

A specific user might not exist in the image; create that user using the instructions in the Dockerfile.

The following demonstrates a complete example of how to do this for a generic Ubuntu image:

dockerfile
FROM ubuntu
RUN mkdir /app
RUN groupadd -r lirantal && useradd -r -s /bin/false -g lirantal lirantal
WORKDIR /app
COPY . /app
RUN chown -R lirantal:lirantal /app
USER lirantal
CMD node index.js

The example above:

If you’re a fan of Node.js and alpine images, they already bundle a generic user for you called node. Here’s a Node.js example, making use of the generic node user:

Dockerfile
FROM node:10-alpine 
RUN mkdir /app
COPY . /app
RUN chown -R node:node /app
USER node
CMD [“node”, “index.js”]

If you’re developing Node.js applications, you may want to consult with the official Docker and Node.js Best Practices.


Create a dedicated user and group on the image, with minimal permissions to run the application; use the same user to run this process

For example, Node.js image which has a built-in node generic user:

Dockerfile
FROM node:10-alpine
USER node
CMD node index.js