Keepassxc: Key file last position is remembered after session lock

Created on 30 Oct 2017  Â·  36Comments  Â·  Source: keepassxreboot/keepassxc

KeepassXC remembers the exact position (directory) of the Key file after session is locked/unlocked, potentially reducing the security of the key file, even if "remember last key files and security dongles" option is disabled.

Expected Behavior

After a session lock / lid closed KeepassXC should point to the user home directory (as for a new instance of KeepassXC) instead of bringing the user to the directory where the last used key file is/was positioned.

Steps to Reproduce (for bugs)

While using a database with also a key file master key:

  1. De-select "Remember last key files and security dongles"
  2. Select "Lock databases when session is locked or lid is closed"
  3. Lock session
  4. Unlock session
  5. Browse for the key file

Debug Info

KeePassXC - Version 2.2.2
Revision: 6d46717

Libraries:

  • Qt 5.9.2
  • libgcrypt 1.8.1

Operating system: Windows 7 SP 1 (6.1)
CPU architecture: x86_64
Kernel: winnt 6.1.7601

Enabled extensions:

  • KeePassHTTP
  • Auto-Type
  • YubiKey
bug security

All 36 comments

Does this happen when you first open the database or only on lock/unlock?

Only on lock/unlock. At first it points to the user home directory.

This is likely because we reuse the widget that you enter your password into to unlock and don't clear the "memory" stored in the browse... Button.

If you want to make sure nothing is left in memory, you should really terminate KeePassXC. The option only makes sure that nothing is stored on disk.
I don't really see this too much as a security issue, especially when the key file is on an external disk drive. There are a lot more things that perhaps should be purged from memory, but aren't (e.g., the position of the selected entry inside a DB). Yes, maybe we should clear all those things, but on the other hand, your passwords are probably already compromised when a malicious application can access your system's memory. Aknowledged, one reasonable threat scenario would be if you leave your workstation and someone else then creates a memory dump. But that same person could also simply install a key logger and get your password next time you unlock the database.

Indeed, that's why I called it just a potential reduction of security.
But speaking about the scenario, I was thinking of a compromised OS account password, more than a memory dump.
IDK, maybe there are indeed worse things and better priorities, but I thought it could be a little improvement :)

It's an issue, but nothing that shouldn't let you sleep at night. It's weighing security against usability. I kind of like it when the database Remembers my selection, but you may of course argue that it leaks at least meta data about the database. Perhaps we should go over the code, identify those parts and then thoroughly decide how to proceed with them. We fixed an issue in the past where KeePassXC wouldn't clear the search field. I think that was a bigger issue, because it potentially allowed shoulder surfing.

The issue of the OP happens to me, but at startup. I've checked "Remember last databases", but unchecked "Remember last key files and security dongles", yet if I click on "Browse" at keepassxc startup, the file dialog opens in the key file directory... so you know, if you don't use a password and there aren't so many files in that dir, you're giving away the database.

I think I remember this didn't happen with the original keepassx software.


KeePassXC - Version 2.2.2
Revision: 6d46717

Libraries:

  • Qt 5.9.2
  • libgcrypt 1.8.1

Operating system: Arch Linux
CPU architecture: x86_64
Kernel: linux 4.13.9-1-ARCH

Enabled extensions:

  • KeePassHTTP
  • Auto-Type
  • YubiKey

@tomgar not using any password is extremely dangerous.

I know... just acknowledging the consequences of letting keepassxc remember the last dir in the file dialog.

So... I see that OP is using windows and I'm using linux... do I have to make another issue? Or fixing OP's issue will fix my issue too?

Thanks.

It is a good question, no need for a new issue at this point. If we do fix this and it does not work on Linux then we can open a new issue specifically for Linux. However, that would likely be a Qt bug at that point.

I think that is just expected behavior in any case. Remembering the last browsed directory is just a feature of any better file browser and it would be absolutely annoying if it didn't. We also can't really fix it. While it may be fixable for the Qt-internal dialog, we cannot guarantee that the system's dialog, which Qt uses instead if possible, will also honor that, unless maybe we hardcode a default location.

Thanks, @phoerious and @droidmonkey.

Just for the sake of it, I took a quick look at the source code...
https://github.com/keepassx/keepassx/blob/master/src/gui/DatabaseOpenWidget.cpp (line 170 onwards)
https://github.com/keepassxreboot/keepassxc/blob/develop/src/gui/DatabaseOpenWidget.cpp (line 277 onwards)

Unless another code is being used in keeypassxc, they look pretty much the same to me... yet, keepassx opens a file dialog which opens by default to the XDG-sanctioned Docs dir, and keepassxc opens a file dialog in the last dir used. And both file dialogs are different, actually, I think the keepassxc looks like the GTK one to me. So I guess you're correct, different versions of Qt, different behaviors.

Anyway something must be done... or even tell Qt about it. I don't think this is not the only project where it's in the interest of the software that the file dialogs don't leak this kind of info.

I looked into the code a little bit more.
The fileDialog for the keyfile is called by fileDialog()->getOpenFileName(this, tr("Select key file"), QString(), filters);
https://github.com/keepassxreboot/keepassxc/blob/master/src/gui/DatabaseOpenWidget.cpp#L274

getOpenFileName is declared QString FileDialog::getOpenFileName(parent, caption, dir, ...), so the dir is set to an empty string,
https://github.com/keepassxreboot/keepassxc/blob/develop/src/gui/FileDialog.cpp#L34-L36

Then there is this if, that load the last directory from config if dir is empty

if (dir.isEmpty()) {
    dir = config()->get("LastDir").toString();
}

LastDir is a KeePassXC "internal" configuration that keep track of user last selected folders, it's used also when browsing for DB, importing CSV file, adding entry icon, etc.

Ideas?

Good find @TheZ3ro !

I went into my ~/.config/keepassxc/keepassxc.ini file, and saw a LastDir entry in there. I removed it and checked now that the file dialog of "Browse" button points to my home, instead of the last dir of the key file, as it should be.

But to my dismay, once the database is opened, I closed Keepassxc and opened it again, and now the "Browse" button points to the last dir of the key file again! And yes, I checked the keepassxc.ini and there's the LastDir entry there again too.... so it's fixable:

  • If "Remember last key files and security dongles" is unchecked by the user, remove the LastDir entry immediately.
  • As long as the "Remember last key files and security dongles" is unchecked, don't store the last directory in the config file.

If the last dir is being used for another purposes, like for opening databases for convenience, then it would be best to have several LastDir entries instead (and let the user configure all that stuff) or not having one for the last key files at all.

But to my dismay, once the database is opened, I closed Keepassxc and opened it again, and now the "Browse" button points to the last dir of the key file again!

So you store the database and the keyfile in the same directory.
When you open the database the LastDir is set to the database dir.

I'm not a fan of adding many and many configuration.

I would instead make an if statement when the getOpenFileName is called for the keyfile and if "Remember last key files and security dongles" is True, set the directory to the user HomeDir, otherwise use and empty string that will resolve LastDir

So you store the database and the keyfile in the same directory.
When you open the database the LastDir is set to the database dir.

No, because I'm using the "Remember last databases" option which means I'm not using the LastDir entry to open the database; it's already stored in the .ini file (LastDatabases entry), so I necessarily need to open a file dialog (for the last key) to update the LastDir entry.

I don't care that keepassxc tells a user where the database is. Unless I'm using stenography or I change the extension of the file, it will be easy to find it. I care that there're hints about where the keyfile to open it is. If you don't delete the LastDir entry and avoid at all cost storing that info in the ini file, a third-party could know that and get the config file too to know where to look in spite of Keepassxc opening always the home directory.

"Hiding" the keyfile on disk is not a security measure.
It's pretty easy for a malware searching through all the folders and find keyfiles in your disk.
You should store the keyfile in a different device.

In case someone has physically access to your PC remove the device with the keyfile and don't tell them your password

Adding a new setting for this is ultra paranoid and pretty useless, i think the solution I proposed before is enough

