[GH-ISSUE #796] Jail escape through DBus #539

Closed
opened 2026-05-05 06:04:44 -06:00 by gitea-mirror · 23 comments
Owner

Originally created by @lheckemann on GitHub (Sep 19, 2016).
Original GitHub issue: https://github.com/netblue30/firejail/issues/796

Blacklisting client/server-based terminal emulators is not sufficient to avoid jailbreaks. For example, if GNOME Terminal is installed, one can escape using a wide variety of tools, such as gdbus or DBus bindings for the language of the attacker's choice.

Example:

# Start service
gdbus call --session --dest=org.freedesktop.DBus --object-path=/org/freedesktop/DBus -m org.freedesktop.DBus.StartServiceByName org.gnome.Terminal 0
# Open terminal window
gdbus call --session --dest=org.gnome.Terminal --object-path=/org/gnome/Terminal/Factory0 -m org.gnome.Terminal.Factory0.CreateInstance '{"display":<b":1">}'
# Will return something like (objectpath '/org/gnome/Terminal/window/14/terminal/714ab892_a1fa_41fa_ad03_6ad202fdce9f',)
# Use this path for the next call
# Start a shell
gdbus call --session --dest=org.gnome.Terminal --object-path=/org/gnome/Terminal/window/15/terminal/714ab892_a1fa_41fa_ad03_6ad202fdce9f -m org.gnome.Terminal.Terminal0.Exec '[]' '[]'
# Or something else
gdbus call --session --dest=org.gnome.Terminal --object-path=/org/gnome/Terminal/window/15/terminal/714ab892_a1fa_41fa_ad03_6ad202fdce9f -m org.gnome.Terminal.Terminal0.Exec '[]' '[b"echo", b"hello"]'

Of course there are diverse other attack options through DBus, such as shutting down the system through UPower, unmounting things mounted through GVFS, etc.

As a lot of applications will not work without access to DBus, there needs to be some more fine-grained access control to only allow applications access to the interfaces they really need...

Originally created by @lheckemann on GitHub (Sep 19, 2016). Original GitHub issue: https://github.com/netblue30/firejail/issues/796 Blacklisting client/server-based terminal emulators is not sufficient to avoid jailbreaks. For example, if GNOME Terminal is installed, one can escape using a wide variety of tools, such as `gdbus` or DBus bindings for the language of the attacker's choice. Example: ``` bash # Start service gdbus call --session --dest=org.freedesktop.DBus --object-path=/org/freedesktop/DBus -m org.freedesktop.DBus.StartServiceByName org.gnome.Terminal 0 # Open terminal window gdbus call --session --dest=org.gnome.Terminal --object-path=/org/gnome/Terminal/Factory0 -m org.gnome.Terminal.Factory0.CreateInstance '{"display":<b":1">}' # Will return something like (objectpath '/org/gnome/Terminal/window/14/terminal/714ab892_a1fa_41fa_ad03_6ad202fdce9f',) # Use this path for the next call # Start a shell gdbus call --session --dest=org.gnome.Terminal --object-path=/org/gnome/Terminal/window/15/terminal/714ab892_a1fa_41fa_ad03_6ad202fdce9f -m org.gnome.Terminal.Terminal0.Exec '[]' '[]' # Or something else gdbus call --session --dest=org.gnome.Terminal --object-path=/org/gnome/Terminal/window/15/terminal/714ab892_a1fa_41fa_ad03_6ad202fdce9f -m org.gnome.Terminal.Terminal0.Exec '[]' '[b"echo", b"hello"]' ``` Of course there are diverse other attack options through DBus, such as shutting down the system through UPower, unmounting things mounted through GVFS, etc. As a lot of applications will not work without access to DBus, there needs to be some more fine-grained access control to only allow applications access to the interfaces they really need...
gitea-mirror 2026-05-05 06:04:44 -06:00
Author
Owner

@chiraag-nataraj commented on GitHub (Sep 19, 2016):

So apparently using net none mitigates this problem as DBus is unable to do anything. Obviously this isn't a huge mitigating factor since there are many programs which require internet access...

<!-- gh-comment-id:248047284 --> @chiraag-nataraj commented on GitHub (Sep 19, 2016): So apparently using `net none` mitigates this problem as DBus is unable to do anything. Obviously this isn't a huge mitigating factor since there are many programs which require internet access...
Author
Owner

@chiraag-nataraj commented on GitHub (Sep 19, 2016):

Also, is fine-grained control of DBus even possible without a complete rewrite of DBus itself? I guess one way is to blacklist DBus service files. That would entail letting blacklist and whitelist operate on /usr...is that an option @netblue30?

<!-- gh-comment-id:248049403 --> @chiraag-nataraj commented on GitHub (Sep 19, 2016): Also, is fine-grained control of DBus even possible without a complete rewrite of DBus itself? I guess one way is to blacklist DBus service files. That would entail letting blacklist and whitelist operate on /usr...is that an option @netblue30?
Author
Owner

@netblue30 commented on GitHub (Sep 19, 2016):

DBus runs an abstract socket, very similar to x11. So far there are two ways to stop it: --net= and --apparmor. I will document it on the Known Problems page on project website.

<!-- gh-comment-id:248057557 --> @netblue30 commented on GitHub (Sep 19, 2016): DBus runs an abstract socket, very similar to x11. So far there are two ways to stop it: --net= and --apparmor. I will document it on the Known Problems page on project website.
Author
Owner

@lheckemann commented on GitHub (Sep 19, 2016):

@chiraag-nataraj it's also possible to prevent access to DBus using --net=inet,inet6 which still allows internet access. What's necessary for a good sandboxing solution though is being able to control DBus access in a more fine-grained manner, because some applications require access to DBus services.

@netblue30 the issue isn't to prevent access to DBus, but to allow access to DBus without entirely compromising the sandbox.

One hypothetical possibility would probably be to have a proxy between the jailed process and the real DBus daemon that controls access. Of course this would likely be a lot of effort to implement, but as of now the isolation for any process that requires DBus is sufficient only to prevent casual attacks.

<!-- gh-comment-id:248074681 --> @lheckemann commented on GitHub (Sep 19, 2016): @chiraag-nataraj it's also possible to prevent access to DBus using `--net=inet,inet6` which still allows internet access. What's necessary for a good sandboxing solution though is being able to control DBus access in a more fine-grained manner, because some applications require access to DBus services. @netblue30 the issue isn't to prevent access to DBus, but to allow access to DBus without entirely compromising the sandbox. One hypothetical possibility would probably be to have a proxy between the jailed process and the real DBus daemon that controls access. Of course this would likely be a lot of effort to implement, but as of now the isolation for any process that requires DBus is sufficient only to prevent casual attacks.
Author
Owner

@chiraag-nataraj commented on GitHub (Sep 19, 2016):

@lheckemann, I think the easier option is to blacklist service files in /usr/share/dbus-1/.

<!-- gh-comment-id:248078659 --> @chiraag-nataraj commented on GitHub (Sep 19, 2016): @lheckemann, I think the easier option is to blacklist service files in `/usr/share/dbus-1/`.
Author
Owner

@netblue30 commented on GitHub (Sep 19, 2016):

/usr/share/dbus-1/ - let me check out!

@lheckemann, the biggest problem DBus has is browsers and other networking programs don't use it. Usually programs that have also been ported to Windows behave well in the absence of DBus.

<!-- gh-comment-id:248111492 --> @netblue30 commented on GitHub (Sep 19, 2016): /usr/share/dbus-1/ - let me check out! @lheckemann, the biggest problem DBus has is browsers and other networking programs don't use it. Usually programs that have also been ported to Windows behave well in the absence of DBus.
Author
Owner

@lheckemann commented on GitHub (Sep 19, 2016):

@chiraag-nataraj as far as I understand, that will only prevent automatic starting of the server and the jail can still be escaped if the user has a GNOME Terminal open.

@netblue30 How is that a problem that DBus has?

<!-- gh-comment-id:248113458 --> @lheckemann commented on GitHub (Sep 19, 2016): @chiraag-nataraj as far as I understand, that will only prevent automatic starting of the server and the jail can still be escaped if the user has a GNOME Terminal open. @netblue30 How is that a problem that DBus has?
Author
Owner

@netblue30 commented on GitHub (Sep 19, 2016):

There are only a few applications relying on DBus, for example multilingual keyboard support. But if you don't need them you can just shut it down inside the sandbox. I don't know how a proxy would work, you still have to hide the abstract socket, otherwise the bad guy will go directly to the abstract socket bypassing the proxy.

The only valid method I know for filtering the traffic over DBus is using AppArmor, but this is deep inside the kernel. We don't have anything equivalent in user space.

<!-- gh-comment-id:248124581 --> @netblue30 commented on GitHub (Sep 19, 2016): There are only a few applications relying on DBus, for example multilingual keyboard support. But if you don't need them you can just shut it down inside the sandbox. I don't know how a proxy would work, you still have to hide the abstract socket, otherwise the bad guy will go directly to the abstract socket bypassing the proxy. The only valid method I know for filtering the traffic over DBus is using AppArmor, but this is deep inside the kernel. We don't have anything equivalent in user space.
Author
Owner

@lheckemann commented on GitHub (Sep 19, 2016):

Should the proxy and hiding the abstract socket not be possible through IPC namespacing?

<!-- gh-comment-id:248146635 --> @lheckemann commented on GitHub (Sep 19, 2016): Should the proxy and hiding the abstract socket not be possible through IPC namespacing?
Author
Owner

@chiraag-nataraj commented on GitHub (Sep 19, 2016):

As far as I can tell, multilingual keyboard (fctix) is literally the only thing that legitimately uses DBus on my laptop. Everything else seems to rely on other mechanisms. Is there any way to get dbus to rely on unix sockets so that it's easy to blacklist/block?

<!-- gh-comment-id:248147939 --> @chiraag-nataraj commented on GitHub (Sep 19, 2016): As far as I can tell, multilingual keyboard (fctix) is literally the only thing that legitimately uses DBus on my laptop. Everything else seems to rely on other mechanisms. Is there any way to get dbus to rely on unix sockets so that it's easy to blacklist/block?
Author
Owner

@lheckemann commented on GitHub (Sep 20, 2016):

The commands I included as an example also work in a jail with --net=none.

--protocol=inet,inet6 successfully blocks DBus, but also X... So I don't actually know of a way to test applications with X but without DBus right now.

As for legitimate use cases for DBus, a variety of applications such as mail clients (which as we know are a good idea to sandbox) may wish to use libnotify to send notifications, which uses DBus, for example.

<!-- gh-comment-id:248224398 --> @lheckemann commented on GitHub (Sep 20, 2016): The commands I included as an example also work in a jail with `--net=none`. `--protocol=inet,inet6` successfully blocks DBus, but also X... So I don't actually know of a way to test applications with X but without DBus right now. As for legitimate use cases for DBus, a variety of applications such as mail clients (which as we know are a good idea to sandbox) may wish to use libnotify to send notifications, which uses DBus, for example.
Author
Owner

@chiraag-nataraj commented on GitHub (Sep 20, 2016):

Here's the profile I use for my terminal emulator:

caps.drop all
seccomp
netfilter
private-dev
noroot
net none
protocol unix
whitelist /tmp/user/1000/
whitelist /tmp/.X11-unix/

noexec /tmp

With this profile, your example fails to work and DBus returns a Error connecting: Could not connect: Connection refused.

<!-- gh-comment-id:248351577 --> @chiraag-nataraj commented on GitHub (Sep 20, 2016): Here's the profile I use for my terminal emulator: ``` caps.drop all seccomp netfilter private-dev noroot net none protocol unix whitelist /tmp/user/1000/ whitelist /tmp/.X11-unix/ noexec /tmp ``` With this profile, your example fails to work and DBus returns a `Error connecting: Could not connect: Connection refused`.
Author
Owner

@netblue30 commented on GitHub (Sep 21, 2016):

As for legitimate use cases for DBus, a variety of applications such as mail clients

Yes, this is a legitimate use of dbus.

Should the proxy and hiding the abstract socket not be possible through IPC namespacing?

No, unix sockets are in the network subsystem not in IPC subsystem.

Is there any way to get dbus to rely on unix sockets so that it's easy to blacklist/block?

Probably they have something similar to x11, where they say what type of sockets to use.

<!-- gh-comment-id:248586959 --> @netblue30 commented on GitHub (Sep 21, 2016): > As for legitimate use cases for DBus, a variety of applications such as mail clients Yes, this is a legitimate use of dbus. > Should the proxy and hiding the abstract socket not be possible through IPC namespacing? No, unix sockets are in the network subsystem not in IPC subsystem. > Is there any way to get dbus to rely on unix sockets so that it's easy to blacklist/block? Probably they have something similar to x11, where they say what type of sockets to use.
Author
Owner

@chiraag-nataraj commented on GitHub (Sep 21, 2016):

Probably they have something similar to x11, where they say what type of sockets to use.

Indeed, I found it. Look for the <listen> tag in the dbus configuration file and change the type to path rather than tmpdir. And now you can easily blacklist programs from using dbus! Keep in mind that some programs (like e.g. fcitx) have their own dbus configuration files which you must also edit in this fashion.

<!-- gh-comment-id:248717216 --> @chiraag-nataraj commented on GitHub (Sep 21, 2016): > Probably they have something similar to x11, where they say what type of sockets to use. Indeed, I found it. Look for the `<listen>` tag in the dbus configuration file and change the type to `path` rather than `tmpdir`. And now you can easily blacklist programs from using dbus! Keep in mind that some programs (like e.g. fcitx) have their _own_ dbus configuration files which you must _also_ edit in this fashion.
Author
Owner

@lheckemann commented on GitHub (Sep 25, 2016):

(thanks thiago on #dbus on irc.freenode.net!)

21:35 < sphalerite> Is there a way to restrict the messages that an application may send through D-Bus? It would be nice to have the ability to e.g. send notifications from a sandboxed program without letting the program execute arbitrary commands outside its sandbox (using GNOME Terminal for instance). A potential solution for this would be having a proxy program that will connect to the real bus in the sandboxed program's stead and filter out unauthorised messages, but that seems like unnecessary extra effort in case D-Bus should already have support for some sort of access control.
21:37 < thiago> sphalerite: what bus?
21:37 < thiago> session?
21:37 < thiago> D-Bus has access control on the system bus
21:37 < thiago> not on the session bus
21:37 < sphalerite> yeah, session bus
21:38 < thiago> it makes no sense since all applications are running with the same UID, so any application can impersonate another
21:38 < thiago> or ptrace an existing application and make that one run some commands
21:38 < sphalerite> not with the use of PID namespaces etc :)
21:38 < thiago> which aren't applied
21:38 < thiago> everything runs under in the same namespace
21:39 < sphalerite> I'm asking because of an issue with firejail, which does set up new namespaces and such
21:40 < sphalerite> but is trivial to break out of if the application inside has access to the session bus and one of several terminal emulators is installed
21:41 < thiago> then that application (firejail) needs to do something
21:41 < thiago> D-Bus isn't designed for that
21:41 < thiago> the session bus assumes that all connecting processes have the same privileges
21:41 < sphalerite> so something like the proxy that I described earlier I guess
21:41 < thiago> yes

Key part being "the session bus assumes that all connecting processes have the same privileges", so sandboxed applications really shouldn't have unfiltered access to the session bus.

This is also relevant to #801

<!-- gh-comment-id:249442236 --> @lheckemann commented on GitHub (Sep 25, 2016): (thanks thiago on #dbus on irc.freenode.net!) ``` 21:35 < sphalerite> Is there a way to restrict the messages that an application may send through D-Bus? It would be nice to have the ability to e.g. send notifications from a sandboxed program without letting the program execute arbitrary commands outside its sandbox (using GNOME Terminal for instance). A potential solution for this would be having a proxy program that will connect to the real bus in the sandboxed program's stead and filter out unauthorised messages, but that seems like unnecessary extra effort in case D-Bus should already have support for some sort of access control. 21:37 < thiago> sphalerite: what bus? 21:37 < thiago> session? 21:37 < thiago> D-Bus has access control on the system bus 21:37 < thiago> not on the session bus 21:37 < sphalerite> yeah, session bus 21:38 < thiago> it makes no sense since all applications are running with the same UID, so any application can impersonate another 21:38 < thiago> or ptrace an existing application and make that one run some commands 21:38 < sphalerite> not with the use of PID namespaces etc :) 21:38 < thiago> which aren't applied 21:38 < thiago> everything runs under in the same namespace 21:39 < sphalerite> I'm asking because of an issue with firejail, which does set up new namespaces and such 21:40 < sphalerite> but is trivial to break out of if the application inside has access to the session bus and one of several terminal emulators is installed 21:41 < thiago> then that application (firejail) needs to do something 21:41 < thiago> D-Bus isn't designed for that 21:41 < thiago> the session bus assumes that all connecting processes have the same privileges 21:41 < sphalerite> so something like the proxy that I described earlier I guess 21:41 < thiago> yes ``` Key part being "the session bus assumes that all connecting processes have the same privileges", so sandboxed applications really shouldn't have unfiltered access to the session bus. This is also relevant to #801
Author
Owner

@liloman commented on GitHub (Nov 16, 2016):

Quirky as hell all this issue.

I had noticed that in Fedora 22 I couldn't launch a free lxterminal for vimperator cause firejail. Now in Fedora 23 and 24 if you have any lxterminal already opened and execute on vimperator:
:!lxterminal

It will be a escaped "trough" DBus ...

It's 2016 and they don't care about sessions/security yet? I'm kind of amaze.

<!-- gh-comment-id:261025084 --> @liloman commented on GitHub (Nov 16, 2016): Quirky as hell all this issue. I had noticed that in Fedora 22 I couldn't launch a free lxterminal for vimperator cause firejail. Now in Fedora 23 and 24 if you have any lxterminal already opened and execute on vimperator: :!lxterminal It will be a escaped "trough" DBus ... It's 2016 and they don't care about sessions/security yet? I'm kind of amaze.
Author
Owner

@lheckemann commented on GitHub (Nov 16, 2016):

It's 2016 and they don't care about sessions/security yet? I'm kind of amaze.

Who are "they"?

The issue is that the design of the interfaces to services that many applications will need to use (notifications, accessibility functions like advanced input methods, and others, even more basic stuff like integration with GNOME/Unity for the application menu) is based on the assumption that all applications having access to them have the same privileges. This is entirely opposite to the principle that firejail aims to implement: giving applications only the privileges that they need and none more.

It's a design flaw in how applications interact with their environment, a design flaw that is still pervasive across most desktop environments (including on OSX and Windows). Newer platforms like Android were designed with privilege minimisation in mind (to some degree... Some of the more advanced functionality like lazy privilege granting was shoehorned in a bit... but regardless it's far better than what we've got on desktops) and allow applications to declare exactly which permissions they need. This means not only that they're isolated well, but that the user can be informed of what the application wants to do and in more recent versions can choose to deny it some of the requested permissions. This also avoids the hacky "profiles" solution we have in firejail.

Basically, firejail is a hack to improve a broken system and hacks will never be better than a system that isn't broken in the first place.

</rant>

<!-- gh-comment-id:261053881 --> @lheckemann commented on GitHub (Nov 16, 2016): > It's 2016 and they don't care about sessions/security yet? I'm kind of amaze. Who are "they"? The issue is that the design of the interfaces to services that many applications will need to use (notifications, accessibility functions like advanced input methods, and others, even more basic stuff like integration with GNOME/Unity for the application menu) is based on the assumption that all applications having access to them have the same privileges. This is entirely opposite to the principle that firejail aims to implement: giving applications only the privileges that they need and none more. It's a design flaw in how applications interact with their environment, a design flaw that is still pervasive across most desktop environments (including on OSX and Windows). Newer platforms like Android were designed with privilege minimisation in mind (to some degree... Some of the more advanced functionality like lazy privilege granting was shoehorned in a bit... but regardless it's far better than what we've got on desktops) and allow applications to declare exactly which permissions they need. This means not only that they're isolated well, but that the user can be informed of what the application wants to do and in more recent versions can choose to deny it some of the requested permissions. This also avoids the hacky "profiles" solution we have in firejail. Basically, firejail is a hack to improve a broken system and hacks will never be better than a system that isn't broken in the first place. `</rant>`
Author
Owner

@liloman commented on GitHub (Nov 17, 2016):

I suppose I just can wait for someone to fix it. :)

We need a Lennart for a dbus-like project.

<!-- gh-comment-id:261118818 --> @liloman commented on GitHub (Nov 17, 2016): I suppose I just can wait for someone to fix it. :) We need a Lennart for a dbus-like project.
Author
Owner

