Open borsboom opened 9 years ago
More concretely, the attack scenario is: I clone a project because I want to patch a library, so I start by running stack build
. Generally build systems have escape hatches to execute arbitrary code, but it is limited to the user's permission. If I have docker installed, the build process could escalate its privileges to root!
I think this is getting at a larger problem for library authors; there is a stack.yaml
that you would check in and distribute, and there are stack.yaml
settings that you only want to develop with. Probably STACK_ROOT is meant to solve this, but in this case it cannot solve a security issue.
I think it is better to not allow enabling docker from stack.yaml
because it does not make sense to distribute that setting to other people. Enabling docker should be done some other way. Obviously env variables and cli options can be used, but eventually I may want to write that setting down and have it be automatically used. The approach we could take is to have a list of docker enabled projects in ~/.stack
Yes, that is exactly the scenario I was thinking of. Of course, stack itself doesn't really create this problem -- any library could have some TemplateHaskell that uses the same loophole to escalate its privileges even if you're using cabal-install.
We actually really do want to allow you to enable docker and set the image in the project's stack.yaml, because that way you can ensure that everyone on a team is using a precisely consistent build environment. This is, in fact, the primary purpose of the Docker support. However, any new image will require the user to perform an explicit "stack docker pull" so you can't accidentally end up running an unknown image.
We actually really do want to allow you to enable docker and set the image in the project's stack.yaml, because that way you can ensure that everyone on a team is using a precisely consistent build environment. This is, in fact, the primary purpose of the Docker support. However, any new image will require the user to perform an explicit "stack docker pull" so you can't accidentally end up running an unknown image.
Restricting to not allow pulling an unknown image helps, but does not solve the problem unless the docker build commands that are automatically executed are restricted to just stack
. Maybe this is already the case? I have no idea how the docker integration actually works at this point (I am hoping for some documentation).
This may be a little off topic, but I created a shell script in my PATH called docker
to override the docker command
#!/bin/bash -e
# The goal of this script is to maintain the security privileges of sudo
# Without having to constantly type "sudo"
exec sudo /usr/bin/docker "$@"
This seems like a much better solution that the docker group that gets widely used today. Maybe I am missing something.
unless the docker build commands that are automatically executed are restricted to just stack
That is correct, it the only thing it'll run automatically is stack
.
And using that wrapper is an excellent idea. I'll mention that in the docs I'm working on.
@gregwebs Does your method https://github.com/commercialhaskell/stack/issues/260#issuecomment-110858705 really work?
I put such a script in my $PATH (at $HOME/.local/bin/docker) and then
the initial stack docker pull
works, but for stack build
I get
...
@(System/Process/Read.hs:306:3)
2017-01-03 13:47:47.461984: [debug] Creating process: /home/me/.local/bin/docker start -a -i d63ea057b976fb01939e1de2e05e6f04207113685593b02a27d9fa4a070f1558
@(System/Process/Run.hs:102:5)
pid1: /opt/host/bin/stack: createProcess: runInteractiveProcess: exec: permission denied (Permission denied)
...
I have stack --version : Version 1.3.2 x86_64 hpack-0.15.0
, on Fedora 25, with docker
from their distro.
I have no experience with docker, but at least sudo docker run ubuntu /bin/echo 'Hello world'
does work for me.
Works for me
Currently, if a user has
docker
installed and set up so their user can run it withoutsudo
, it's possible to craft a stack.yaml that runs arbitrary commands as root. This is due to well-known security weaknesses with Docker and basically any arbitrary code you run on your system (like, say, downloading an executable or shell script, or building a Haskell package that uses TemplateHaskell) could also take advantage of it), so this is far from unique to stack.That said, I'd like to at least close the hole with stack.yaml, so that if you're doing your builds in a Docker container security is improved. I propose to disallow the following settings in the project's stack.yaml (but still allow them in global/user stack.yamls and from the command-line).
run-args
mount
pass-host
database-path
auto-pull
Since a user may want to change these settings for a project, adding the option of a "local" project config inside .stack-work may be desirable (kind of like you can add extra git excludes in
.git/extra/excludes
).In addition, any time a new image is encountered in a stack.yaml, an explicit action should be required to approve it with a big warning to not approve untrusted images. Anyone could craft a malicious image and point the
repo
setting to it, but I don't think we want to be in the business of whitelisting images.I also considered using the
docker run -u
option to always start containers as a non-root user, but anyone could still craft an image that has an entrypoint whichsudo
s to root, so that doesn't end up helping very much.