Keepassxc: Unlock database popup not in focus when opening from browser plugin

Created on 6 Sep 2020  路  39Comments  路  Source: keepassxreboot/keepassxc

Overview

When you unlock your database from the browser plugin, a popup appears to type in the master password, but the popup window is not in focus, at least not when opening from the plugin for the first time in a session. This behaviour is annoying because I directly want to start typing, rather than having to move the mouse to the window and clicking on it to get it in focus.
When I did this for the first time, I inadvertently started typing into the browser window.

Steps to Reproduce

  1. Click the browser plugin icon and then 'reopen database' or the icon appearing on password/username fields or press alt+shift+u (with locked database)

  2. A popup window appears to type in the master password, but it is not in focus.

Expected Behavior

When opening the database from the browser plugin, the appearing popup window should be in focus, so that one can directly start typing in the password.
Screenshot (35)

Actual Behavior

When opening the database from the plugin for the first time in a browser session, the window is not in focus.
Screenshot (34)

KeePassXC - Version 2.6.1
Revision: 9a35bba
KeePassXC Browser 1.7.0

Operating System: Windows 8.1
Browser: Firefox

bug Browser integration

Most helpful comment

While I agree that KeePassXC can't be expected to handle all cases where the window doesn't handle focus, I think it's a bit much to expect the user (especially less technical users) to recognise that the window isn't focused when it looks exactly the same. That being said, I recognise this isn't the most exciting item to be working on and we shouldn't expect anything reported to be fixed for free, so I decided to see what I could do to help.

Fair warning that I've never done any C++ before. I will also stress that this is not a solution, only investigating the cause. Based on earlier conversation, I decided to try adding a short wait to see if it resolved the issue for me and it now seems to be working.

https://github.com/deosrc/keepassxc/commit/942d49d242454c01f5c913a546cbc5050390d5e0

Obviously this is only tested on my machine and only briefly so can't be considered conclusive, but it seems promising in proving @droidmonkey 's earlier thoughts that this is just a timing issue.

I've not checked but the wait I used probably means that the UI locks for a second. Perhaps isActive could be used after activateWindow() in order to check if a short delay is required before re-attempting to active the window? I'm happy to have a go at producing something if it's going to help out but my C++ skills will be limited to learning from what's in the file already.

On a separate note, the build instructions were great. Kudos to the authors/contributors for that.

All 39 comments

I'm not a C++ developer but I believe I have found the cause of this.

I believe the code to bring the window to focus when triggered by the browser is:

https://github.com/keepassxreboot/keepassxc/blob/e1c2537084651c4cfeb466b28f5bcd71d05dc4ff/src/gui/DatabaseTabWidget.cpp#L678-L680

According to the documentation for activateWindow(), limitations in Windows prevents the window from taking focus:

On Windows, if you are calling this when the application is not currently the active one then it will not make it the active window. It will change the color of the taskbar entry to indicate that the window has changed in some way. This is because Microsoft does not allow an application to interrupt what the user is currently doing in another application.

For context on the other methods explained by the documentation, there is no effect if the window is not visible which explains show() and rasie() is required to bring the window to the top.

The restriction makes sense to avoid malicious applications stealing focus constantly. I think the best action would be to just make this a better user experience. I have two suggestions:

  1. The text on the browser button could be changed to "Show KeePassXC".
  2. When the window is brought to the front, the password field has a caret and border to indicate it has focus even when the window is not active. Removing this until the window gets focus could avoid confusion (this is why I got confused while trying to type my password).

I'm confused by the above summation of this issue. Because KeepassXC browser is able to get focus on my Windows 10 install sometimes. About 20% of the time, focus works correctly without having to tab away and back.

From what I can tell, my behavior isn't any different. So why does Windows sometimes considering it "interrupting what the user is currently doing" and other times not?

@awesomer I'm afraid I can't answer that as it has never worked for me on Win10 :disappointed:

This is not the cause, unfortunately. The cause is likely due to not waiting in between the raise and show commands to then issue an activate window command. I believe that sometimes windows or Qt swallows the activation too soon causing the window to be in the foreground, but stay unfocused.