@liloman commented on GitHub (Nov 17, 2016):

It seems just started...

https://lwn.net/Articles/706025/
https://www.linuxplumbersconf.org/2016/ocw/proposals/3609

He's going to leave out desktop stuff for now but he's coming up against the D-Bus issues.

<!-- gh-comment-id:261309403 --> @liloman commented on GitHub (Nov 17, 2016): It seems just started... https://lwn.net/Articles/706025/ https://www.linuxplumbersconf.org/2016/ocw/proposals/3609 He's going to leave out desktop stuff for now but he's coming up against the D-Bus issues.
Author
Owner

@Fred-Barclay commented on GitHub (Jul 22, 2018):

Since we have nodbus now to block dbus access, I'll close this.

<!-- gh-comment-id:406872880 --> @Fred-Barclay commented on GitHub (Jul 22, 2018): Since we have `nodbus` now to block dbus access, I'll close this.
Author
Owner

@ned64 commented on GitHub (Feb 22, 2020):

It's 2020 and more and more applications use dbus. Also, many fail to start with the nodbus option. Additionally programs like Libre Office and Evince fail to start a second instance of themselves without dbus, exiting (evince) or blocking until the first instance is exited (loffice).

So, is there a way to filter dbus messages instead of having full or no access to dbus?

Or, can we start a new instance? I have written a script for that but it would be nice as part of firejail.

<!-- gh-comment-id:589940735 --> @ned64 commented on GitHub (Feb 22, 2020): It's 2020 and more and more applications use `dbus`. Also, many fail to start with the `nodbus` option. Additionally programs like Libre Office and Evince fail to start a second instance of themselves without dbus, exiting (evince) or blocking until the first instance is exited (loffice). So, is there a way to filter dbus messages instead of having full or no access to dbus? Or, can we start a new instance? I have written a script for that but it would be nice as part of firejail.
Author
Owner

@rusty-snake commented on GitHub (Feb 22, 2020):

#3184

<!-- gh-comment-id:589943731 --> @rusty-snake commented on GitHub (Feb 22, 2020): #3184
Author
Owner

@ned64 commented on GitHub (Feb 22, 2020):

Thanks for the fast response. :) Following your link.

<!-- gh-comment-id:589951002 --> @ned64 commented on GitHub (Feb 22, 2020): Thanks for the fast response. :) Following your link.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/firejail#539
No description provided.