Skip to content
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

Feature request / security enhancement: gpg encrypt + sign to ensure both confidentiality and authenticity, and check signature before decrypting #2932

Open
jerabaul29 opened this issue Aug 31, 2024 · 3 comments

Comments

@jerabaul29
Copy link

It is clear that https://rot256.dev/post/pass/ has several good points about issues in the security model of pass (and similarly gopass, as if I understand correctly gopass does things very similar to pass?). In particular, there are a number of challenges when relying on a third party that is not necessarily fully trusted to back up the password (as many users do, by using github as a way to synchronize the git repo containing their passwords; github can be hacked / forced by government / one can fall for a man-in-the-middle attack against github etc).

The main issues pointed in this article arise when there is no guaranteed authenticity check in place; this is what would in theory allow an attacker tricking github (or any other service used to sync git), to trick the user into deciphering arbitrary data.

There would be a simple fix for that: when creating a password, not just gpg-encrypt it with the public key, but also sign the gpg-encrypted key with the private key. This way, hijacking github would be visible for the user, as the hijacked gpg-encrypted keys would not be signed.

I can think of at least 2 ways to implement this:

  • 1: use git signed commits, and refuse / warn about decrypting a password that comes from a non signed commit.

  • 2: encrypt + sign when performing the secret encryption. I suppose that this could be done directly by using a functionality similar to the --encrypt --sign flags that can be used together with gpg, into the encryption done by gopass? Doing so the encrypt + sign should be used at password creation, and then at password decryption, one should first check the signature, and then decrypt (or if no or invalid signature, at least warn about it and offer a y/n answer if decryption should be done); this would require a bit of implementation on gopass side, but this would allow to enforce authenticity independently of any compromised third party used for password synchronization.

Implementing one of these solutions, especially solution 2, would be a nice security boost, while requiring potentially little extra work (I am not familiar with the internals of gopass, but I guess changing from --encrypt to --encrypt --sign should not be too much?).

If implementing solution 1 or 2, it could be nice to provide a command to migrate from non-authenticated to authenticated gopass store, by signing existing commits / re-encrypting all secrets with signature in one gopass command.

@dominikschulz
Copy link
Member

Thanks for this suggestion.

One issue I see is that signing will require the passphrase when writing secrets. Something we currently do not require.

But as an optional feature this might be something worth toying around with.

@jerabaul29
Copy link
Author

Yes, I agree that it is a tiny bit more hazzle to write the passphrase when writing secret - but as you say, it could be nice to have this as an option (configurable with either a flag and / or a global config option for the store?), as it would negate a whole class of possible attacks :) . For my part, I would definitely include it in my store, I would see this very much worth the tiny hazzle :) .

I actually use pass for now (considering / in the process to move to gopass), so I was not thinking about another aspect, which is shared stores. Not sure how this works in details / is implemented in gopass, but this specific case may also require a tiny bit more logics (i.e., signing will happen with the private key of the specific person adding the secret, and then any other user of the shared store should accept that the shared secret is signed with the corresponding key and not their own, as long as it is valid to sign with the mentioned key. I would guess valid here would mean in the list of recipients for the corresponding store / the list of people in the current store? not sure how this works internally / how to determine and enforce this; but for single user stores this should not be an issue, could be implemented for single user store to start with, and then extended to the multi-user store? :) ).

@AnomalRoil
Copy link
Member

Honestly, the proper way to solve all the complaints from there would be for us to finally get around to implementing our age backend with a fully encrypted store and use age scrypt recipient for the store itself as well...
It's been requested too many times, and would be nice to have for sure. #931

But in turn it's not very compatible with the team usage, since it assumes knowledge of the store password.

So the actual solution would be to have an hybrid PQ approach to be both classically and post-quantum secure to encrypt the store I guess.
Which is possible with age using the (yet to be released?) plugin described in https://words.filippo.io/dispatches/post-quantum-age/ that would be combining both kyber+x25519 into a single recipient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants