New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security issue with dom0 confirmation dialogs stealing focus with KDE default settings #1166

Open
qubesuser opened this Issue Sep 4, 2015 · 16 comments

Comments

Projects
None yet
7 participants
@qubesuser

System

Tested on 3.0-rc2 live USB image and normal install.

Root issue

While experimenting with the GUI daemon, I noticed that it seems that in the default configuration with KWin, dom0 confirmation dialogs are spawned with input focus and the "Yes" button is focused.

This means that just pressing Space after the dialog pops up confirms the action.

Attacks

An AppVM that can predict when the user is going to press space (for example by looking at the user typing "cat" or "cd" or "git" and so on in a terminal of that VM or noticing that the user is typing in a lot of text quickly or inducing the user to play a computer game that requires repeatedly pressing space) can trigger a Qubes RPC precisely at that moment and with some luck have the space keypress confirm the dialog box before the user notices.

For instance, it's possible to run the OpenInVM RPC and send a file that exploits a viewer or that perhaps automatically runs some code if any viewer allows that.

There is also a mouse-based attack route because the dialog seems to be deterministically placed on the center of the screen (with the default KWin configuration), and so the AppVM can put a button there, convince the user to click it and then cause the dom0 confirmation dialog to spawn as the user is about to click the AppVM button (and if necessary close the AppVM window).

This is also a problem with AppVM windows stealing input, although in this case it's much harder to predict when to spawn the window since you need to do so while the user is about to type a secret in another window.

How to make your system not vulnerable

Enabling "Focus stealing prevention" does NOT fix the issue! This is because the AppVM can just close its own focused window after the confirmation dialog is shown and then the idiotic window manager will give focus to the confirmation dialog (rather than to nothing).

Type the following in a dom0 terminal:

