Saturday, April 23, 2011

The Linux Security Circus: On GUI isolation

There certainly is one thing that most Linux users don't realize about their Linux systems... this is the lack of GUI-level isolation, and how it essentially nullifies all the desktop security. I wrote about it a few times, I spoke about it a few times, yet I still come across people who don't realize it all the time.

So, let me stress this one more time: if you have two GUI applications, e.g. an OpenOffice Word Processor, and a stupid Tetris game, both of which granted access to your screen (your X server), then there is no isolation between those two apps. Even if they run as different user accounts! Even if they are somehow sandboxed by SELinux or whatever! None, zero, null, nil!

The X server architecture, designed long time ago by some happy hippies who just thought all the people apps are good and non-malicious, simply allows any GUI application to control any other one. No bugs, no exploits, no tricks, are required. This is all by design. One application can sniff or inject keystrokes to another one, can take snapshots of the screen occupied by windows belonging to another one, etc.

If you don't believe me, I suggest you do a simple experiment. Open a terminal window, as normal user, and run xinput list, which is a standard diagnostic program for Xorg (on Fedora you will likely need to install it first: yum install xorg-x11-apps):

$ xinput list

It will show you all the pointer and keyboard devices that your Xorg knows about. Note the ID of the device listed as “AT keyboard” and then run (as normal user!):

$ xinput test id

It should now start displaying the scancodes for all the keys you press on the keyboard. If it doesn't, it means you used a wrong device ID.

Now, for the best, start another terminal window, and switch to root (e.g. using su, or sudo). Notice how the xinput running as user is able to sniff all your keystrokes, including root password (for su), and then all the keystrokes you enter in your root session. Start some GUI app as root, or as different user, again notice how your xinput can sniff all the keystrokes you enter to this other app!