With the stenography thing, I was talking about the database.

I don't quite get how malware would find keyfiles in disk though, since a keyfile could be anything, e.g. use a jpg file as a keyfile, so there's no shape or form of what a keyfile is.

As long as the key file directory is not stored in disk and the file dialog opens a default place, I think @jamm3r and I will be happy.

Quoting the keepass website https://keepass.info/help/base/keys.html

The point is not to keep the location of the key file secret – selecting a file out of thousands existing on your hard disk basically doesn't increase security at all, because it's very easy for malware/attackers to find out the correct file (for example by observing the last access times of files, the recently used files list of Windows, malware scanner logs, etc.). Trying to keep the key file location secret is security by obscurity, i.e. not really effective.

I use noatime in my hard disk partitions, so those things won't apply here, but having a LastDir entry stored in the .ini config file is a red flag, even if the keyfile is in an external USB device. It's like telling the world what to use to open my password database. Imagine a guy who has only the key file in that directory. There are variations of these situations and if there's a setting which says "remember last key files" and it's unchecked, it doesn't help that the key file directory is remembered; it's like it's not following the point of that setting. I imagine not everybody use several password databases, so that LastDir entry is a good hint of where the keyfile is in case a keyfile is being used.

I think that it's best not to store the last dir entry like the old keepassx software did (the software from where you got that text actually that it did the correct thing), but anyway I'm not going to continue this conversation. I think my point is clear enough. Thanks.

Not only .config/keepassxc/keepassxc.ini:LastDir,

.config/QtProject.conf:history
.config/QtProject.conf:lastVisited
are also saving last position. And that was caused by KeepassXC.

I think I remember this didn't happen with the original keepassx software.

That's true. So today I am still using KeepassX. I hope I can switch to KeepassXC in the future.

Interesting find @garywill. This is a Qt "feature" but it may be possible to disable it. These guys did some digging already: https://musescore.org/en/node/75306#comment-345291

And that was caused by KeepassXC.

It's not caused by KeePassXC, it's caused by Qt5 :)

Every Qt5 program will write folders into that file, not just KeePassXC.

@garywill check out ~/.config/Trolltech.conf to see where KeePassX/Qt4 stores the filedialog histroy path :smile:

In my case, I run a "sudo chattr +i ~/.config/Trolltech.conf" which prevents Qt to write on it, a couple of years ago, which I didn't remember till you mentioned the file (I don't have a ~/.qt dir). Every Qt-related things works here nicely in spite of it. It's a known trick out there if you search in the internet, although not specifically used for this use case though.

I just did the same with ~/.config/QtProject.conf and it's working nice too. I did it too with the keepassxc.ini file and it's working nice. Just hope I remember to remove the attribute the day I need to change a setting.

At least those Qt file dialog files are common to all apps. At the moment, you use the file dialog in another Qt program, the last reference is lost.

This should be configurable in Qt to say the least too.

But, well, if keepassxc doesn't repeat the job of the file dialog, it would be great. Or if it's needed for other systems like Windows or Mac, at least, it should be configurable, in my humble opinion.

I have a solution in mind for this that can make everyone (I hope) happy.

@droidmonkey are you working on this or can I step in?

Its all yours!

I dont have ~/.qt/
In |~/.config/Trolltech.conf| and ~/.config/QtProject.conf

 filedialog=@ByteArray(\0\0\0\xb ........ ile:///home/[myusername]\0

........

check out |~/.config/Trolltech.conf| or |~/.qt/| to see where
KeePassX/Qt4 stores the |filedialog| histroy path 😄

I use KeePassXC on my laptop to store not only my website credentials but also system passwords for sudo access, opening encrypted drives, pgp keys ect.. I find this to be a very valuable tool to manage all of my different passwords while having ease of access using global auto type.
As a test, I created a database using only a keyfile (no password). With the database locked, clicking the keepassxc icon in my tray (Linux - XFCE4) brings up the unlock dialog with the fully qualified file name already filled in. All an attacker need do is click the keyfile checkbox then click enter to have access to the database. The attacker needs only a 5th grade education and little to no determination to gain access.
The main problem aside the obvious is that having anything filled in automatically gives any attacker an important clue to unlocking the database. It tells them that a keyfile WILL be part of the equation.
When the unlock dialog appears, it should be completely blank, giving an attacker no clues as to how to unlock the database. This requires an attacker to not only be technically sophisticated (relative to an average user) and very determined. Even having the keyfile path filled in narrows the possibilities from potentially thousands of choices in the case of /home/[user] down to hundreds or less in sparsely populated directories.
I love KeePassXC and thank the developers for a wonderful product.

@Hairyplotter You are talking about an attacker that already has access to your unlocked computer.
Using only the keyfile is BAD for security. You should use it as a 2nd Factor along with a password.

In the settings deselect the option "Remember last keyfiles and security dongles", this will discard previously used keyfile in the unlock dialog.

@TheZ3ro You are correct, I am talking about an attacker that has full access to an unlocked computer. Because, that is when KeePassXC will be at it's most vulnerable. I have had the option you described turned off as well as the database locking after 240 seconds of inactivity.
I do agree 100% that a keyfile should be used in tandem with a strong password.
Thank you very much for making an awesome product. Please don't take this as any kind of smear or complaint. All I was trying to do is point out that data retained by a dialog could give an attacker information they could use to their advantage.

@Hairyplotter with that option off, when unlocking the db the keyfile field should be empty.

Anyway like I've said before. The keyfile should be used as second factor, a thing that only you possess. Hiding it's location is useless since an attacker can retrive it easily or at worst he can try all the files (pretty fast and even in parallel)
https://github.com/keepassxreboot/keepassxc/issues/1151#issuecomment-341741304

For paranoid mode, the keyfile should be stored in an (encrypted) USB key and unmounted/disconnected when you are away from the PC, like a yubikey

If the attacker has full access to your computer, your passwords are already potentially compromised, not matter what.

Is this really fixed? I still find my path remembered.

My keepassxc.ini

[General]
AutoReloadOnChange=false
AutoSaveAfterEveryChange=true
AutoSaveOnExit=false
AutoTypeDelay=25
AutoTypeEntryTitleMatch=true
AutoTypeEntryURLMatch=true
AutoTypeStartDelay=500
BackupBeforeSave=false
GlobalAutoTypeKey=0
GlobalAutoTypeModifiers=0
IgnoreGroupExpansion=false
LastDatabases=@Invalid()
LastDir=**my path**
LastKeyFiles=@Invalid()
LastOpenedDatabases=
MinimizeOnCopy=false
OpenPreviousDatabasesOnStartup=false
RememberLastDatabases=false
RememberLastKeyFiles=false
SSHAgent=false
ShowToolbar=true
SingleInstance=true
UseAtomicSaves=true
UseGroupIconOnEntryCreation=true

LastDir remember my path, which shouldn't.

In QtProject.conf

[FileDialog]
history=file://**my path**
lastVisited=file://**my path**
qtVersion=5.9.4
......

Steps to Reproduce :
(Before start, I manually delete path with text editor)

  1. double click KeePassXC-2.3.3-x86_64.AppImage
  2. click open existing database
  3. navigate to the path and double click my databse file

Now KeepassXC asks for password, while keepassxc.ini's LastDir and QtProject.conf appear my path.

There must be some bug.

Some interesting phenomenon:

  • If set OpenPreviousDatabasesOnStartup=true, keepassxc.ini's LastDir doesn't always have my path
  • QtProject.conf remembers path even if you click cancle on the file-picking window

We don't have any control over QtProject.conf. Maybe there is a workaround.

For keepassxc.ini, I will look into it

Not sure if related to what garywill said but if you have the setting to lock DB after certain amount of inactivity time if you go to reopen the db again from XC the location of the key file is shown in the Key File: line on the "Enter master key" screen. Instead the Key File option should be unticked and the line left blank (just like it is for the password).

Was this page helpful?
0 / 5 - 0 ratings