keepassxreboot / keepassxc

KeePassXC is a cross-platform community-driven port of the Windows application “Keepass Password Safe”.
https://keepassxc.org/
Other
20.76k stars 1.44k forks source link

Deploy service credentials/config files on unlock (similar to ssh agent) #4847

Open JGoutin opened 4 years ago

JGoutin commented 4 years ago

Summary

Some software use plain-text files stored at fixed location on the local hard drive to store their credentials. The idea is to have the ability to secure theses files using KeePassXC.

My proposal is to have something that works exactly like the "SSH agent" feature, but instead of sending the secret to an agent, KeePassXC writes the file at the excepted location on "add to agent" and delete it on "remove from agent".

Since the file can be updated when on the disc (By the software that use it), the file may need to be updated in the database on "remove from agent" (or by checking if changed on a regular basis).

The GUI can be almost the same than the SSH agent feature one and provides the same features (Copy the file locally on database open/unlock, remove the file locally on database close/lock, ...).

Since this feature can be used with any file, it can be used with a wide variety of software (User need only to know files path).

Examples

For my work I need to use "awscli". This utility credentials are stored in the following INI file "~/.aws/credentials".

With the new feature:

Without, I can still add the file in the database, add/remove it manually to its local location, and manually update it. But I risk to forgot to remove it or update it, and loose some time by doing all operation manually.

Context

KeePassCX really help me to store my secrets more securely (Browser secrets, SSH keys, TOTP, and more). The only secrets that are not managed with it on my machines are theses plain-text credentials files.

Thanks for this awesome tool.

droidmonkey commented 4 years ago

This is an awesome idea!

hifi commented 4 years ago

With AWS specifically you can add 2FA which can be enforced for cli secrets as well.

bjornfor commented 4 years ago

Although this is a nice feature, I wish more programs supported reading passwords from stdout of a command. That way the secrets wouldn't have to touch the filesystem at all.

JGoutin commented 4 years ago

I agree that this feature is mainly intended to be used with software that does not provide a better secure solution.

There are maybe some tricks to mitigate the fact that the secret is written on the file system, like writing it on a ramfs/tmpfs if available and using a symlink from the expected position to redirect to the real file position. This ensure the secret is erased on system exit and does not leave traces on a non-volatile storage.

droidmonkey commented 4 years ago

That would require implementing a Fuse virtual file system in keepassxc. Would be helpful for attachments in general, but wildly out of scope for our application. Ideally you would be running an encrypted partition for your user space files such that any data at rest would be protected. This would simply add an additional layer of security by only having the sensitive config files present on the file system when needed.

JGoutin commented 4 years ago

It may also be possible to use some already existing tmpfs, on my OS (Fedora 32) I have the following by default (that are writeable by the current user): /run/user/1000 (Owned by the current user), /dev/shm (Owned by root). But these may not be available everywhere and some OS like Windows does not support ram drives by default.

This may be eventually be a future improvement. Even without this the feature is helpfull.

ieugen commented 4 years ago

Looking forward for something like this. It looks very similar to how Kubernetes mounts secrets in containers.

etosan commented 4 years ago

This feature seems nice, but I am strongly voicing objection against relying on FUSE for this.

Relying on FUSE will break keepasxc portability.

I used to use tup to track my file changes during builds, until it introduced brain dead FUSE support for filesystem changes. All major BSDs have proper FUSE now, but their implementations are internally quite different that that of Linux. This does not mean their FUSE verison is less capable or something, it's just a tiny bit different on each OS, which is logical as FUSE ties strongly to OS kernel.

This reliance on FUSE unfortunately makes tup unusable on BSDs. tup is tightly internally integrated with it's FUSE crap, so for somebody who does not work on tup codebase regularly or at all, it's virtually impossible to find the spot, where fixes should be applied, though it could be done as there is functional parity between BSD FUSE and Linux FUSE. I reported the issue several times, but tup authors are unable to fix it, as they don't run and know BSDs. This makes tup Linux only and thus useless.

Also FUSE adds yet another indirection whose benefits are dubious. If attacker has root on your box FUSE won't help you with that. I suggest to rely on classic filesystem semantics for this.

Still it would be really nice if keepass actually provided integrated exporting of secret keyfiles this way.

As somebody mentioned, I am using tmpfs approach, this takes care of power-off situation as file is wiped on powerfail or poweroff. Tighter restrictions should be arranged with classic POSIX permissions (it's good enough for SSH to use, so it should be good enough for keeepas) and can be strengthened further with selinux, or namespaces if you are really paranoid.

Good logic would be to export file to designated path on user request, and install inotify/kqueue monitor for that path (reverting to stat(), should those more advanced monitors not be available). As keepass seems to use Qt for that, it should have something like that in Qt toolchest. I am not sure entirely, but on Linux read detection of the file contents should work fine this way. There should be slight timeout configurable, after the keyfile is read, if consumer perhaps reads it in in multiple chunks. Once file is read, keepass would rm() it, lowering risk of secret being stolen or leaked significantly.

This is not bulletproof, and it is racy, but I think it is better performance/portability/ease-of-implementation wise than FUSE approach.

I personally would suggest having also dedicated timeout option, which would rm() the file once designated time passes without any activity on consumer or user part.

This prevents most easy stealings, but does not protect from dedicated attacker, from which keepass does not protect you either.

Having CLI support for this as well would make this fork of keepss really versatile tool.

There is something to be said about stdin approach @bjornfor mentions. Many software indeed supports this, but it's also keepass that is lacking here a bit. CLI module is somewhat anemic in this regard, especially with file descriptor redirections. Those redirections are not related to #4760, but are related to CLI plugin so maybe we should open special issue for them? It would be great if CLI invocation supported arbitrary redirections of passwords obtained to any FD, with stdout (eg stdin of next command in pipeline) being default.

fire833 commented 2 years ago

Initial Comments:

I really enjoy this idea, I had the exact same idea for things such as ~/.kube/config files for kubectl & Kubernetes. I would think it would be adequate to just load files onto the host filesystem when needed and then remove them afterwards (probably would be best implemented by zeroing the file before deleting, but even that may not be bulletproof at the hardware level for "true deletion"). Another thing to potentially mitigate security issues is allow the user to configure security permissions for the files when they are mounted to the filesystem, so the user has some more granular control on that aspect.

Security concerns

I generally agree with what you are saying @etosan, keepass will not protect you from a root attacker regardless of if this idea for mounting files is added, someone who is determined will just get root and ptrace() keepass's memory when the db is unlocked and then you are completely out of luck. As such, I don't see much of a security difference between just mounting files with custom permissions and bypassing a FUSE drive, which would have minimal security improvements for the amount of work that would be to implement.

jtagcat commented 2 months ago

Related: https://github.com/keepassxreboot/keepassxc/issues/4798 (which is not in fact a dupe of https://github.com/keepassxreboot/keepassxc/issues/2400)