Yes, I can understand what is happening in your mind and heart right now... Don't worry, others have also passed through it. Feel free to hate me, throw out insults at me, etc. I don't mind, really (I just won't moderate them). When you calm down, continue reading.

In Qubes the above problem doesn't exist, because each domain (each AppVM) has it own local, isolated, dummy X server. The main X server, that runs in Dom0 and that handles the real display is never exposed to any of the AppVMs directly (AppVMs cannot connect to it via the X protocol). For details see this technical overview.

You can repeat the same experiment in Qubes. You just need to use the ID of the “qubesdev” device, as shown by xinput list (should be 7). Run the xinput in one of your domains, e.g. in the “red” one. Because we actually use the same device for both mouse and keystrokes, you should now see both the key scancodes, as well as all the mouse events. Notice how your xinput is able to sniff all the events that are destined for other apps belonging to the same domain where you run xinput, and how it is unable to sniff anything targeted to other domains, or Dom0.

BTW, Windows is the only one mainstream OS I'm aware of, that actually attempts to implement some form of GUI-level isolation, starting from Windows Vista. See e.g. this ancient article I wrote in the days when I used Vista at my primary laptop. Of course, it's still easy to bypass this isolation, because of the huge interface that is exposed to each GUI client (that also includes GPU API). Nevertheless, they at least attempt to prevent this at the architecture level.


Anonymous said...

Try this with SELinux sandbox... "sandbox -X xterm" (on F14 or RHEL6... install policycoreutils-sandbox if needed). It does not see keys destined for another window. This is because sandbox -X also uses its own X server (Xephyr).

How does this differ from Qubes?

Joanna Rutkowska said...

The primary problem with SELinux sandbox is that it still relies on the big, buggy, bloated Linux kernel to enforce security. In Qubes we rely on Xen to enforce domain isolation (a few orders of magnitude less code, I would say 10^3 less, even including the few daemons/backends we also have in Dom0 and which are reachable from VMs).

Second, SELinux sandbox X server isolation doesn't really eliminate all the attacks coming over the bloated X protocol. As a result it is relatively easy to attack. See, e.g. this paper from Rafal for example of an escape:

In Qubes the only point of contact to the real server is our GUI daemon -- see the reference quoted in the blog post for details on the protocol we use. Compare this now to the X protocol. It's orders of magnitude simpler!

SELinux sandbox creates an X server instance (Xephyr) per each sandboxed app, which sounds to me like a huge resource waste. In Qubes we have one X server instance per *domain*.

SELinux sandbox doesn't offer any desktop integration, such as secure copy-and-paste operation. We provide secure inter-domain clipboard on Qubes -- again see the above-quoted reference for technical details.

Finally, SELinux sandbox requires the user to setup complex SELinux polices to achieve also filesystem-level and network-level isolation. In Qubes all the domains are automatically isolated on all those levels.

rinaku said...

I would be interested to know what you think about capability-based security (as in the Capsicum project), and how it compares to what you do in Qubes.

From what I understand (but I know very little about security), capabilities allow the same level of security as Qubes, or even better, but they need the applications to be modified, which seems unrealistic. Is that correct ?

Anyway, I'm not good enough to beta test, but I can't wait for a stable release, to see what it is like to use a system like Qubes.

Joanna Rutkowska said...

@rinaku: Capsicum currently doesn't support GUI-level isolation, but I think they're planning to add it at some point in time. When this happens we would seriously consider using it inside our domains, to bring some isolation into each domain as well (currently there is no isolation between apps running in the same domain, specifically for reasons given in the blog article above).

Capability-based systems, as you pointed out, require application modifications. This also means they cannot protect against intentionally malicious apps. Thus I see them as complementing Qubes, but never replacing it. Also, note that capsicum works only on app-level, but cannot protect against e.g. network subsystem compromises (cannot isolate the networking subsystem or other drivers). In Qubes we can easily do that e.g. via NetVM. Another reason to think about it as something to complement Qubes (and to run it inside a domain).

Anonymous said...

Welcome to 1987.

Anonymous said...

That is something I didn't know about... but very interesting. Good Post.

Anonymous said...

Why can't we just fix/modify the X-Server to make GUI level isolation easier?

Anonymous said...

How old/young has somebody to be to write "....designed long time ago by some happy hippies who just thought all the people apps are good and non-malicious..." ?

The problem is the other way around. These guys created some awesome software tailored to their problems and means. Using it 20 years later in a different environment/world is the fault, not their initial design.

Blame the actual generation, respect and praise the founder.

Ashish said...

Yes the same hippies who built X11 before you were born....

Please read the man page on Xsecurity

While you are at it also read up on xhost, xauth.
Linux is not representative of how X11 really is supposed to work.

josericardo said...

Very interesting indeed. I didn't know about this threat and doesn't seem to be fixable. Nevertheless I wanted to know if this is the case for wayland. It would be interesting to run your experiment in it and post the findings on the wayland-devel mailing list.

Unknown said...

So, how does Qubes implement global keyboard shortcuts or applications like VNC?

Joanna Rutkowska said...

@Ashish: the security mechanisms you mention have been designed for a totally different security model than the "desktop GUI security" that is prevalent today.

The point is, as correctly made by some other commenter, that X have been designed long, long, time ago, in different realities, for solving different problems, but the Linux community has blindly adopted it to current conditions, failing to see that it really doesn't fit today. Why do you think the title of this post is "*Linux* Security Circus" instead of "X Security Circus"? (Yes, I know, the problem also affects other OSes, such as e.g. *BSD, etc).

Joanna Rutkowska said...

@fliebel: In Qubes all the keystrokes are first processed byt he *trusted* window manger running in Dom0 (the trusted partition). Then, they might be consumed by Qubes (e.g. if this is a global clipboard management sequence, or perhaps the "Expose" sequence), or passed down to the *active* domain's local X server.

VNC is just a regular app running in one of the domains. No special VNC for Qubes is needed.

phocean said...

Instructive article.
But what about Wayland?
Wayland is claimed to replace X soon. Major distros are already working on its integration.
Are the authors aware of it or does it have the same design flaws?

Joanna Rutkowska said...

@phocean: good question about Wayland, why don't you check for yourself? ;)

phocean said...

So I will when I have some free time.
But as it is your research topic, I expected you had already done that or even contacted the developers to inform them.
As it is still under heavy development, I guess it is a good timing to implement good stuff and for expert like you to advise them.

Joanna Rutkowska said...

@phocean: Don't kid me, kid! What I did here was not a "research" (you might want to check some real research we did at ITL on our website). That was just a Saturday morning blog post with an aim to save some lost souls, like yours... And I really don't have time to go and test all the software in the development that is out there. I do have real job, that among other things includes doing *real* research...

Wladimir said...

*they at least attempt to prevent this at the architecture level.*

I'm not sure that trying and failing is better than not trying, in the case of security :)

That said, I agree application-level isolation on desktop OS is a problem that deserves solving. It is very very hard, though.

As X is going the way of the dodo, have you examined the case with Unity?

Tom said...

There is an extension called XACE that when integrated with selinux fixes these problems. I think it was developed by Eamon Walsh for the NSA.

I don't know how well that works, but it is clear that this is a problem for other people, too.

Joanna Rutkowska said...

@Tom: The XACE project seems to be dead for at least 3 years now...

Anonymous said...

I ran gksudo and its input was not collected by xinput test. What kind of magic is it doing?

Joanna Rutkowska said...

About gksudo: perhaps it somehow owns the input only to itself for the period of displying its prompt window? I bet you cannot use other apps until the window is present?

But that's probably irrelevant, because I bet that once you switch to a different user and start some apps as this new user, then xinput will be able to sniff all those keystrokes without any problem (and you could also easily write a program that could be injecting keystrokes to those apps).

KimTjik said...

I don't ask you to waste time on an explanation; you could as well just direct me to a source of information. What I wonder is: what's the real danger of the current sloppy model?

My question is based on the fact that all network connected systems can be remotely compromised, with or without a window system. What priority does this in theory sane improvement get in relation to established precautions?

I understand it's difficult to objectively answer that, while you at the same time invest time in a project addressing described issue.

Joanna Rutkowska said...

@KimTijk: your assumption about easiness of exploiting any system that is connected to the network, regardless of what apps are running there, is simply flawed.

Anonymous said...

Nice post and you're probably right, but your attitude needs some work kid.

Maybe it's a researcher thing.

Joanna Rutkowska said...


Joanna Rutkowska said...

Correction: I was wrong about Xace being dead -- it has been apparently merged into the mainstream Xorg. Its just that... apparently nobody uses it, because it just not suited to solve the problems we talk about here. See e.g. this presentation from Dan Walsh (SELinux maintainer), slide #12:

...which shows how he decided to use a nested X server instead of Xace to implement SELinux sandbox (see comments above), because... "Xace doesn't work" ;)