phar-io / phive

The Phar Installation and Verification Environment (PHIVE)
https://phar.io
BSD 3-Clause "New" or "Revised" License
579 stars 43 forks source link

add no-interaction flag #66

Closed m8rge closed 8 years ago

m8rge commented 8 years ago
$ docker exec warehouse_app_1 phive install
Phive 0.5.0 - Copyright (C) 2015-2016 by Arne Blankerts, Sebastian Heuer and Contributors
Downloading https://phar.phpunit.de/phive.xml [ 64.47 KB / 64.47 KB - 100% ]
Downloading https://phar.phpunit.de/phpunit-4.7.7.phar [ 2.96 MB / 2.96 MB - 100% ]
Downloading https://phar.phpunit.de/phpunit-4.7.7.phar.asc [ 819 B / 819 B - 100% ]
Downloading key 4AA394086372C20A
Trying https://hkps.pool.sks-keyservers.net
Sucessfully downloaded key

    Fingerprint: D840 6D0D 8294 7747 2937 7831 4AA3 9408 6372 C20A

    Sebastian Bergmann <sebastian@php.net> (2014-07-19)
    Sebastian Bergmann <sebastian@thephp.cc> (2014-07-19)
    Sebastian Bergmann <sebastian@phpunit.de> (2014-07-19)
    Sebastian Bergmann <sb@sebastian-bergmann.de> (2014-07-19)
    Sebastian Bergmann <sebastian.bergmann@thephp.cc> (2014-07-19)

    Created: 2014-07-19

Import this key? [y|N] [ERROR]    User declined import of key 4AA394086372C20A 

This tool isn't compatible with docker. I can't specify --no-interaction flag and image build failing.

theseer commented 8 years ago

Thinking about it, I'm not even sure the aforementioned behavior is wrong: Given that the very point of using phive to install a phar is to verify the signature, silently importing any unknown key feels rather counter productive.

Additionally, the default behavior of phive is to symlink the requested phar into the project's directory. Given that a docker container should be isolated from the rest of the infrastructure, this is also seems counter productive.

An potentially better approach would be to have a shared phive home directory with all the phars and particularly their respective gpg public keys at the ready so that running phive to setup a new docker container can refer to that shared source and copy the phars into the container file system.

tl;dr: I'm not exactly sure that having a "no-interaction" mode would be wise idea, given that we are talking about security relevant things. Instead, there may be a need to specifiy an alternative GPG home directory so a previously generated keyring can be used.

sebastianheuer commented 8 years ago

@theseer and I discussed this today and we both think that implementing a generic "no-interaction" flag is not something we like (as @theseer explained in his comment).

Instead we came up with the following idea: Users can provide a list of GPG Key IDs they want Phive to accept without asking interactively either via command line arguments or via the project-specific phive.xml. On the command line this could look something like this:

phive install --trust-gpg-keys 4AA394086372C20A[,...] phpunit

By explicitly trusting only certain keys, your Docker build will fail when the key assigned to the downloaded PHAR changes, giving you an opportunity to check if that change is actually correct. If you used some generic "always say yes to everything" option, you would not notice that (or maybe notice it too late, when your Docker image is already being used in production).

theseer commented 8 years ago

Closed in favor of #69.

radmen commented 1 year ago

@theseer @sebastianheuer I understand the point about not adding the --no-interactive flag. For CI, the phive install will have to be used with the --trust-gpg-keys option.

Since that flag will be part of the CI config, would it be possible to keep the trusted GPG key in the phive.xml lock file? I don't see any bigger difference (keep them in CI config vs. in Phive lock file), but it is more usable in terms of maintenance.

The one who installs a new archive and "trusts" the GPG key is saying, "I verified those keys. Let's trust them project-wise".

What do you think? In general, I'm wondering if my idea is valid in terms of security. Thank you!

theseer commented 1 year ago

Thanks for taking the time to give feedback here.

We again have a conflict of interests here: If we were to store the trust choice in the phive.xml, that means it would become part of the repository. For the reason you described in your idea and for your use case that makes total sense. But If you clone any random project from github, would you blindly trust their choice of trustworthy keys to be adopted into your environment? Keep in mind that phive tries to keep a shared environment in ~/.phive. An accepted key imported due to its use in said cloned repo would thus impact the overall system. We could of course have a per-project trust store - but then you'd have to reconfirm the same key for every project despite having the phar file already on disk.

So all that doesn't make sense.

What I'm considering though is to have a list of trusted key ids stored in a separate file per project and provide a means to load the list of trusted keys from that file rather than having to manage the CLI call.

radmen commented 1 year ago

@theseer I see your point and it makes sense. Thank you.

I'm new to the project and maybe I miss the obvious thing, but still, I will ask :) Why GPG and not using SHA sums to validate that the correct library was downloaded? I think the latter could be kept in the phive.xml without any issues you mentioned.

theseer commented 1 year ago

I'm new to the project and maybe I miss the obvious thing, but still, I will ask :) Why GPG and not using SHA sums to validate that the correct library was downloaded? I think the latter could be kept in the phive.xml without any issues you mentioned.

A perfectly valid question .

Short Answer

Because it lags any means to authenticate the signature - because technically it's not a signature to begin with.

Long Answer

SHA-x are a common example to provide a means to ensure the data is identical on both ends of the line. But that's all it does.

What we want here is a lot more: We not only care about the fact the downloaded file is identical to the one published - even though that is of course important - but we are looking for a signature.

Think of a physical checklist on paper: The SHA-x is the equivalent of ticking of an item on that list. Without a signature below, anybody could have ticked the box.

There are two common digital ways to sign things: GnuPG/GPG and OpenSSL. Both rely on private/public key file pairs. The idea is that to create a signature you do need access to the private key, to verify the public key is sufficient.

That way, nobdoy can easily forge the signature.

Problem with OpenSSL signatures is that they do not include any identity/owner information. Think of it as an unlabled physical key. Yes, it will be needed to open the matching lock, but you have no idea who's key that is.

So technically, we'd be back to square one: We now have a checklist with a valid signature but we have no idea who the person signing is - we just know a person claiming to have signed it, actually did so in case we get their "key" to compare.

That's all not very helpful. So for OpenSSL and friends, you add certificates and certificate authorities to the mix - like you see with browsers and https. Already getting complex, but we're not even close to being done here.

In our example of downloading a phar, we now have the phar and a signature. But how do we get the public key to verify the signature? And the certificate to decide whether or not to trust the signer? Turns out, we don't as that's not possible based on the signature with OpenSSL alone.

Enter GnuPG: A gpg signature, in a nutshell, is a cryptographically wrapped hash of a "message". That wrapper contains the key-ID used to make the signature. Everybody publishing signatures like that is required to publish their respective public key onto keyservers. Given those keys a public in nature, you can query these key servers using the aforementioned key-ID. In contrast to OpenSSL (and SHA-x), the received public key DOES contain identity information.

That allows us to dump that info to the user and have the user decide whether or not to trust that information. Because technically, since everybody can upload keys to a key server, there is no proof that the person uploading the key is actually who she or he claims to be.

That's why most systems show the key-id and/or a fingerprint and make the user compare it with the information published elsewhere by the "legitimate" owner. For instance, we publish our fingerprint on https://phar.io in the footer.

So, that's why we (and the rest of the linux/git/... world ;-)) uses gpg.

radmen commented 1 year ago

@theseer Thank you for the explanation. I appreciate it a lot! It makes a lot of sense and I understand now better why Phive chose to go that way.

As a side-topic: I think people are lazy and in most cases, they won't validate the fingerprint of the GPG key. In that case, the SHA-x sums would give a slightly better sense of security, however, this is a totally different topic.

(Edit: I have this vague feeling that I sound like a-hole in the paragraph above; if yes, I'm sorry - that's not what I meant)

Thank you!