sudo cp -a /etc/qubes-rpc/policy /root/qubes-rpc-policy-backup
sudo sed -i -r -e 's/\bask\s*$/deny/g' /etc/qubes-rpc/policy/*

This disables all dom0 confirmation dialogs (is there a better way?)

@marmarek

This comment has been minimized.

Show comment
Hide comment
@marmarek

marmarek Sep 4, 2015

Member

Generally RPC should be written with the assumption that the input in not trusted, potentially malicious. But indeed qubes.OpenInVM is a risky case here.
Lets review currently implemented services:

  • qubes.Backup - only allowed from dom0
  • qubes.DetachPciDevice - only allowed from dom0
  • qubes.Filecopy - stores files in dedicated directory, do not parse them
  • qubes.GetAppmenus - only allowed from dom0
  • qubes.GetImageRGBA - only allowed from dom0
  • qubes.Gpg - potentially dangerous - data gets parsed by gpg
  • qubes.GpgImportKey - potentially dangerous - data gets parsed by gpg
  • qubes.OpenInVM - dangerous - data gets parsed by almost any application
  • qubes.PdfConvert - only allowed to spawn new DispVM
  • qubes.Restore - only allowed from dom0
  • qubes.SelectDirectory - only allowed from dom0
  • qubes.SelectFile - only allowed from dom0
  • qubes.SetDateTime - only allowed from dom0
  • qubes.SetMonitorLayout - only allowed from dom0
  • qubes.SuspendPost - only allowed from dom0
  • qubes.SuspendPre - only allowed from dom0
  • qubes.SyncNtpClock - only allowed from dom0
  • qubes.VMShell - only allowed to spawn new DispVM
  • qubes.WaitForSession - only allowed from dom0

So we have 3 that do not fully adhere to the assumption about untrusted input. I would classify gpg as low risk. Which leaves qubes.OpenInVM. I think we can change default policy to the same as for qubes.VMShell - allow to spawn new DispVM and deny anything else. So the solution you've proposed here.

Member

marmarek commented Sep 4, 2015

Generally RPC should be written with the assumption that the input in not trusted, potentially malicious. But indeed qubes.OpenInVM is a risky case here.
Lets review currently implemented services:

  • qubes.Backup - only allowed from dom0
  • qubes.DetachPciDevice - only allowed from dom0
  • qubes.Filecopy - stores files in dedicated directory, do not parse them
  • qubes.GetAppmenus - only allowed from dom0
  • qubes.GetImageRGBA - only allowed from dom0
  • qubes.Gpg - potentially dangerous - data gets parsed by gpg
  • qubes.GpgImportKey - potentially dangerous - data gets parsed by gpg
  • qubes.OpenInVM - dangerous - data gets parsed by almost any application
  • qubes.PdfConvert - only allowed to spawn new DispVM
  • qubes.Restore - only allowed from dom0
  • qubes.SelectDirectory - only allowed from dom0
  • qubes.SelectFile - only allowed from dom0
  • qubes.SetDateTime - only allowed from dom0
  • qubes.SetMonitorLayout - only allowed from dom0
  • qubes.SuspendPost - only allowed from dom0
  • qubes.SuspendPre - only allowed from dom0
  • qubes.SyncNtpClock - only allowed from dom0
  • qubes.VMShell - only allowed to spawn new DispVM
  • qubes.WaitForSession - only allowed from dom0

So we have 3 that do not fully adhere to the assumption about untrusted input. I would classify gpg as low risk. Which leaves qubes.OpenInVM. I think we can change default policy to the same as for qubes.VMShell - allow to spawn new DispVM and deny anything else. So the solution you've proposed here.

@marmarek

This comment has been minimized.

Show comment
Hide comment
@marmarek

marmarek Sep 4, 2015

Member

Regarding confirmation dialog itself, we could introduce feature similar to Firefox download/open dialog - the window must have focus for at least X time to have buttons enabled (where X is for example 500ms or 1s). But this is significant degradation of user experience...

Member

marmarek commented Sep 4, 2015

Regarding confirmation dialog itself, we could introduce feature similar to Firefox download/open dialog - the window must have focus for at least X time to have buttons enabled (where X is for example 500ms or 1s). But this is significant degradation of user experience...

@qubesuser

This comment has been minimized.

Show comment
Hide comment
@qubesuser

qubesuser Sep 4, 2015

In general, it seems the window manager should be fixed so that it's not possible to cause accidental input or steal input both to/from any window.

These things should be sufficient and are probably all necessary to be safe even against pathological user behavior:

  1. Do not give input focus to any window unless the user clicked on it, explicitly switched to the window via alt-tab/taskbar/expose or if the input focus was already on a window of the same VM/application.
  2. Do not place new windows under the mouse pointer and keep some distance, unless they are from the same application/VM that owns the window currently under the mouse pointer
  3. For dom0 dialogs, put them "always on top" so that no VM can obscure them and they don't get ignored for long periods of time
  4. For dom0 dialogs, disable all input for the first ~500ms-1s as you mention.
  5. For dom0 dialogs, make the "no" button the default rather than the yes button

It seems that 1-2 requires patching Kwin, 3 can be done with kwin configuration or a kdialog patch, 4-5 require patching kdialog. Xfce and other DEs might perhaps require similar patching.

That still leaves less severe problems with AppVM windows though: it's possible to cause accidental input by suddenly destroying or moving your own AppVM window and causing the user to click on the window below it, which is what the "always on top" for dom0 dialogs would prevent, and it's possible for an AppVM to steal input by moving or resizing its own window to cover the mouse pointer and receiving a click and a few keystrokes before the user notices.

There are much harder to exploit in a way that is useful for attackers since they usually don't have the information required and mitigating them seems to require either forcibly moving windows near the cursor or using a slow animation for the transitions and ignoring input while it's running.

In general, it seems the window manager should be fixed so that it's not possible to cause accidental input or steal input both to/from any window.

These things should be sufficient and are probably all necessary to be safe even against pathological user behavior:

  1. Do not give input focus to any window unless the user clicked on it, explicitly switched to the window via alt-tab/taskbar/expose or if the input focus was already on a window of the same VM/application.
  2. Do not place new windows under the mouse pointer and keep some distance, unless they are from the same application/VM that owns the window currently under the mouse pointer
  3. For dom0 dialogs, put them "always on top" so that no VM can obscure them and they don't get ignored for long periods of time
  4. For dom0 dialogs, disable all input for the first ~500ms-1s as you mention.
  5. For dom0 dialogs, make the "no" button the default rather than the yes button

It seems that 1-2 requires patching Kwin, 3 can be done with kwin configuration or a kdialog patch, 4-5 require patching kdialog. Xfce and other DEs might perhaps require similar patching.

That still leaves less severe problems with AppVM windows though: it's possible to cause accidental input by suddenly destroying or moving your own AppVM window and causing the user to click on the window below it, which is what the "always on top" for dom0 dialogs would prevent, and it's possible for an AppVM to steal input by moving or resizing its own window to cover the mouse pointer and receiving a click and a few keystrokes before the user notices.

There are much harder to exploit in a way that is useful for attackers since they usually don't have the information required and mitigating them seems to require either forcibly moving windows near the cursor or using a slow animation for the transitions and ignoring input while it's running.

@marmarek

This comment has been minimized.

Show comment
Hide comment
@marmarek

marmarek Sep 5, 2015

Member

@rootkovska what do you think we should do right now about this issue? Change qubes.OpenInVM default policy or something more?

Member

marmarek commented Sep 5, 2015

@rootkovska what do you think we should do right now about this issue? Change qubes.OpenInVM default policy or something more?

@rootkovska

This comment has been minimized.

Show comment
Hide comment
@rootkovska

rootkovska Sep 6, 2015

Member

I definitely we should not be investing any work into our own kwin hardening now (i.e. 3.0 and 3.1). There are many reasons why we would like to move away from KDE/kwin anyway.

I don't think we should be worrying about qubes.Gpg* services, as if GPG had flaws exploitable that way, I think that would be disastrous anyway (i.e. for the gpg-protected communication).

I think changing the default policy for qubes.OpenInVM is a good approach here. Plus, we should make it more specific somewhere in the docs (qrexec service writers guide) that really the services should be written with assumption that the user can be either absent-minded (and thus click ok), or UI-wise tricked into clicking it. Generally in the near future (3.1+) we would like to get rid of all (most) real-time security-related prompts, because most users are generally incapable of making security decisions real time. So, most qrexec services should ultimately never spawn prompts in response to specific user actions, just automatically allow or deny actions (plus log them). All should be (pre-)configured on policy-level. Our upcoming pre-configuration/management infrastructure in 3.1 is particularly well suited to achieve this, I think. This is yet another reason, BTW, why kwin hardening is not worth doing -- however we hardened against focus stealing tricks, the user would always be happy to click "OK" just to Get The Work Done (TM).

Member

rootkovska commented Sep 6, 2015

I definitely we should not be investing any work into our own kwin hardening now (i.e. 3.0 and 3.1). There are many reasons why we would like to move away from KDE/kwin anyway.

I don't think we should be worrying about qubes.Gpg* services, as if GPG had flaws exploitable that way, I think that would be disastrous anyway (i.e. for the gpg-protected communication).

I think changing the default policy for qubes.OpenInVM is a good approach here. Plus, we should make it more specific somewhere in the docs (qrexec service writers guide) that really the services should be written with assumption that the user can be either absent-minded (and thus click ok), or UI-wise tricked into clicking it. Generally in the near future (3.1+) we would like to get rid of all (most) real-time security-related prompts, because most users are generally incapable of making security decisions real time. So, most qrexec services should ultimately never spawn prompts in response to specific user actions, just automatically allow or deny actions (plus log them). All should be (pre-)configured on policy-level. Our upcoming pre-configuration/management infrastructure in 3.1 is particularly well suited to achieve this, I think. This is yet another reason, BTW, why kwin hardening is not worth doing -- however we hardened against focus stealing tricks, the user would always be happy to click "OK" just to Get The Work Done (TM).

@qubesuser

This comment has been minimized.

Show comment
Hide comment
@qubesuser

qubesuser Sep 6, 2015

I think theoretically an exploited VM could use this to get a message signed or decrypted via qubes.Gpg; this is mitigated by the VM itself spawning a confirmation dialog, but that confirmation dialog suffers from the same issue, although getting two unintentional spacebar presses might be harder, and a desktop notification is spawned.

qubes.GetImageRGBA also seems to be an issue because it has "$appvm $appvm ask" policy and seems to allow to read an arbitrary file readable by ImageMagick or a delegate from the target VM filesystem, and compromise the VM if either ImageMagick or any of a scary list of delegate programs that are executed by it (run "convert -list delegate" for a list) is exploitable. Plus due to marmarek/qubes-core-agent-linux#26 it might be usable to delete files in the target VM. Does anything even request this from another AppVM?

I think theoretically an exploited VM could use this to get a message signed or decrypted via qubes.Gpg; this is mitigated by the VM itself spawning a confirmation dialog, but that confirmation dialog suffers from the same issue, although getting two unintentional spacebar presses might be harder, and a desktop notification is spawned.

qubes.GetImageRGBA also seems to be an issue because it has "$appvm $appvm ask" policy and seems to allow to read an arbitrary file readable by ImageMagick or a delegate from the target VM filesystem, and compromise the VM if either ImageMagick or any of a scary list of delegate programs that are executed by it (run "convert -list delegate" for a list) is exploitable. Plus due to marmarek/qubes-core-agent-linux#26 it might be usable to delete files in the target VM. Does anything even request this from another AppVM?

@qubesuser

This comment has been minimized.

Show comment
Hide comment
@qubesuser

qubesuser Sep 6, 2015

There's ClipboardPaste too, which is also set to ask because guid reuses the permission for its own code (I think it should instead use a permission with another name and no actual handlers instead). This is also pretty unrealistic but it seems that in theory it could exploit an application in a Windows HVM watching the clipboard (the Linux VMs don't have an handler because they use the GUI agent protocol instead)

There's ClipboardPaste too, which is also set to ask because guid reuses the permission for its own code (I think it should instead use a permission with another name and no actual handlers instead). This is also pretty unrealistic but it seems that in theory it could exploit an application in a Windows HVM watching the clipboard (the Linux VMs don't have an handler because they use the GUI agent protocol instead)

@marmarek

This comment has been minimized.

Show comment
Hide comment
@marmarek

marmarek Sep 6, 2015

Member

Indeed qubes.GetImageRGBA should not be allowed to run in any VM - it
should be "$anyvm $dispvm allow".
Regarding qubes.Gpg, as Joanna said, it should be configured to allow
(from selected VMs) and deny from others. No prompts.

Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

Member

marmarek commented Sep 6, 2015

Indeed qubes.GetImageRGBA should not be allowed to run in any VM - it
should be "$anyvm $dispvm allow".
Regarding qubes.Gpg, as Joanna said, it should be configured to allow
(from selected VMs) and deny from others. No prompts.

Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

@andrewdavidwong

This comment has been minimized.

Show comment
Hide comment
@andrewdavidwong

andrewdavidwong Sep 22, 2015

Member

I've only skimmed this thread, but I remember bringing up a similar concern on the ML a few years ago. I know you said

Enabling "Focus stealing prevention" does NOT fix the issue!

but you didn't specify which levels of focus stealing prevention you tried. There are actually five different levels ranging from "None" to "Extreme." I used to have a problem with accidentally confirming pop-up dialog boxes in dom0 by pressing the space bar, but after I set mine to "high" several years ago, I haven't had any problems.

From the KDE documentation:

Extreme
    All windows must be explicitly activated by the user.

This means that all windows (including those pesky dialog boxes) will start minimized and blinking on your task bar. You will have to click on them for them to be visible, which should make it virtually impossible to accidentally confirm such a prompt.

Member

andrewdavidwong commented Sep 22, 2015

I've only skimmed this thread, but I remember bringing up a similar concern on the ML a few years ago. I know you said

Enabling "Focus stealing prevention" does NOT fix the issue!

but you didn't specify which levels of focus stealing prevention you tried. There are actually five different levels ranging from "None" to "Extreme." I used to have a problem with accidentally confirming pop-up dialog boxes in dom0 by pressing the space bar, but after I set mine to "high" several years ago, I haven't had any problems.

From the KDE documentation:

Extreme
    All windows must be explicitly activated by the user.

This means that all windows (including those pesky dialog boxes) will start minimized and blinking on your task bar. You will have to click on them for them to be visible, which should make it virtually impossible to accidentally confirm such a prompt.

@andrewdavidwong

This comment has been minimized.

Show comment
Hide comment
@andrewdavidwong

andrewdavidwong Sep 22, 2015

Member

There's also a range of policies regarding focus and active windows ranging from "Click to Focus" to "Focus Strictly Under Mouse" including the ability to delay focus by a number of milliseconds. With this setting, it would be impossible for the window manager to shift focus to a dialog box unless your cursor had already been hovering over it for a set amount of time.

(All of these options are in System Settings --> Window Behavior --> Window Behavior.)

Member

andrewdavidwong commented Sep 22, 2015

There's also a range of policies regarding focus and active windows ranging from "Click to Focus" to "Focus Strictly Under Mouse" including the ability to delay focus by a number of milliseconds. With this setting, it would be impossible for the window manager to shift focus to a dialog box unless your cursor had already been hovering over it for a set amount of time.

(All of these options are in System Settings --> Window Behavior --> Window Behavior.)

@qubesuser

This comment has been minimized.

Show comment
Hide comment
@qubesuser

qubesuser Sep 23, 2015

The problem is that even if you set Extreme focus stealing prevention, the dialog will appear under the current window, but once the current window is closed Kwin will give focus to the dialog.

So an exploited VM just needs to trigger the dialog and close its own window and then the dialog will capture your spacebar presses that were intended for the window the VM suddenly closed.

Not sure about "focus strictly under mouse", it may prevent it but it changes the way the desktop behaves. Also, it seems like that the VM can just induce you to put the mouse where the dialog will be, which is currently fully predictable (e.g. by placing a GUI button you need to click there).

The problem is that even if you set Extreme focus stealing prevention, the dialog will appear under the current window, but once the current window is closed Kwin will give focus to the dialog.

So an exploited VM just needs to trigger the dialog and close its own window and then the dialog will capture your spacebar presses that were intended for the window the VM suddenly closed.

Not sure about "focus strictly under mouse", it may prevent it but it changes the way the desktop behaves. Also, it seems like that the VM can just induce you to put the mouse where the dialog will be, which is currently fully predictable (e.g. by placing a GUI button you need to click there).

@v6ak

This comment has been minimized.

Show comment
Hide comment
@v6ak

v6ak Nov 23, 2015

There are many reasons why we would like to move away from KDE/kwin anyway.

Although this is slightly offtopic, I can't find any more detailed info about this. Is it a plan or just a wish? Are there some details? I like Kwin…

however we hardened against focus stealing tricks, the user would always be happy to click "OK" just to Get The Work Done (TM).

Does this really apply for Qubes target users? I hope that some small UI redesign (making the dialog more skimmable) would further decrease such temptations.

v6ak commented Nov 23, 2015

There are many reasons why we would like to move away from KDE/kwin anyway.

Although this is slightly offtopic, I can't find any more detailed info about this. Is it a plan or just a wish? Are there some details? I like Kwin…

however we hardened against focus stealing tricks, the user would always be happy to click "OK" just to Get The Work Done (TM).

Does this really apply for Qubes target users? I hope that some small UI redesign (making the dialog more skimmable) would further decrease such temptations.

@marmarek

This comment has been minimized.

Show comment
Hide comment
@marmarek

marmarek Nov 23, 2015

Member

On Mon, Nov 23, 2015 at 11:51:57AM -0800, Vít Šesták wrote:

There are many reasons why we would like to move away from KDE/kwin anyway.

Although this is slightly offtopic, I can't find any more detailed info about this. Is it a plan or just a wish? Are there some details? I like Kwin…

Generally support for KDE 5 requires substantial amount of work -
rewrite decoration plugin mostly from scratch. Which means when we'll
implement GUI domain (based on some newer distro version), we'd need to
do that. Or switch to some other desktop environment (with similar
amount of work). @rootkovska likes recent GNOME versions for simplicity.

Anyway we haven't made the decision yet. Either about switching to GNOME
as default (most likely it will be the case), or dropping KDE support.

however we hardened against focus stealing tricks, the user would always be happy to click "OK" just to Get The Work Done (TM).

Does this really apply for Qubes target users? I hope that some small UI redesign (making the dialog more skimmable) would further decrease such temptations.

Generally in most cases it shouldn't be confirmation dialogs at all -
all should be configured in policies as either "allow" or "deny". But
currently we can't do this (in the default installation), because it
highly depends on user use case.

Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

Member

marmarek commented Nov 23, 2015

On Mon, Nov 23, 2015 at 11:51:57AM -0800, Vít Šesták wrote:

There are many reasons why we would like to move away from KDE/kwin anyway.

Although this is slightly offtopic, I can't find any more detailed info about this. Is it a plan or just a wish? Are there some details? I like Kwin…

Generally support for KDE 5 requires substantial amount of work -
rewrite decoration plugin mostly from scratch. Which means when we'll
implement GUI domain (based on some newer distro version), we'd need to
do that. Or switch to some other desktop environment (with similar
amount of work). @rootkovska likes recent GNOME versions for simplicity.

Anyway we haven't made the decision yet. Either about switching to GNOME
as default (most likely it will be the case), or dropping KDE support.

however we hardened against focus stealing tricks, the user would always be happy to click "OK" just to Get The Work Done (TM).

Does this really apply for Qubes target users? I hope that some small UI redesign (making the dialog more skimmable) would further decrease such temptations.

Generally in most cases it shouldn't be confirmation dialogs at all -
all should be configured in policies as either "allow" or "deny". But
currently we can't do this (in the default installation), because it
highly depends on user use case.

Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

@MarioGeckler

This comment has been minimized.

Show comment
Hide comment
@MarioGeckler

MarioGeckler Aug 23, 2016

Would it be enough, to change the default button for these dialogs to no? So when the user hits space, nothing happens.

Would it be enough, to change the default button for these dialogs to no? So when the user hits space, nothing happens.

@andrewdavidwong

This comment has been minimized.

Show comment
Hide comment
@andrewdavidwong

andrewdavidwong Aug 23, 2016

Member

As long as "no" is always the "safe" option, then that would be a sane default, IMO. However, it would still be better to ensure that the user retains control.

Member

andrewdavidwong commented Aug 23, 2016

As long as "no" is always the "safe" option, then that would be a sane default, IMO. However, it would still be better to ensure that the user retains control.

@rustybird

This comment has been minimized.

Show comment
Hide comment
@rustybird

rustybird Aug 24, 2016

@MarioGeckler:

Would it be enough, to change the default button for these dialogs to no? So when the user hits space, nothing happens.

The user might still hit [Y]es or Yes to [A]ll

@MarioGeckler:

Would it be enough, to change the default button for these dialogs to no? So when the user hits space, nothing happens.

The user might still hit [Y]es or Yes to [A]ll

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment