{"id":13435670,"url":"https://github.com/containers/bubblewrap","last_synced_at":"2025-12-11T21:48:58.711Z","repository":{"id":4086238,"uuid":"51868010","full_name":"containers/bubblewrap","owner":"containers","description":"Low-level unprivileged sandboxing tool used by Flatpak and similar projects","archived":false,"fork":false,"pushed_at":"2024-10-30T16:27:17.000Z","size":952,"stargazers_count":4285,"open_issues_count":152,"forks_count":253,"subscribers_count":54,"default_branch":"main","last_synced_at":"2025-05-06T12:48:58.681Z","etag":null,"topics":["linux-containers","user-namespaces"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/containers.png","metadata":{"files":{"readme":"README.md","changelog":"NEWS.md","contributing":null,"funding":null,"license":"COPYING","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-02-16T20:36:10.000Z","updated_at":"2025-05-06T06:10:27.000Z","dependencies_parsed_at":"2023-07-06T01:52:28.417Z","dependency_job_id":"732aee15-2176-488d-a10e-5460c76a2a20","html_url":"https://github.com/containers/bubblewrap","commit_stats":{"total_commits":548,"total_committers":67,"mean_commits":8.17910447761194,"dds":0.7007299270072993,"last_synced_commit":"9ca3b05ec787acfb4b17bed37db5719fa777834f"},"previous_names":["projectatomic/bubblewrap"],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Fbubblewrap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Fbubblewrap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Fbubblewrap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Fbubblewrap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/containers","download_url":"https://codeload.github.com/containers/bubblewrap/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253820518,"owners_count":21969534,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linux-containers","user-namespaces"],"created_at":"2024-07-31T03:00:37.911Z","updated_at":"2025-12-11T21:48:53.671Z","avatar_url":"https://github.com/containers.png","language":"C","readme":"Bubblewrap\n==========\n\nMany container runtime tools like `systemd-nspawn`, `docker`,\netc. focus on providing infrastructure for system administrators and\norchestration tools (e.g. Kubernetes) to run containers.\n\nThese tools are not suitable to give to unprivileged users, because it\nis trivial to turn such access into a fully privileged root shell\non the host.\n\nUser namespaces\n---------------\n\nThere is an effort in the Linux kernel called\n[user namespaces](https://www.google.com/search?q=user+namespaces+site%3Ahttps%3A%2F%2Flwn.net)\nwhich attempts to allow unprivileged users to use container features.\nWhile significant progress has been made, there are\n[still concerns](https://lwn.net/Articles/673597/) about it, and\nit is not available to unprivileged users in several production distributions\nsuch as CentOS/Red Hat Enterprise Linux 7, Debian Jessie, etc.\n\nSee for example\n[CVE-2016-3135](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3135)\nwhich is a local root vulnerability introduced by userns.\n[This March 2016 post](https://lkml.org/lkml/2016/3/9/555) has some\nmore discussion.\n\nBubblewrap could be viewed as setuid implementation of a *subset* of\nuser namespaces.  Emphasis on subset - specifically relevant to the\nabove CVE, bubblewrap does not allow control over iptables.\n\nThe original bubblewrap code existed before user namespaces - it inherits code from\n[xdg-app helper](https://cgit.freedesktop.org/xdg-app/xdg-app/tree/common/xdg-app-helper.c?id=4c3bf179e2e4a2a298cd1db1d045adaf3f564532)\nwhich in turn distantly derives from\n[linux-user-chroot](https://git.gnome.org/browse/linux-user-chroot).\n\nSystem security\n---------------\n\nThe maintainers of this tool believe that it does not, even when used\nin combination with typical software installed on that distribution,\nallow privilege escalation.  It may increase the ability of a logged\nin user to perform denial of service attacks, however.\n\nIn particular, bubblewrap uses `PR_SET_NO_NEW_PRIVS` to turn off\nsetuid binaries, which is the [traditional way](https://en.wikipedia.org/wiki/Chroot#Limitations) to get out of things\nlike chroots.\n\nSandbox security\n----------------\n\nbubblewrap is a tool for constructing sandbox environments.\nbubblewrap is not a complete, ready-made sandbox with a specific security\npolicy.\n\nSome of bubblewrap's use-cases want a security boundary between the sandbox\nand the real system; other use-cases want the ability to change the layout of\nthe filesystem for processes inside the sandbox, but do not aim to be a\nsecurity boundary.\nAs a result, the level of protection between the sandboxed processes and\nthe host system is entirely determined by the arguments passed to\nbubblewrap.\n\nWhatever program constructs the command-line arguments for bubblewrap\n(often a larger framework like Flatpak, libgnome-desktop, sandwine\nor an ad-hoc script) is responsible for defining its own security model,\nand choosing appropriate bubblewrap command-line arguments to implement\nthat security model.\n\nSome aspects of sandbox security that require particular care are described\nin the [Limitations](#limitations) section below.\n\nUsers\n-----\n\nThis program can be shared by all container tools which perform\nnon-root operation, such as:\n\n - [Flatpak](https://www.flatpak.org)\n - [rpm-ostree unprivileged](https://github.com/projectatomic/rpm-ostree/pull/209)\n - [bwrap-oci](https://github.com/projectatomic/bwrap-oci)\n\nWe would also like to see this be available in Kubernetes/OpenShift\nclusters.  Having the ability for unprivileged users to use container\nfeatures would make it significantly easier to do interactive\ndebugging scenarios and the like.\n\nInstallation\n------------\n\nbubblewrap is available in the package repositories of the most Linux distributions\nand can be installed from there.\n\nIf you need to build bubblewrap from source, you can do this with meson:\n\n```sh\nmeson _builddir\nmeson compile -C _builddir\nmeson test -C _builddir\nmeson install -C _builddir\n```\n\nUsage\n-----\n\nbubblewrap works by creating a new, completely empty, mount\nnamespace where the root is on a tmpfs that is invisible from the\nhost, and will be automatically cleaned up when the last process\nexits. You can then use commandline options to construct the root\nfilesystem and process environment and command to run in the\nnamespace.\n\nThere's a larger [demo script](./demos/bubblewrap-shell.sh) in the\nsource code, but here's a trimmed down version which runs\na new shell reusing the host's `/usr`.\n\n```\nbwrap \\\n    --ro-bind /usr /usr \\\n    --symlink usr/lib64 /lib64 \\\n    --proc /proc \\\n    --dev /dev \\\n    --unshare-pid \\\n    --new-session \\\n    bash\n```\n\nThis is an incomplete example, but useful for purposes of\nillustration.  More often, rather than creating a container using the\nhost's filesystem tree, you want to target a chroot.  There, rather\nthan creating the symlink `lib64 -\u003e usr/lib64` in the tmpfs, you might\nhave already created it in the target rootfs.\n\nSandboxing\n----------\n\nThe goal of bubblewrap is to run an application in a sandbox, where it\nhas restricted access to parts of the operating system or user data\nsuch as the home directory.\n\nbubblewrap always creates a new mount namespace, and the user can specify\nexactly what parts of the filesystem should be visible in the sandbox.\nAny such directories you specify mounted `nodev` by default, and can be made readonly.\n\nAdditionally you can use these kernel features:\n\nUser namespaces ([CLONE_NEWUSER](https://linux.die.net/man/2/clone)): This hides all but the current uid and gid from the\nsandbox. You can also change what the value of uid/gid should be in the sandbox.\n\nIPC namespaces ([CLONE_NEWIPC](https://linux.die.net/man/2/clone)): The sandbox will get its own copy of all the\ndifferent forms of IPCs, like SysV shared memory and semaphores.\n\nPID namespaces ([CLONE_NEWPID](https://linux.die.net/man/2/clone)): The sandbox will not see any processes outside the sandbox. Additionally, bubblewrap will run a trivial pid1 inside your container to handle the requirements of reaping children in the sandbox. This avoids what is known now as the [Docker pid 1 problem](https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/).\n\n\nNetwork namespaces ([CLONE_NEWNET](https://linux.die.net/man/2/clone)): The sandbox will not see the network. Instead it will have its own network namespace with only a loopback device.\n\nUTS namespace ([CLONE_NEWUTS](https://linux.die.net/man/2/clone)): The sandbox will have its own hostname.\n\nSeccomp filters: You can pass in seccomp filters that limit which syscalls can be done in the sandbox. For more information, see [Seccomp](https://en.wikipedia.org/wiki/Seccomp).\n\nLimitations\n-----------\n\nAs noted in the [Sandbox security](#sandbox-security) section above,\nthe level of protection between the sandboxed processes and the host system\nis entirely determined by the arguments passed to bubblewrap.\nSome aspects that require special care are noted here.\n\n- If you are not filtering out `TIOCSTI` commands using seccomp filters,\nargument `--new-session` is needed to protect against out-of-sandbox\ncommand execution\n(see [CVE-2017-5226](https://github.com/containers/bubblewrap/issues/142)).\n\n- Everything mounted into the sandbox can potentially be used to escalate\nprivileges.\nFor example, if you bind a D-Bus socket into the sandbox, it can be used to\nexecute commands via systemd. You can use\n[xdg-dbus-proxy](https://github.com/flatpak/xdg-dbus-proxy) to filter\nD-Bus communication.\n\n- Some applications deploy their own sandboxing mechanisms, and these can be\nrestricted by the constraints imposed by bubblewrap's sandboxing.\nFor example, some web browsers which configure their child proccesses via\nseccomp to not have access to the filesystem. If you limit the syscalls and\ndon't allow the seccomp syscall, a browser cannot apply these restrictions.\nSimilarly, if these rules were compiled into a file that is not available in\nthe sandbox, the browser cannot load these rules from this file and cannot\napply these restrictions.\n\nRelated project comparison: Firejail\n------------------------------------\n\n[Firejail](https://github.com/netblue30/firejail/tree/HEAD/src/firejail)\nis similar to Flatpak before bubblewrap was split out in that it combines\na setuid tool with a lot of desktop-specific sandboxing features.  For\nexample, Firejail knows about Pulseaudio, whereas bubblewrap does not.\n\nThe bubblewrap authors believe it's much easier to audit a small\nsetuid program, and keep features such as Pulseaudio filtering as an\nunprivileged process, as now occurs in Flatpak.\n\nAlso, @cgwalters thinks trying to\n[whitelist file paths](https://github.com/netblue30/firejail/blob/37a5a3545ef6d8d03dad8bbd888f53e13274c9e5/src/firejail/fs_whitelist.c#L176)\nis a bad idea given the myriad ways users have to manipulate paths,\nand the myriad ways in which system administrators may configure a\nsystem.  The bubblewrap approach is to only retain a few specific\nLinux capabilities such as `CAP_SYS_ADMIN`, but to always access the\nfilesystem as the invoking uid.  This entirely closes\n[TOCTTOU attacks](https://cwe.mitre.org/data/definitions/367.html) and\nsuch.\n\nRelated project comparison: Sandstorm.io\n----------------------------------------\n\n[Sandstorm.io](https://sandstorm.io/) requires unprivileged user\nnamespaces to set up its sandbox, though it could easily be adapted\nto operate in a setuid mode as well. @cgwalters believes their code is\nfairly good, but it could still make sense to unify on bubblewrap.\nHowever, @kentonv (of Sandstorm) feels that while this makes sense\nin principle, the switching cost outweighs the practical benefits for\nnow. This decision could be re-evaluated in the future, but it is not\nbeing actively pursued today.\n\nRelated project comparison: runc/binctr\n----------------------------------------\n\n[runC](https://github.com/opencontainers/runc) is currently working on\nsupporting [rootless containers](https://github.com/opencontainers/runc/pull/774),\nwithout needing `setuid` or any other privileges during installation of\nrunC (using unprivileged user namespaces rather than `setuid`),\ncreation, and management of containers. However, the standard mode of\nusing runC is similar to [systemd nspawn](https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html)\nin that it is tooling intended to be invoked by root.\n\nThe bubblewrap authors believe that runc and systemd-nspawn are not\ndesigned to be made setuid, and are distant from supporting such a mode.\nHowever with rootless containers, runC will be able to fulfill certain usecases\nthat bubblewrap supports (with the added benefit of being a standardised and\ncomplete OCI runtime).\n\n[binctr](https://github.com/jfrazelle/binctr) is just a wrapper for\nrunC, so inherits all of its design tradeoffs.\n\nWhat's with the name?!\n----------------------\n\nThe name bubblewrap was chosen to convey that this\ntool runs as the parent of the application (so wraps it in some sense) and creates\na protective layer (the sandbox) around it.\n\n![](bubblewrap.jpg)\n\n(Bubblewrap cat by [dancing_stupidity](https://www.flickr.com/photos/27549668@N03/))\n","funding_links":[],"categories":["HarmonyOS","C","System Components","others","Tools, Applications, Libraries, Frameworks","Host-based tools","Foundational sandbox primitives and low-level tooling","Sandboxing \u0026 Isolation"],"sub_categories":["Windows Manager","Sandboxing","Sandboxes","Linux"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontainers%2Fbubblewrap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcontainers%2Fbubblewrap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontainers%2Fbubblewrap/lists"}