I can confirm this annoying problem which has led me to typing the master password into all kinds of other windows.

I'm confused by the above summation of this issue. Because KeepassXC browser is able to get focus on my Windows 10 install sometimes. About 20% of the time, focus works correctly without having to tab away and back.

@awesomer For me, the window is always not in focus when I open it for the first time in a KeePassXC session. Maybe you could reproduce this behaviour, too, if you had KeePassXC set to be in the system tray at startup and to go to tray if the window is minimized, and to minimize on database unlock?

Interestingly, when I once focused the window manually and then lock and reopen the database in this session, the window correctly comes up in focus.

@mara004 : I confirm that my window isn't in focus the first time in a session, but that seems to be true regardless of whether I have "Show a System Tray Icon" and "Hide Window to System Tray" checked in Settings.

Checking or unchecking those boxes does not seem to have any effect on this behavior. Other than the first unlock always being broken, whether I have or haven't unlocked before doesn't seem to meaningfully change it either.

Same problem here. It's not in focus also if you click the KeePass icon on a username field while the database is locked. I think the problem is the same. Just reporting.
When you click the keepass icon, the windows is shown but if you write something, it's inserted in the webpage and not in the password field

@awesomer For me, the window is always not in focus when I open it for the first time in a KeePassXC session. Maybe you could reproduce this behaviour, too, if you had KeePassXC set to be in the system tray at startup and to go to tray if the window is minimized, and to minimize on database unlock?

Interestingly, when I once focused the window manually and then lock and reopen the database in this session, the window correctly comes up in focus.

Same behaviour for me. I'd really like this solved if possible.

The continued lack of engagement with an issue which results in users leaking a portion of their key vault password into web forms is starting to significantly impact my confidence in KeepassXC as a project. While happy with the software otherwise, I hesitate to recommend it to others while this serious issue is outstanding.

I first reported this problem on June 20th, 2020, 143 days ago [1]. Other users have repeatedly reported it since. At very least, could we get a statement regarding whether the project considers this issue serious enough to address?

[1] https://github.com/keepassxreboot/keepassxc-browser/issues/922

Just ensure the pop-up us in focus before typing. There are many other things that can cause a window to not obtain focus. We are doing all we can in code right now without funky workarounds that may or may not work. At the end of the day, where your keyboard is focused is really up to YOU. The program can fail due to external reasons out of our control.

While I agree that KeePassXC can't be expected to handle all cases where the window doesn't handle focus, I think it's a bit much to expect the user (especially less technical users) to recognise that the window isn't focused when it looks exactly the same. That being said, I recognise this isn't the most exciting item to be working on and we shouldn't expect anything reported to be fixed for free, so I decided to see what I could do to help.

Fair warning that I've never done any C++ before. I will also stress that this is not a solution, only investigating the cause. Based on earlier conversation, I decided to try adding a short wait to see if it resolved the issue for me and it now seems to be working.

https://github.com/deosrc/keepassxc/commit/942d49d242454c01f5c913a546cbc5050390d5e0

Obviously this is only tested on my machine and only briefly so can't be considered conclusive, but it seems promising in proving @droidmonkey 's earlier thoughts that this is just a timing issue.

I've not checked but the wait I used probably means that the UI locks for a second. Perhaps isActive could be used after activateWindow() in order to check if a short delay is required before re-attempting to active the window? I'm happy to have a go at producing something if it's going to help out but my C++ skills will be limited to learning from what's in the file already.

On a separate note, the build instructions were great. Kudos to the authors/contributors for that.

I respectfully disagree that it is reasonable for the user to be expected to assume that they will have to manually verify the focus of a window which they are typing their most secret password into. Every other foregrounded/focused window I have encountered in Windows, ever, has also been active and ready for my input. The appropriate response to such an unusual landmine in security software UI is probably not to tell one's users "well, don't step on it, then!"

