Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Liran Tal
Liran Tal

Posted on • Edited on • Originally published atlirantal.com

     

How to securely build Docker images for Node.js

Use a least privileged user

When aDockerfile doesn’t specify aUSER, it defaults to executing the container using the root user. In practice, there are very few reasons why the container should have root privileges.

Docker defaults to running containers 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.

To minimize exposure, opt-in to create a dedicated user and a dedicated group in the Docker image for the application; use theUSER directive in theDockerfile 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 theDockerfile.

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

FROM ubuntuRUN mkdir /appRUN groupadd -r lirantal && useradd -r -s /bin/false -g lirantal lirantalRUN chown -R lirantal:lirantal /appWORKDIR /appCOPY . /appUSER lirantalCMD node index.js
Enter fullscreen modeExit fullscreen mode

The example above:

  • creates a system user (-r), with no password, no home directory set, and no shell
  • adds the user we created to an existing group that we created beforehand (using groupadd)
  • adds a final argument set to the user name we want to create, in association with the group we created

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

FROM node:10-alpine RUN mkdir /appCOPY . /appRUN chown -R node:node /appUSER nodeCMD [“node”, “index.js”]
Enter fullscreen modeExit fullscreen mode

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

This post is part of10 Docker image security best practices you should adopt. Thanks for reading and toOmer Levi Hevroni who worked with me on it.

The original blog post includes a high-resolution printable PDF like the snippet you see below.Check it out

Docker Images Security Best Practices

Top comments(7)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
rubberduck profile image
Christopher McClellan
I make software & software accessories.
  • Work
    Software Craftsman
  • Joined

You’re jumping through a lot of hoops to create a user. There’s a keyword for creating a user in a particular group.

docs.docker.com/engine/reference/b...

CollapseExpand
 
lirantal profile image
Liran Tal
GitHub Star 🌟 · DevRel at Snyk 🥑 · Author of Essential Node.js Security · Node.js CLI Best Practices 🔥 · Docker security 🐳
  • Email
  • Location
    Israel
  • Work
    Developer Advocate at Snyk
  • Joined

theUSER instruction though is only switching the user ownership to a specific user, it isn't actually creating a new one. Correct?

CollapseExpand
 
rubberduck profile image
Christopher McClellan
I make software & software accessories.
  • Work
    Software Craftsman
  • Joined

No. It creates a user. The only reason to do it the way you did it is if you need to map a user/group from the host to one inside the container.

Thread Thread
 
lirantal profile image
Liran Tal
GitHub Star 🌟 · DevRel at Snyk 🥑 · Author of Essential Node.js Security · Node.js CLI Best Practices 🔥 · Docker security 🐳
  • Email
  • Location
    Israel
  • Work
    Developer Advocate at Snyk
  • Joined
• Edited on• Edited

Would you like to reference an example Dockerfile for that?
AFAIK a directive such asUSER lirantal does not create a user if one doesn't exist already.

Thread Thread
 
asto profile image
astodev
  • Location
    Vernon, BC
  • Joined

docs.docker.com/engine/reference/b...

USER directive does not create a user. The username specified must already exist or can be created earlier in the Dockerfile directives.

Fromdocs.docker.com/develop/develop-im...
If a service can run without privileges, use USER to change to a non-root user. Start by creating the user and group in the Dockerfile with something like:


RUN groupadd -r postgres && useradd --no-log-init -r -g postgres postgres

Thread Thread
 
lirantal profile image
Liran Tal
GitHub Star 🌟 · DevRel at Snyk 🥑 · Author of Essential Node.js Security · Node.js CLI Best Practices 🔥 · Docker security 🐳
  • Email
  • Location
    Israel
  • Work
    Developer Advocate at Snyk
  • Joined

Thanks for reassuring.

Thread Thread
 
rubberduck profile image
Christopher McClellan
I make software & software accessories.
  • Work
    Software Craftsman
  • Joined

Yup. I stand corrected.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

GitHub Star 🌟 · DevRel at Snyk 🥑 · Author of Essential Node.js Security · Node.js CLI Best Practices 🔥 · Docker security 🐳
  • Location
    Israel
  • Work
    Developer Advocate at Snyk
  • Joined

More fromLiran Tal

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp