Setting File and Process Ownership to Non-existent Users

Viewed 157

I'd like to know the security implications of changing the ownership of files, and starting process by, a UID that has no mapping to a current user on the system.

Let's say there's a file /foobar, and we've changed it's UID:GID to 1010:1010 — where those IDs are not currently mapped to any existing user — and set it's permissions to 0600. Other users will not be able to perform read or write operations on the file. If the file were instead in a directory owned by an existing user, that user could write to the file. And obvioulsy if a user were created that received the UID 1010, they could also write to the file. If we say that no such user will be created, though, is this a good way to keep that file secure from other users?

The reason I'm asking is that I don't want to run my Docker containers as root, but also don't want to get into the mess of managing user remapping with subuids. I thought the answer could be to run and own things in the container as the UID of the user who owns the files on the host. This seems to work just fine, and the non-existant container user (with the UID of the existing host user) is able to write to those files.

Though I feel there's some important security aspect I'm missing.

1 Answers

The important security aspect here is that, when you docker run the container, you can bind-mount any host directory and run as any user.

# What you expect
docker run \
  -u $(id -u) \
  -v $(pwd):/data \
  --rm \
  data-processing-image \
  process /data/input.txt

# What's also possible
docker run \
  -u root \
  -v /:/data \
  --rm \
  data-processing-image \
  cat /data/etc/shadow     # to print out the host's encrypted password file

Some tools might print out error messages if the current user ID isn't in /etc/passwd or if the current group ID isn't in /etc/groups, but it'd be a little unusual to run into these cases in Docker. (You wouldn't typically run a heavily customized interactive shell in a container, for instance.) Actual security enforcement is based on the numeric user and group IDs and there aren't particular consequences if the database files don't include them.

One specific case I'll note is the Docker Hub postgres image, which allows running the database as an arbitrary user (not necessarily the in-container postgres user), mostly to support bind-mounted host data directories. The "Arbitrary --user Notes" section there notes

postgres doesn't care what UID it runs as (as long as the owner of /var/lib/postgresql/data matches), but initdb does care (and needs the user to exist in /etc/passwd)

And this statement can be generalized to say that, for enforcing filesystem permissions, the user doesn't need to be in /etc/passwd so long as all of the numeric uids line up, but specific processes may have other expectations.

Related