Thanks to @deosrc for their initiative and hackish proposed solution. Unfortunately after building a version with their patch (https://github.com/deosrc/keepassxc/commit/942d49d242454c01f5c913a546cbc5050390d5e0), I was unable to verify any fix; it still doesn't accept input. To further test the patch, I increased the wait to 2000 and also removed the ifdef to force it to always wait. I also put in a second round of show/raise/activateWindow, still to no effect. FWIW, when the wait was set to 2000, I saw no indication that anything in the UI was blocking for 2 seconds.

As an aside to interested parties, the way one can visually ascertain whether the input box is focused or not is to look at the window title. If it is grey, the window is not focused and active for input, even though it is foregrounded and the input cursor is flashing. Until this issue is resolved, the safest course of action is to always mouse click in the text entry box before typing.

Thanks for testing @awesomer. Did you test the change linked above or the latest on the branch? (https://github.com/deosrc/keepassxc/tree/bugfix/window-not-focusing)

I made some further tweaks to try detect if the window was active rather than just copying the intent stuff in the code above. I also removed the ifdef as it should be safe for any OS if the window active check works. Unfortunately I didn't get around to testing it much which is why I didn't post yet.

I agree that it would be better if the window displayed "greyed" or something to indicate it isn't active. I looked into it as a failsafe if the window is still not active after the second activation attempt but I couldn't work it out. Probably needs someone with Qt experience.

@deosrc : Thanks again for your engagement with the issue, happy to continue to test potential fixes. I am surprised that you have experienced it working, are you on up-to-date Windows 10?

I initially tested the patch linked above. I just built and tested your branch. Still, unfortunately, the same negative result.

I tried the following scorched earth approach :

- if (!m_databaseOpenDialog->isActiveWindow()) {
+ while (!m_databaseOpenDialog->isActiveWindow()) {

It did not block indefinitely, as I expected it to. While I am (obviously!) not an expert in Qt, this suggests that the window may become active, but that somehow being active doesn't mean that it has the relevant input focus? When I have more time to dedicate to investigation, I will add some debug output to attempt to understand whether m_databaseOpenDialog does in fact return true for isActiveWindow().

I am starting to think that the reason that 1Password's Chrome extension takes it's own input is to avoid this particular Windows GUI issue. It seems to take the password input and passes it to the background process, unlocking it, without the need to foreground the background process. This approach is probably the needed solution here?

We explicitly do not pass your database credentials through the browser because that is a massive security risk. I think you have something going on with your environment that is causing persistent focus failures. Can you describe your exact steps or take a video of your usage?

I can do a screen recording, but it's so extremely simple and unremarkable that the steps should suffice. The behavior is the same in Chrome or Firefox, including in a Chrome Incognito window.

  1. start with KeePassXC open, but locked, with KeePassXC-browser extension icon displaying an orange lock
  2. click on KeePassXC-browser extension icon in extensions bar, it says "Database Not Opened" with a button labelled "Reopen Database"
  3. click "Reopen Database"
  4. KeePassXC icon flashes in the toolbar and "Unlock Database - KeePassXC" window pops up with the window title greyed out, the cursor flashing in the "Enter Password" input box.

If I type after opening the dialogue in this way, the characters do not go into the "Enter Password" box, they appear to go... nowhere.

Edit : If I do this repeatedly, it will very, very occasionally correctly take input. I am unable to reproduce in what circumstances this occurs.

OR

  1. start with KeePassXC open, but locked, with KeePassXC-browser extension icon displaying an orange lock
  2. load page with stored passwords.
  3. click on KeePassXC-browser icon displaying a orange lock, in a username field.
  4. KeePassXC icon flashes in the toolbar and "Unlock Database - KeePassXC" window pops up with the window title greyed out, the cursor flashing in the "Enter Password" input box.

In this case, typing results in the typed characters being typed in plaintext into the browser, in the form field in which the icon was clicked to attempt to unlock.

I'm not running Stardock Windowblinds or anything that should interfere with window focus. ~Perhaps I should try starting Windows in Safe Mode to see if there's any difference...~

Edit : I was able to get it to work more frequently for a short time by doing the following -

  1. click "reopen database"
  2. mouse click in the "Unlock Database - KeePassXC" window text input box, and input text
  3. close the "Unlock Database - KeePassXC" window
  4. tab back to the browser and click "reopen database" again

This resulted in successful focus a few times... and then suddenly stopped working again. Really weird.

Edit 2 : It doesn't make a difference whether I have a single desktops or multiple desktops via "extend."

Edit 3 : Safe Mode with Networking behavior is identical.

I think you have something going on with your environment that is causing persistent focus failures.

I don't believe the problems are due to @awesomer's particular system. As far as I could test, the focus problem just affects all Windows 8.1 and 10 users. On the Linux distribution I use focus works correctly, however.

Thanks we know this affects Windows. That was not what I was referring to. There could be other applications and settings on his computer that cause this to happen _more often_ than most other people.

I think I can reproduce it consistently with these steps which are similar to what awesomer has described.

Precondition: KeepassXC is locked and minimized. It's hidden in the task bar, only the tray icon is visible.

(KeepassXC stays locked all the time time in all following steps)

  1. Click "Reopen Database" in the browser.
    Result: The "Unlock Database" window opens but is not focused
  2. Close the "Unlock Database" window (click on x).
  3. Click "Reopen Database" in the browser.
    Result: The "Unlock Database" window opens and is focused correctly.

So the first time it fails but once focus is successful, I can repeat these step 2 and 3 without any issues, if I really just open and close the window repeatedly.

Now when it's working, I can break it again reliably with these steps:

  1. Close the "Unlock Database" window (click on x).
  2. Click on the KeepassXC tray icon.
    Result: The main " [locked]" window opens.
  3. Click "Reopen Database" in the browser.
    Result: The "Unlock Database" window opens but is not focused again.

As long as the main window is open, I can repeat step 1 and 2 without the "Unlock Database" window ever getting focus.
Now if I close the main window, I can repeat steps 1-3 and have it always focused from then on correctly again. I tried everything a lot and so far the behaviour seems consistent.

Great that's what I was looking for

I tried to reproduce the instructions by @kapexx. My setup and experience is slightly different:

Precondition: KeepassXC is locked and minimized. It's ~hidden~ in the task bar, ~only the~ no tray icon is visible.

  1. Click "Reopen Database" in the browser.
    Result: The "Unlock Database" window opens but is not focused
  2. Close the "Unlock Database" window (click on x).
  3. Click "Reopen Database" in the browser.
    Result: The "Unlock Database" window opens but is not focused

So it fails all the time. Note the difference of taskbar vs. tray icon. Given @kapexx final observations, could this be related as in the minimized window is never really gone?

As for my environment: Win 10 with FF (both auto-updated), KeepassXC 2.6.2, nothing special that I would know of.

I unchecked the option to hide the window when minimized and can confirm @f00f's observation that the login window fails to get focus every time then.

I forgot to mention I have the issue on two different machines both with Win 10, FF, KeepassXC 2.6.2.

I'll work this tonight

@kapexx : "the option to hide the window when minimized" could you be more specific about where exactly this is located in Settings?

Edit : Oh yeah, that setting. I forgot that you can scroll down in "Basic Settings" and wasn't seeing it, LOL.

@kapexx : "the option to hide the window when minimized" could you be more specific about where exactly this is located in Settings?

I think it's this one:

Application Settings > General > Basic Settings > User Interface (Bottom) > Show a System tray icon (must be checked) > Hide window to system tray when minimised

I have this unchecked and also encounter this issue every time. Maybe this is two issues? Potentially why the slight delay I added in https://github.com/deosrc/keepassxc/tree/bugfix/window-not-focusing resolved it for me but not for others.

Application Settings > General > Basic Settings > User Interface (Bottom) > Show a System tray icon (must be checked) > Hide window to system tray when minimised

@awesomer that's the options I meant. I don't see any option to change the UI language so I didn't know how the menus and options are named in English. The German translation is literally just "hide window when minimized". _Edit: I found the language setting, it actually is right above the mentioned option.._

First, technical note: pressing the global Auto-Type key sequence while the database is locked calls the exact same code as the browser extension. The exact same unlock dialog is used for both purposes. When using the Auto-Type key sequence, the unlock dialog is never unfocused, even from within the browser.

OK I tried the following using the above replication steps:

1) Added delays before and after showing dialog -- broken
2) Calling activateWindow and raise multiple times -- broken
3) Adding QTimer::singleShot to call unlock request after delay -- broken
4) Removed parent on m_databaseOpenDialog -- better, first show still unfocused, subsequent shows were focused

See branch: fix/unlock-dialog

At this point I have no idea what else to try, I spent 3 hours trying all sorts of different things and still no explanation as to why the Auto-Type trigger doesn't exhibit this behavior at all (reminder SAME CODE!). I strongly believe this is related to interacting with the browser just before the dialog is shown.

I have an untested idea... we could detect if the dialog is not the active window, close it, then reopen it again. This should simulate the working behavior shown in trial 4 above.

Weird AF. I commented on October 19 (https://github.com/keepassxreboot/keepassxc/issues/5390#issuecomment-712450975) that the minimize to tray setting didn't seem to help. In testing today, it seemed to help overall. If the locked window is minimized to the tray and not the taskbar, I sometimes successfully get focus repeatedly.

In sum, I still can't determine what changes between repeated successful focus and repeated unsuccessful focus, but that setting does help. I am excited to see if the close/re-open strategy works, googling about this particular QT behavior did find people suggesting this as a workaround.

@droidmonkey : really appreciate you diving in, multiple users will have a much smoother experience with the crucial workflow if you can get to the bottom of this! 馃槉

My idea did not work.

When using the Auto-Type key sequence, the unlock dialog is never unfocused, even from within the browser.

Out of curiosity I tried the browser addon auto-type shortcuts but it's the same behaviour as with the "Reopen Database" button (first time never work, then it keeps working until the main windows is opened). Not sure if this is related: using the shortcuts, I can't seem to open the login window twice in the same browser tab after I closed it the first time. Nothing happens when I hit the shortcut keys again. If I switch tabs to another login form I can open it with the shortcut again. Is that a feature?

One more observation: If I use the browser autotype shortcut or if I click on the KeepassXC icon in a login field and the login window doesn't get focussed, then whatever input I type goes straight into the login field in the browser. But if I use the "Reopen Database" button and the login window doesn't get focussed, then any input I type seems to go nowhere anywhere (I guess because the button is focused instead of an input form).

So to avoid compromising the master password by accidentally typing it into some login form, I will deactivate these icons and browser shortcuts for now.

Auto-Type is a totally different feature than the browser integration, I was not referring to the keyboard shortcuts in the browser that trigger the browser fill action.

Yeah I got that. Global auto-type did work fine for me too. As I said I was just curious and wanted to see if there's any difference between the browser buttons and browser shortcuts.

Keepass2 had the option "Enter master key on secure desktop". Having this turned on it is impossible to have another window focused.

fyi: When I had issues activating a window from a not currently active window (many year ago, so I don't know if this trick would still work) the only way I found to make it work was to launch a new process which would then call activateWindow on the relevant window. The newly launched process was active (even when launched from a process that was not active) and so it could successfully activate the required window.

@normanr I tried activating the main window even while minimized, then showing the dialog and it still fails. I find this to be tightly linked with the browser interaction that occurs just before the dialog is shown. When using auto type global shortcut to unlock database, the same code is executed, yet the window is focused every time. Even if the browser is in focus.

A possible solution would be to make the master password input dialog system modal

This property holds whether the widget is a modal widget
This property only makes sense for windows. A modal widget prevents widgets in all other windows from getting any input.

This is similar to Windows UAC feature allowing KeePass2 to "Enter master key on secure desktop", but the blocking of other apps is done at the app level instead of the OS level.

Unfortunately no, modality only works within the same application (when Qt says "all other windows" they mean in the same application). We already tell it to "stay on top" and explicitly focus to it. I will try making it explicitly modal, but like I said it works always when using Auto-Type shortcut so modality isn't the problem here.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

clementlesne picture clementlesne  路  3Comments

MisterY picture MisterY  路  3Comments

n1trux picture n1trux  路  3Comments

2tbwXj46BDbdNBRV79DS picture 2tbwXj46BDbdNBRV79DS  路  3Comments

guihkx picture guihkx  路  3Comments