How your passwords are stored
QtPass does not encrypt anything itself. Every password is a file in
your password store, encrypted by
GnuPG to the public keys listed in
the folder's .gpg-id; only the matching secret keys can
open it. The store is a plain folder (usually
~/.password-store) that you can read with
pass, back up, or put
under Git. QtPass is the window onto it: it asks GnuPG to decrypt an
entry when you select it and to encrypt when you save.
Nothing leaves your computer unless you turn on Git and push to a remote of your choosing. QtPass has no accounts, no telemetry and no network code of its own (privacy policy).
What it protects against, and what it does not
Someone who obtains your password store, but not your secret key, gets nothing: the files are ciphertext. That covers a stolen backup, a leaked Git remote, a shared server.
Someone who controls the computer you decrypt on gets everything you decrypt there. No password manager can change that. A smartcard or YubiKey narrows it: the secret key never leaves the card, so an attacker who copies your disk or logs your keystrokes still cannot decrypt on another machine. But once the card is plugged in and the PIN entered, any software on that machine can ask it to decrypt (with an old GnuPG, thanks to CVE-2015-3298, even without the PIN). Two things help against a targeted attack:
- A card that requires a touch or a confirmation for every decryption, or at least keeps a counter you can compare afterwards.
- Different cards, or at least different keys, for different groups of passwords, so one unlocked key does not unlock the whole store.
The whitepaper from the early days goes through the model in more detail; the conclusions still hold.
Clipboard and screen
A decrypted password is only as private as the screen and the clipboard it ends up on. QtPass gives you the knobs in Configuration:
- Clipboard: copy always, on demand, or never; clear it again after a timeout (45 seconds by default). On X11 the primary selection can be left out of it.
- Content panel: hide the password, hide all content, and clear the panel after a timeout, for working with someone looking over your shoulder.
- One-time password secrets are never shown, only the current code.
Verifying downloads
Every release asset on the
releases page
has a detached signature next to it (.asc), made with the
maintainer's OpenPGP key:
DF7F EF8D FBA7 21E3 20B1 8F56 15B6 3ADC A003 4B9E
gpg --keyserver hkps://keys.openpgp.org --recv-keys DF7FEF8DFBA721E320B18F5615B63ADCA0034B9E
gpg --verify QtPass-1.8.1.tar.gz.asc QtPass-1.8.1.tar.gz
The same key is at
annejan.com/key.asc.
Packages from your distribution are signed by the distribution
instead; the downloads page lists them. The
macOS .dmg and the Windows installer are not code-signed
by Apple or Microsoft; the OpenPGP signature is what you have there,
see macOS.
Password generator
The built-in generator has used a proper random source since 1.2.1;
today that is the operating system's
(QRandomGenerator::system()), with rejection sampling so
no character is favoured. Or it calls pwgen if you
prefer.
Advisory, 2016: passwords generated by QtPass
before 1.2.1 are predictable. The generator used libc's
random() seeded with the millisecond within the current
second, so there were only 1000 possible sequences (#338). This was a QtPass bug, not one in pass or GnuPG. If you still have
passwords generated by a QtPass older than 1.2.1, change them.
Reporting a vulnerability
Please do not open a public issue for a security problem. Instead:
- mail help@qtpass.org, encrypted to the key above if you like, or
- open a private security advisory on GitHub.
Include what you found, how to reproduce it and what you think the impact is; a suggested fix is welcome but not required. You get an acknowledgement within 48 hours and a first assessment within a week; fixes are prioritised by severity. Security fixes go into the current 1.8.x release; older versions are not maintained. The machine-readable version of this is /.well-known/security.txt, the source of record is SECURITY.md.