anchore / anchore-engine

A service that analyzes docker images and scans for vulnerabilities
Apache License 2.0
1.59k stars 272 forks source link

effective_user should be nobody #621

Open tonsV2 opened 4 years ago

tonsV2 commented 4 years ago

Is this a request for help?: Yes, but it might be a bug


Version of Anchore Engine and Anchore CLI if applicable: Anchore Engine: 0.8.1

What happened: I'm scanning an image I've build using Jib.

As part of the result I'm seeing the following dockerfile effective_user User root found as effective user, which is explicity not allowed list warn

But I've configured my process to be run by the user nobody and it does indeed run as the user nobody when I exec into the container and ps -aux.

What did you expect to happen: I was expecting not to see my effective user reported as root

What docker images are you using: tons/whoami-mn:ci

How to reproduce the issue: Scan the above image

Anything else we need to know: GitHub Action results: https://github.com/tonsV2/whoami-mn/runs/1123868444?check_suite_focus=true Jib configuration: https://github.com/tonsV2/whoami-mn/blob/master/build.gradle#L14

zhill commented 4 years ago

Thanks @tonsV2 we'll take a look

zhill commented 4 years ago

I looked at the image and I see no USER directive in the history. That is what the check is looking for. A clear indicator from the dockerfile/history that the image commands run as a non-root user. That doesn't mean that when you run the container you can't use another uid, but that isn't indicated in the dockerfile itself. At least from what I can see. Did I miss something in the build steps for the image?

tonsV2 commented 4 years ago

Thanks for the fast response!

The image is build using Jib so I'm not using a Dockerfile. The configuration can be seen here. I'm not sure about the inner workings of Jib but I'm sure the image runs as nobody as I can see that when instantiating the container.

The whole project is open source and can be found here. It's a simple whoami service build using the Micronaut framework. And should you feel bold you can build a container and push it to your local Docker registry using ./gradlew jibDockerBuild.

I'll try to look more into why the USER directive is missing. But are there any other ways to assert which user is running the process? Somehow the process is running as the user nobody.

tonsV2 commented 4 years ago

When I execute docker image inspect tons/whoami-mn:ci I can see that the ContainerConfig.User is empty however the Config.User isn't. That states "nobody".

Which tool are you using to look for the user directive?

zhill commented 4 years ago

The check you're referring to is specifically a dockerfile check, not a generic image configuration check, so it looks like in that specific build process is setting the container config another way than with a directive in a Dockerfile. The code inspects the docker history and tries to see if the USER directive was set explicitly in the dockerfile, so that check may just not be appropriate for images built without a dockerfile.

This is an interesting case that may necessitate a different check that looks for the container user using the configuration on the container, which is probably more generic than a Dockerfile-centric approach.

Based on findings, I think this is a case where our code is operating as intended, but the resulting semantics are not quite what is expected in this case since there isn't a Dockerfile so those layers aren't an accurate way to determine if the user was set.

tonsV2 commented 4 years ago

Everything you say sounds reasonable. But shouldn't this be consider a bug since it's a false positive is reported?

zhill commented 4 years ago

Perhaps this check should be removed from the Dockerfile gate and added to a "ImageConfig" gate or similar that only considers the configuration section of the image to avoid confusion and make the semantics clear instead of the current feature design of checking the Dockerfile/layer content itself.

danielwegener commented 4 years ago

I can confirm the behaviour (ran pretty much in the same trap with jib). effective_user and exposed_ports really should be in the metadata gate or a dedicated image_configuration gate. Currently it only ensures that someone has created a history entry with a certain created_by element (see https://github.com/anchore/anchore-engine/blob/067ae3556418a25463be4da3a99b4f2c5d36ea79/anchore_engine/services/policy_engine/engine/policy/gates/dockerfile.py#L100) - what everyone (even in base images) could freely imitate without actually changing the image configuration.

Unfortunately I can not even use a workaround with the metadata gate because it only supports certain ("valid attributes"). @zhill Is there any chance or plan to support checks on the config section of the docker image metadata or would you be willing to accept contributions in that direction? It would also be very desirable to be able to check for the presence of certain environemtn variables (Env), the entrypoint (Entrypoint) or labels (Labels).