mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2026-02-27 07:58:30 +03:00
Lots of vulnerabilities in Docker images #460
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @AlexandreGohier on GitHub (Oct 24, 2019).
Hello,
First of all: thanks for the great work 👏 !!
I ran a trivy scan on the latest docker amd64 image and there is a bunch of vulnerabilities inherited from upstream images.
I'm considering BW for production password storage and I need a few independent instances, so the docker road was tempting. Any idea on how to improve this? Have you had problems in the past updating to the latest alpine and rust images? I'm guessing this won't fix all the vulns since some of them are many years old...
If you could share your experience with this I would very much appreciate.
Thanks.
FYI, scan results below:
@dani-garcia commented on GitHub (Oct 24, 2019):
Good point, I've updated the base images that used debian stretch to the new buster, and while I was at it decided to update the rest. (
57b1d3f850)That said, most of those vulnerabilities are on programs we don't interact with at all, so I can't imagine they pose a big threat. That said we should try to minimize them as much as we can, though at the end of the day we depend on those base images being updated in the first place.
@AlexandreGohier commented on GitHub (Oct 25, 2019):
Thank you for the quick feedback and update.
IMO, even for an average app, having vulnerable packages included in the image is not great, not so much for the risk it poses on the app itself but for the way they can be leveraged (use as pivot on the network for instance). In the case of BW, an app with the very purpose of storing and serving secrets, I would try as much as possible to avoid any unnecessary vulnerability. The stakes are similar to protecting a directory such as LDAP or AD. Once identified, this composant would be a prime target.
Imagine if someone manages a SSRF on the app (server side request forgery). If you’re not familiar with that, this attack consists on successfully getting the app to run a request, or a command of our choosing, on the server. Unless the attacker also manages to perform a remote file inclusion (RFI), the only available tools / commands will be those already at hand on the server. This is called “Living of the Land”. So if our attacker has got 200 vulnerabilities at his/her disposal, it’s a pretty good start. Of course this would need to be a multi-stage operation, but owning the back-end server is a pretty good start, even if the stored content is fully encrypted. If the same attacker manages to serve compromised client-side code, such as a modified web vault or os client (in a supply-chain attack scenario), then it would be possible to send unencrypted data instead. Without owning the back-end database, the data would need to be sent somewhere else, thus requiring to either drop https altogether or managing to bypass the same origin policy (SOP), which requires additional work.
We do depend on base images to be updated and that’s a real issue at the moment. Snyk highlighted this earlier this year in their annual report, a very interesting read. But using the latest base images is already an improvement. I ran a new trivy scan based on your updates and the number of vulnerabilities was cut in half overall, the “high” vulnerabilities dropped from 45 to 10 and the “critical” ones from 3 to 1 (see below). So unless these updated base images break something (a dependency or something else), I would strongly encourage you to push this new updated image and thank you in advance for it!
Another improvement you can consider in the longer term is including the free Aquasec microscanner in your image build process. This will fail the build if any known high or critical vulnerability is included / identified. This would of course require a prior fix of the remaining 11 high/critical vulnerabilities…
New scan results:
@dani-garcia commented on GitHub (Oct 26, 2019):
The images should be updated now after I fixed the failing docker builds, about the vulnerabilities left, we could consider uninstalling those packages if they aren't needed by the system, because other than openssl and sqlite (maybe libc too?), we don't use them.
Can you also test the alpine image? It's a smaller image so I can imagine it might have less vulnerabilities present.
@AlexandreGohier commented on GitHub (Oct 27, 2019):
Yes, uninstalling unnecessary packages would certainly be a huge improvement, it's a best security practice anyway to reduce the overall attack surface.
The latest Debian image results are much better as tested before (new test on registry image):
The new alpine image is squeaky clean !! :
Are there any functional or technical downsides to using the Alpine image instead of Debian?
And for information (also to anyone reading this in the future), Trivy is free and open-source. One binary to compile or install, and scanning an image is as simple as:
The full output looks like this. The vulnerability database sync takes the longest (a little over a minute here) :
Thank you very much for these image updates.
@mprasil commented on GitHub (Oct 27, 2019):
Not really, they should be functionally the same. The problem is, that we don't have MySQL variants of alpine image, but if you don't need that you're fine. This makes me wonder - because the alpine version is statically linked binary, does that mean some of the library vulnerabilities would apply even on alpine considering the binary is built on debian-based image?
As for the vulnerabilities in the main image, many do not apply in the context of docker image. For example all of the systemd-related issues rely on systemd actually running which is not the case. Many of the privilege escalation vulnerabilities also rely on privileged process already running, but we only run bitwarden_rs inside the container, nothing else. I'm not saying we shouldn't try to get rid of those, but the criticality might be much lower in our context.
As for removing unneeded packages, I think we could try to do that, many of those are there as an dependency for debian (especially apt) itself, so we would have to do that as last step.
@AlexandreGohier commented on GitHub (Oct 27, 2019):
Thanks for that answer. I was wondering why use MySQL or Postgre instead of sqLite? Is it just a matter of benefiting from operational workflows already in-place or are there other benefits? Not wanting to host a MSSQL server instance is what got me looking at bitwarden_rs in the first place... Since other forks can run on lambda and dynamodb, it must mean most of the data is key-value based. In a distributed, high-availability scenario, something such as Consul would probably also make a robust back-end storage option.
I'm not familiar enough with Alpine to risk an answer to that. However, running a scan on older Alpine images does identify some vulnerabilities that were since patched:
Agreed, this is probably not a high priority task but any opportunity to improve the situation without requiring a lot of extra work would be worth exploring IMO. Again, this is a security tool so it's a tasty target. And just because we can't imagine attack scenarios based on previous incidents doesn't mean much given how creative attackers are!
@mprasil commented on GitHub (Oct 27, 2019):
I've ran couple for loops trying to figure out non-essential packages 😄 and here's how many we could remove as last step in the debian-based image:
This still leaves couple vulnerable packages in:
Unfortunately these are either our direct dependencies or dependencies of
curl(probably most of these) andsqlite. We could get rid ofcurlbut that would mean removing health check. We could also get rid ofsqlitebut we added this to enable backup button in admin interface.And I should add that removing above packages essentially renders the system inside completely broken to the point that it's unable to install them back. It still works for the purpose of running the service, but for any users using our image as base image and adding more stuff on top, this would break their setup without any good alternative.
So I'm very hesitant about doing this. Especially with the understanding that most of the issues do not present a problem inside a container with single
bitwarden_rsprocess, so the benefits are really questionable. Maybe we could point security strict users to alpine as that image is leaner and hence ships with less (or none) vulnerable packages? (the price being paid here is that we don't have MySQL image available)As with everything here, there are millions of reasons. The benefit of using something already in place is one thing I've often saw as argument to implement it. It was clearly tangible enough benefit for multiple users to implement this and submit a PR.
Thanks for raising this BTW, trivy looks quite cool and I'm glad I've learned about it.
@AlexandreGohier commented on GitHub (Oct 27, 2019):
I understand, it's anyone's guess what use is made of the image downstream. You could try forking the Debian image in two variants: "debian_hardened" and "debian_full", put the "latest" tag on the hardened one, write a short wiki about the change and check the download stats of both images. If no one notices, then the full image can be dropped over time and everyone benefits from added invisible security. If on the other hand there are complaints and significant downloads of the full image, then there might not be a use-case for the hardened image (the Alpine one would still be a hardening option indeed).
Thank you again very much for caring about security!
@dani-garcia commented on GitHub (Oct 27, 2019):
Personally I never heard of someone depending on our image as a base, I think anyone doing that would be better just modifying our dockerfiles and building it themselves.
If we could get the alpine image building correctly for all databases we could point to that one as the more secure one, or even discontinue the debian based, which wouldn't offer any benefits.
@AlexandreGohier commented on GitHub (Oct 27, 2019):
Yes even better if that can be achieved.
@mprasil commented on GitHub (Oct 28, 2019):
I was curious, so tried to search and actually found image that's using our image as one of the sources. That is one public image that we know of. Forking our repo and modifying the Dockerfile is quite a lot more effort to keep up with compared to keeping your simple Dockerfile that probably has couple lines in it and pretty much never changes. So I wouldn't be surprised there are more users like that.
We've also suggested that people should add sqlite on top of our image in the past to avail of admin backup functionality.
Plus let me reiterate that even if we did all that, we still need curl and sqlite inside. So breaking
aptjust to removetaris still meaningless exercise all things considered. I mean you'd be literary trying to fix an issue that is absolutely irrelevant:I mean how likely are you to trick someone to go inside the docker container and unpack an tar file with malicious content and then you need to get inside that container yourself as non-root (which in all honesty won't be the case, you'll be root already) and you'd use the trick to gain root privileges.. (the issue is just warning mind you, even fixed version wouldn't prevent such files being created..)
So yeah, I do think most of the security issues are absolutely irrelevant in our context.
I'd be up for using alpine as default image, but we need to figure out reliable way to compile statically linked binaries for all versions of backends we use.
@AlexandreGohier commented on GitHub (Oct 29, 2019):
That's probably the best medium-term bet. For the Debian-based images, the real sustainable solution anyway is to patch or to reduce the attack surface upstream... meanwhile it may be more efficient to work on new functionalities for the Alpine image instead, that's less likely to break things for downstream projects. I've started using the Alpine image and I can't tell the difference so far. There are probably many sqlite users that went for the default Debian image like I did but could do with Alpine.
Should we close this issue?
@tckb commented on GitHub (Oct 29, 2019):
any updates on this one? did we come to a conclusion or any one have a better base image with less vulnerabilities ?
@gnu300 commented on GitHub (Nov 20, 2019):
After building the image based on the Dockerfile i scanned it with clair. The result of the scan shows that there are 3 vulnerabilities left for which already a fixed version exists:
@AlexandreGohier commented on GitHub (Nov 20, 2019):
It would be interesting to compare the scan results between clair and trivy for the same image. AFAIK, trivy can detect more vulns in 3rd party libraries.
@frdescam commented on GitHub (May 19, 2020):
I saw that now the amd64 image is built on alpine, but what about the other arch? It would be great to have an alpine based image for raspberry (for security and lightness), is there any limitation on building from alpine for arm?
@dadatuputi commented on GitHub (May 27, 2020):
Regarding vulnerable packages, what about updating them using a package manager (apt, apk, etc), assuming that the repos have patched versions of the vulnerable programs and libraries? Instead of removing them, just update them on each run.
@gnu300 commented on GitHub (May 28, 2020):
I would go for a more progressive approach and think about a distroless container:
https://www.andreafortuna.org/2020/02/19/the-distroless-approach-to-docker-containers/
https://github.com/GoogleContainerTools/distroless
@BlackDex commented on GitHub (Sep 22, 2020):
That is nice for go applications since they most of the time are build statically by default and thus could use a very small base system. Unfortunately for us to build statically we would need to use musl, which is causing some errors during build.
To not make it more complex i think it is better to keep it as is and just keep updating too the most recent base image.
@BlackDex commented on GitHub (Oct 4, 2020):
We have updates the Final docker base for the builds some time back.
Creating static builds or bare containers is something we could look at in the future. Lets put this on the meta features requests.
@reneleonhardt commented on GitHub (Jun 24, 2025):
@BlackDex You are using musl in Dockerfile.alpine, can a static build be revised?
In addition, is there a technical reason to run as root and opening port 80?
I'm wondering, wouldn't rust-postgres be enough to allow connecting to Postgres without libpq5 and openssl via native-tls? 🤔
@BlackDex commented on GitHub (Jun 25, 2025):
We can only use libraries supported by the Diesel ORM which is only
pq-sys, so probably not.native-tlsstill uses openssl, so not sure what you will gain with that route? What is wrong with the current way?Vaultwarden on Alpine is fully static, and i can even run it on my Android.
I still have a busybox/from-scratch image on my to-do list, probably busybox since there are some scripts we use to allow some modifications.
Also, port 80 shouldn't be an issue modern docker/podman work just fine with that port without root even.
And it's more historically that it currently runs as root, but changing it could cause issues with current deployments. The busybox on my to-do list would not be running as root though.