Skip to main content

Use of an insecure channel - Docker

Need

Secure communication channels for Docker containers

Context

  • Usage of Node.js 20 for server-side JavaScript development

Description

Non compliant code

# Dockerfile for a Node.js application
FROM node:20
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 80
CMD [ "node", "server.js" ]

In the Dockerfile provided above, the EXPOSE instruction is used to inform Docker that the container listens on the specified network ports at runtime. In this case, port 80 is being exposed.

Port 80 is typically used for HTTP traffic. Exposing this port can lead to potential security risks as it opens up the application running inside the Docker container to the outside world. If an attacker gains access to this port, they could potentially exploit it to carry out attacks such as Denial of Service (DoS), data theft, or even gain unauthorized access to the system.

Furthermore, the RUN npm install command is run as root in the Dockerfile. This could potentially allow an attacker to gain root access to the Docker container if they were able to exploit a vulnerability in the application.

In summary, the Dockerfile is vulnerable due to the exposure of port 80 and the running of commands as root.

Steps

  • Remove the EXPOSE instruction from the Dockerfile.
  • Update the CMD instruction to use a secure communication channel, such as HTTPS with TLS v1.2.
  • Consider using a reverse proxy, such as Nginx, to handle the secure communication and expose only the necessary ports.
  • Update the documentation to specify the required ports for the application.
  • Regularly update and patch the Docker image and dependencies to ensure security.
  • Test the updated Dockerfile to ensure the application functions correctly over the secure channel.

Compliant code

# Dockerfile for a Node.js application
FROM node@sha256:c2ed73be34c27a42bd202021c7fdf1a92999fb171f2e1d54bd4b461d9344eeb2
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
CMD [ "node", "server.js" ]

The Dockerfile no longer exposes port 80, reducing the attack surface. The application should be deployed behind a reverse proxy like Nginx, which can handle HTTPS with TLS and expose only the necessary ports. The Dockerfile uses a digest to specify the Node.js image, ensuring that the same image is always used. The Dockerfile also sets up a non-root user to run the application, following the principle of least privilege.

References