Root Access Detection
Container Root Access Detection addresses a serious security concern with regards to containers – the ability to escape from the container to the host and have root access to run commands host side. There are two root access detections that Qualys uses with regards to containers. The first detection is “inside” the container and the second detection is “outside” of the container.
“Inside” Root Access Detection
The first detection looks for the root user being present on the container. The users present are detected during the container scan by the Container Security Sensor in General mode.
Search users:root
Use this search to find out if the root user is present on the container. In the Container Security UI, go to Assets > Containers and enter “users:root” in the search field.
What is being detected?
When you perform a search query for “users” Qualys checks the /etc/passwdfile to see what users are present. Here’s an example showing that the root user is present:
root@32f8282fd563:/# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
“Outside” Root Access Detection
The second detection looks at the host level user permissions the container was spun up with. This is detected during the container scan by the Container Security Sensor.
Search isRoot:true
Use this search to find out if the container was spun up with root privileges. This time enter “isRoot:true” in the search field.
What is being detected?
When you perform a search query for “isRoot” Qualys checks the “docker inspect” output of the container, checking the Config.User field. We’re looking for three different scenarios (no user, root user, non-root user), which are described in detail below.
1) No user specified
If no user is specified, then it is assumed that the host level root user or a user with root permissions spun up the container.
"User": "",
This will result in “isRoot:true”.
2) Root user specified
When the root user is specified, this means the container was explicitly started with host level root user permissions.
"User": "root",
This will result in “isRoot:true”.
3) Non-root user specified
The container was spun up with a host level non-root user, such as a user above 1000.
docker run -u 1001 ubuntu:latest
<container_id>
docker inspect <container_id>
Find the Config section and look for the “User” field.
"User": "1001",
This will result in “isRoot:false”.
This is also the user the container will start with internally by default.
Note - The root user inside of the container, if not removed, will still be present. However the default operations will take place with the new non-root user. It is recommended that you remove the root user if not needed.
If the user was not created within the container, and permissions specified, then the user will not show up when checking the /etc/passwdfield.
$ docker exec -it <container_id> /bin/bash
I have no name!@<container_id>:/$ whoami
whoami: cannot find name for user ID 1001
It is recommended that you create the non-root user inside of the container when building the image, as well as on the host side.
Why does root access on a container matter?
The “isRoot:true” and “users:root” detections are provided to help you address container security concerns. If a container is to become compromised you need to know whether host level root privileges are present for the given container. If host level root privileges are present, this means it would be possible to escape from the container to the host with full control.
The ideal security method is to follow the practice of least privilege. One way this can be done is by creating a non-root user with the least privileges necessary inside of the container and on the host for the processes/files/directories/etc that are required, then spin the container up using this user.
A potential drawback to this method, is the potential for non-portability and/or complexity in container CI/CD.