subuser-security / subuser

Run programs on linux with selectively restricted permissions.
http://subuser.org
GNU Lesser General Public License v3.0
888 stars 65 forks source link

Docker images can contain SUID binaries #229

Open timthelion opened 8 years ago

timthelion commented 8 years ago

This means that all subusers can be considered to have root WITHIN THE CONTAINER. This bug will be resolved once usernamespaces are a thing in runc/Docker.

ruipin commented 8 years ago

Can't docker mount its filesystems as nosuid?

timthelion commented 8 years ago

I searched for this, but couldn't find it. I don't think that it is possible. I also found many claims that it is not desireable, because most distributions rely on nosuid for core functionality. I haven't verified that second part yet.

ruipin commented 8 years ago

I thought they could. For example, this article mentions:

if you’re worried about normal apps escalating from non-root to root, "defang" SUID binaries by removing the SUID bit and/or mount filesystems with nosuid.

Even if that's not the case, this article takes a different approach, by removing suid permissions from files manually, in the dockerfile itself. This could be used as a work-around, I guess.

timthelion commented 8 years ago

Yes, I saw that article. Which really seems to give the impression that the only way is to remove suid bits. We even have a good place to put that code: https://github.com/subuser-security/subuser/blob/master/logic/subuserlib/classes/subuserSubmodules/run/runReadyImage.py#L38

However, any time one adds code that gets run within the image, that code has to be extremely portable. Preferably POSIX compliant shell. (Or I guess it might be possible to use a statically linked binary, but that has other complications with compiling/distribution ect.)

timthelion commented 8 years ago

If you want to play with this, I would suggest, writing some really crapy code quickly, to get rid of the suid bits and see if anything breaks. Don't invest a lot of time in it, untill you know that normal applications have a chance of working without suid bits in the system :)

timthelion commented 8 years ago

Oops, I just realized that modifying the run ready image Dockerfile might not work in this case because it would be possible for a malicious image to interfere with any script that we inserted there. I'm not sure if it would be possible for a malicious image to interfere with a statically linked binary though.

ruipin commented 8 years ago

Assuming we trust the docker image not to interfere, for example the only attacks we are worried about would come from outside WHILE using the sandboxed application (for example, browser exploits), removing SUID bits while building the dockerfiles would be enough, right?

ruipin commented 8 years ago

I added this to my dockerfile, right at the end:

# Remove SUID bits
RUN for i in `find / -not \( -path /proc -prune \) -perm +6000 -type f`; do echo -n "Removing SUID bit from $i... " && chmod a-s $i && echo "Done."; done

I know this isn't POSIX compliant and all, but I wanted something quick. It seems to work perfectly fine. I can then run bash under the subuser, and am not able to find a single SUID binary. Meanwhile, Firefox (+ fresh-player/pepper-flash Flash; and audio through Pulseaudio), Thunderbird and qBittorrent still seem to work perfectly fine.

The SUID binaries of course stop working without "sudo" (for example, 'ping www.google.com' gives an error), but that doesn't matter much.

timthelion commented 8 years ago

Thank you for testing this out. I will resolve this once a good, elegant, solution appears. Which might not be untill subuser moves from working through Docker to calling runc directly.

SuicSoft commented 8 years ago

@timthelion I think that subuser should not run as root (like xdg-app) because if a application escapes the sandbox then they have root (I think it is better to run my web browser outside subuser)

Also take a look at how rm -rf / could permanently brick your UEFI (2012 and newer) motherboard (I am typing this using a UEFI laptop running elementary OS freya). This needs root access to be done and makes me not run my web browser in subuser (Chrome already has a sandbox)

timthelion commented 8 years ago

First off, subuser itself does not ever run as root, Docker does. But that is irrelivant. Docker and xdg-app both use the same sandboxing mechanism, only xdg-app uses user-namespaces. Whether using user namespaces or not is more secure or less secure has been debated. What docker does as root in order to create a sandbox is:

1) Creates a new filesystem namespace. That means that "rm -rf /" no longer can damage your system, becuase the files simply aren't in the namespace. 2) Uses cgroups to prevent access to devices, the network, and other things that the container doesn't need 3) Creates a special network "bridge" which allows the container to talk to the network (if need be, if a subuser isn't given network access permission, this bridge will be dissabled). 4) Drops administrator capabilities and many other capabilities, thus restricting which actions the processes in the sandbox can perform 5) Uses seccomp to dissable 44 infrequently used system calls, to reduce the risk that the program can trick the kernel into letting it out of the sandbox

This makes Docker quite secure. It is not perfect, but in no way is it significantly less secure than xdg-app's own sandbox.

Subuser further provides several security advantages:

1) It discards all changes to the containers root filesystem each time the container is run 2) It dissables access to the network unless you specifically give the subuser permission to access it 3) It runs all aplications as the normal user within the sandbox 4) It uses the xpra x11 bridge to provide secure access to x11. Unless you use wayland, xdg-app is %100 insecure becuause it gives full access to X11!

The bug report that you are commenting on, about SUID binaries, only applies to UNTRUSTED images. But the iceweasel or chromium images that you would run in subuser would be trusted, as they are installed directly from debian: https://github.com/subuser-security/subuser-default-repository/blob/latest/iceweasel/image/SubuserImagefile

The fact is, that iceweasel or chromium or whichever web browser you choose would never be run as root in subuser! Nor would they have any access to root, within the sandbox or outside of it.

The most likely vectors of attack against subuser and xdg-app are via the kernel, which both have direct access too. If there is a serious kernel bug which allows container sandboxes to be escaped, than it is probable that both subuser and xdg-app will be effected.

On 04/08/16 16:40, Suici Doga wrote:

@timthelion https://github.com/timthelion I think that subuser should not run as root (like xdg-app) because if a application escapes the sandbox then they have root (I think it is better to run my web browser outside subuser)

Also take a look at how |rm -rf /| could permanently brick your UEFI (2012 and newer) motherboard (I am typing this using a UEFI laptop running elementary OS freya). This needs root access to be done and makes me not run my web browser in subuser (Chrome already has a sandbox)

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/subuser-security/subuser/issues/229#issuecomment-207457586

mviereck commented 6 years ago

You can forbid suid in container with --cap-drop=SETUID --cap-drop=SETGID. Indeed, I regulary drop all capabilities with --cap-drop=ALL and most apps still work fine.