12 ms·
Docker is vulnerable to a symlink-race attack
- drogorbrn 7y agohttps://xkcd.com/1988/ https://xkcd.com/1988/
- keanebean86 7y agoThis gave me an existential crisis. We're told not to build our own since that's a waste of time and our version won't be as good. At the same time we're mocked for not understanding what we're using. What's the happy medium?
- have_faith 7y agoThere isn't one, we just accept the fragility of our options.
- i_am_nomad 7y agoNot caring what other people mock us for is a very happy medium.
- capitol_ 7y agoTo use things that you understand? It's perfectly possible to read through the documentation/code for the things that you want to use.
- codegladiator 7y ago> We're told not to build our own since that's a waste of time and our version won't be as good. We're told not to build our own since we don't understand what we're using
- swinglock 7y agoStudy what you use of course. Contribute if needed.
- gambler 7y agoThere is no happy medium. Due to its complexity, the whole ecosystem of modern software engineering is inherently dysfunctional. Being able to understand existing solutions and to create your own solutions that aren't broken toys is both essential.
- jameskilton 7y ago"Don't build your own" does not imply "just use what's there blindly". You should have an understanding of the tools you're using, but of course if you try to audit every line of code you include into your app (God help you if you're using node and npm/yarn) then you'll never get any work done. At some point you simply have to trust other developers, but don't be afraid to build your own, especially if it's smaller functionality (looking at you left-pad ...). Dependency management is a skill all developers should learn but it's not one that is actively taught or encouraged. Most (including myself) only really start learning once you've felt the bite of that one bad dependency, or fought through dependency upgrade hell. In short, make sure you're asking yourself "Do I really need this as a dependency or can I build something myself?"
- Xylakant 7y ago> (God help you if you're using node and npm/yarn) Try to audit gcc if you’re using C :)
- xfer 7y agoYou only have to audit the binary produced, not gcc.
- merb 7y agoand how do you do that? - btw. without reading bit per bit you still have a problem since you can't audit a binary with a full trust chain, i.e. the auditing tool needs to be audited aswell, etc...
- comex 7y agoThere’s CompCert, if you really want to go that far… Then there’s the question of auditing the hardware you’re running on ;)
- AlexB138 7y agoIt's not something to have a crisis about. We all stand on the shoulders of giants. There's too much out there to understand every facet yourself (for a fun example of this, go read I, Pencil) and have any time left over to actually make anything. Like most things in engineering, and life, it's a trade-off. The only problem here is the smirking know-it-all nature of comics like that.
- enriquto 7y ago> We all stand on the shoulders of giants. Sure! And this does not mean that once we are standing on them we can start to piss on their head. (e.g., the python programmers who despise C, or the matlab programmers who despise fortran). There is a worrying trend of ignorant programmers who dismiss "old-school" or "legacy" systems without realizing that they rely on them every day. You can mock perl, for example, but then you buy a brand-new macbook pro and unless you run "file /usr/bin/*|grep -i perl|wc -l" you do not realize how much your computer depends on the this language.
- thenewwazoo 7y ago"A novice was trying to fix a broken Lisp machine by turning the power off and on. Knight, seeing what the student was doing, spoke sternly: “You cannot fix a machine by just power-cycling it with no understanding of what is going wrong.” Knight turned the machine off and on. The machine worked."
- deleted 7y ago[deleted]
- worldsayshi 7y agoIf you'd like to venture further into this rabbit hole I can recommend "Preventing the Collapse of Civilization": https://www.youtube.com/watch?v=pW-SOdj4Kkk&list=LL6MdPYF0rDm71eTMnoEVwGg&index=2 https://www.youtube.com/watch?v=pW-SOdj4Kkk&list=LL6MdPYF0rD... And "The Thirty Million Line Problem": https://www.youtube.com/watch?v=kZRE7HIO3vk https://www.youtube.com/watch?v=kZRE7HIO3vk
- mrguyorama 7y agoThere is absolutely nothing wrong with building your own for personal projects, especially fun ones. The "don't reinvent the wheel" is more about how if you are ENGINEERING something, you should fully understand standards and best practices, how to use them, any configuration if needed, and composition of tools. The professional will use and understand tools, it's the enthusiast who builds his own.
- carrja99 7y agoFor me the happy medium is using the tools to get the job done, even if it entails building from scratch certain parts of the overall system.
- hinkley 7y agoI'd say the difference is in what you do with the one you built. In a number of disciplines, you might learn the basics of building a tool that you use, but you elect to use that knowledge to buy a good tool rather than mastering that problem domain. So what do you do with the one you built? Can you bring yourself to 'build one to throw away'? We struggle with this mightily. Once we've put effort into something and we have a 'thing' to show for it, we have trouble walking away from the thing. It's our form of hoarding.
- hinkley 7y agoI worked at a place that was processing voting for a TV show. The CTO at the time insisted that everything be written in-house so that we would understand how it all worked. Problem with that is that the code was full of bad documentation, obscure function names, unexpected behaviors and vast areas of missing functionality. Our people writing the software were less capable than the open source equivalents. With the support of some other people I was stumping for stewardship over authorship. Basically, we should have been allowed to use smaller libraries of Open Source software as long as one or more employees were intimately familiar with the internals of that library. For the one I wanted to use, I already knew it fairly well so I could have reached that level with a month or two of work. Instead I had to keep adding features and bug fixes to our busted piece of crap, or (more often) reimplement functionality in the caller.
- zzzeek 7y agoThe happy medium is build your own, do an amazing job, and don't care what some clueless middle manager who secretly hates that you are actually able to write your own is telling you. Also forget about sleeping or having any social or family life for the next eight years.
- deleted 7y ago[deleted]
- munchbunny 7y agoThe "don't build your own" advice has a more specific piece of wisdom embedded. When you build and use a non-trivial piece of software, you also create a large body of non-trivial design and reliability issues, which will take you many iterations and possibly rewrites to get right. Mature software has generally had time to address those issues, and what isn't addressed is better understood by the users and implementors. When you roll you own, you have to ask: compared to the thing I'm replacing, do I understand the problem domain well enough to anticipate the issues?
- PyroLagus 7y agoI definitely understand the sentiment of "don't build your own" when it comes to cryptography, but do people get mocked for not using Docker and instead using a traditional containerless setup? (Well, I guess people get mocked for anything.) Of course you shouldn't reinvent Docker; if you really need containers, use what's there (whether that's Docker or something else) and try to learn how it works, but I think there's more choices than just "use docker containers" or "build your own containers".
- nineteen999 7y agoWe run our core compute in-house (well, in datacenters); our application isn't particularly well suited for running in cloud hosting environments at all. In our environment, we don't use Docker at all. Well with one exception. There is a cross-compilation build environment for an Intel XScale based-industrial computer which is deployed to several hundred remote locations. The previous developer was fond of working alone unchecked and insisted on creating a (pet snowflake) Docker host and a set of containers into which he installed the SDK for said industrial PC. God only knows where he pulled the original Docker base image from. He spent a year doing this unchecked (amongst a few other things) so that he could pad out his CV with the word "Docker". And after that was done, he left the business. You start the Docker container and it fairly neatly builds the entire environment and creates a filesystem image which can be written to a CF card and installed in the physical industrial PC's, and handed to the field maintenance team. My point is - the whole build process for this could run on a bare VM which would be under our regular configuration management. The Docker container and host really provide no benefit in this situation (except perhaps quick start up time for a fresh build environment) and are really just a hassle, because we'd rather not mess with Docker. The integration into our Jenkins instance was a complete nightmare - we spent hours poring over the Docker documentation which we found sub-par, or too new (the Docker version he had installed was ancient by this point) and running afoul of various Docker bugs. We don't have enough other use cases for Docker to make it worthwhile for the rest of the team to learn in depth at this point. It's still on my TODO list to de-dockerize this build process and nuke that Docker host VM forever.
- drdaeman 7y ago> What's the happy medium? Possibly, not building your own, but investing some time researching how others have built already existing tech? That helps if what's out there doesn't work for you - either if it breaks (and you have to fix someone else's stuff that you use) or lacks feature-wise (and you _have_ to build your own, either by extending or re-designing).
- MagicPropmaker 7y agoWhy is MalwareBytes giving a warning for this site?
- phoe-krk 7y agoMalwareBytes is wrong. seclists is a website containing security mailing lists, and CVE mails are a very common sight there.
- smpetrey 7y agoBecause MalwareBytes is scareware?
- MagicPropmaker 7y agoI'd still like to know why MalwareBytes is warning me about this page. If you can't answer that, why mock someone?
- pushpop 7y agoEdit: you’ve hacked your comment after I replied so much that this post no long bares any context to the question it was originally responding to....
- MagicPropmaker 7y agoAnd it's not true that MalwareBytes is "scareware". I'm sure the person saying that is simply some 12-year-old who wants to show the Windows user that he runs Linux and is a "l33t h4x0r" or something and knows better than my (commercial) security software. MalwareBytes is actually reporting that something on that page is trying to make an outbound connection to port 50685 on ip address 45.33.49.119. I don't know what to make of this, but it smells fishy. It's very odd that this program will make a claim if there isn't something going on. I'm not going to risk visiting that page.
- pushpop 7y ago
- raesene9 7y agoSo from a reading of the advisory and pull request, this seems to affect a specific set of scenarios, where a malicious image is running (attacker has gained access either to the running container, or compromised the image before distribution) and then a process goes to copy data out of the running container (for example by using docker cp). Not sure if there are other scenarios where this would hit as well. One to be aware of, but as with most vulnerabilities, good to understand how it can be exploited, when you're assessing mitigations...
- chatmasta 7y agoMany services allow uploading arbitrary images. This is certainly a threat they should mitigate against in their sandboxing strategies.
- rtempaccount1 7y agoWould an arbitrary image upload alone allow exploitation of this, or would it require an operation on the host along the lines of a 'docker cp' as well?
- chatmasta 7y agoI’m not entirely sure, as I could only read 50% of the article’s text on my mobile phone...
- cpuguy83 7y agoNo, the vulnerability is within the API for `docker cp`, specifically.
- cyphar 7y agoThe only currently known and exploitable API is with `docker cp`, but FollowSymlinkInScope is used all over the place. Unfortunately, fixing FollowSymlinkInScope requires redesigning the API and then redesigning all the callers so they stop passing around path strings blindly and instead pass around handles (which are O_PATH fds). But, as I mentioned in TFA, the plan is to rework https://github.com/cyphar/filepath-securejoin https://github.com/cyphar/filepath-securejoin to have a sane API that detects attacks on older kernels while using the new kernel bits (once merged).
- Bucephalus355 7y agoThis is a known attack for quite sometime. The Apache Web Server, which I love/hate, has for years never really been 100% secure because of issues with how the Linux kernel handles FollowSymLinks and SymLinksIfOwnersMatch. You can purchase special distributions of Linux that are patched against this vulnerability, and also I believe this gentleman [1] has released an OS patch that sort of fixes the issue. Anyway I switched to Caddy [2] even though I deeply love Apache and it has an amazing history behind it. [1] https://twitter.com/hanno https://twitter.com/hanno [2] https://caddyserver.com/ https://caddyserver.com/
- xrisk 7y agoCaddy is brilliant. Configuration is so simple and easy compared to Apache / Nginx.
- tdhz77 7y agoHave you tried Traefik ?
- tepidandroid 7y agoDifferent use-cases.
- cargoshipit 7y agoAre you serious? Their kubernetes setup guide is longer than War and Peace https://docs.traefik.io/v1.4/user-guide/kubernetes/ https://docs.traefik.io/v1.4/user-guide/kubernetes/
- tdhz77 7y agoNot sure what that has to do with anything.
- mholt 7y agoThank you!! These comments made my day. Feel free to open an issue on GitHub if you have any ideas for how to improve it even more, since the sky's the limit for Caddy 2. https://github.com/mholt/caddy/issues https://github.com/mholt/caddy/issues
- deleted 7y ago[deleted]
- kazinator 7y agoI think symlink attacks could, at least in some situations, be prevented by a Boolean function (perhaps in the kernel) which validates a path. It returns true if the path is immune to symlink attacks, false otherwise. Immune to symlink attacks means this: the path is walked, and the permissions of each directory are checked to make sure that it isn't open for anyone to create a symlink (anyone whose effective ID is not either root, or the caller). If the path is relative, then the current working directory is prepended to it for the purposes of checking. (A nuance here that has to be taken into account is sticky-bit directories like /tmp.) If the path contains symlinks, then we have to validate that the real parent directory of the symlink target doesn't allow that target to be replaced. E.g. we are following /foo/bar and bar is a symlink to /xyzzy/pop. If /xyzzy is writable to adversaries, pop can be replaced by a malicious symlink even if pop itself isn't writable to other users. Anyway, the idea is that if a path we would like to operate on has any components vulnerable to manipulation, we fail the entire operation. Things can be simplified if we canonicalize the path (so it is free of symlinks) but that is often undesirable. Software should keep the paths it has been given as-is; the symlink abstraction belongs to the user and should be respected.
- the8472 7y agoOr you can use the open + O_PATH + *at syscall family which can be used to get a handle on a resolved directory relative to which you can manipulate with no re-traversal happening for different operations on that handle. This combo exists exactly to avoid these kinds of issues. Another way would be temporarily joining the container's mount namespace to obtain the source handle. But that can't really be done in go since goroutines don't play nicely with per-thread operations. Edit: After looking through the go standard library it seems that there is an impedance mismatch. Go just does not expose the necessary pieces to do this properly. A dedicated docker-cp tool in C or Rust could probably handle this better. I could be wrong though, maybe it's just not part of the stdlib.
- kazinator 7y agoBut that starting point has to be initially checked somehow. Say we are user "bob" we open "/foo/bar/xyzzy" (for later use with openat), and, say, "bar" is writable to "mallory", then that isn't a path we can trust in the first place. O_PATH is a Linux Kernel 4.x thing; can't find it in POSIX. Won't compile on non-Linux POSIX operating systems or older kernels. It seems to be an optimization; if we omit it, we just get a "fatter" file descriptor that takes more cycles to set up.
- ga-vu 7y agoNot that big of a deal after you read it, though
- deleted 7y ago[deleted]
- bayareanative 7y ago"Docker is vulnerable" is also a valid statement at present, hopefully it will improve by the forces of $$$ and tech fashionablism.
- phoe-krk 7y agoIt won't. Docker already has too much inertia to be stopped by a single CVE. The "it's just another bug of an actively supported piece of software, we'll just update tomorrow" behaviour will click.