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

Add Support Cryptographic Signatures with Public Key Pinning #4022

Open
sarciszewski opened this issue May 12, 2015 · 30 comments
Open

Add Support Cryptographic Signatures with Public Key Pinning #4022

sarciszewski opened this issue May 12, 2015 · 30 comments

Comments

@sarciszewski
Copy link

Please read these first

The purpose of this Github issue is to propose a movement towards enabling package maintainers to publish their own OpenSSL signatures via Composer, should they want to.

New optional property for composer.json

I'd like to propose a new composer.json property called "security". It will have the following properties:

  • contact which could contain an array of contact information options for reporting security vulnerabilities
  • publisher should contain an array of authorized publishers and the SHA-256 fingerprints of their public keys (e.g. openssl)

Example

{
    "name": "some_author/myproject",
    "security": {
        "contact": [
              {
                   "email": "security@example.com",
                   "pgpkey": "89F7B8300E87E03C52B05289926BC5171CDEA439",
              }
        ],
        "publishers": [
            {
                "name": "our_publishing_key",
                "public_keys": [
                    {
                        "key": "someRSApublickeyhere",
                        "sha256": "i4a+yBCeboJ2W4kYSQ1DoxUEK00OUpQ0dE6lw1K5XUk=",
                        "sha1": "XijzBWQ2WjqfEprXBu6TRkCUolI="
                    },
                    {
                        "key": "someOtherRSAPublickeyhere",
                        "sha256": "hCTafmUcyOYtvhO4ENY/U5v1pTK1iq+5YHtRnfiGpAk=",
                        "sha1": "xVY8xokHfHi1GSpm8fugZJsLInw="
                    }
                ]
            }
        ]
    }
}

How it should be used

When a package opts to specify their own public keys, Composer should be able to verify signatures on the client's side. Packagist may also benefit from tracking which projects offer digital signatures.

This idea is just a draft. I'd like to know what the Composer team and PHP community wants before I even think about writing a pull request.

@indeyets
Copy link

👍

@padraic
Copy link
Contributor

padraic commented May 17, 2015

@sarciszewski I did some prototyping in this area a while back. While it's likely not aged well against the Composer public API, you can view the new classes and commands.

Branch: https://github.com/padraic/composer/tree/developer-signatures
Compare: master...padraic:developer-signatures

It uses a model where the signing keys are authorised using one or more offline root keys, i.e. allowing a lead to delegate signing to other maintainers or sets of online keys. Tracked in a keys.json file. The signature is made against a manifest of files.

Two tricky parts...

  1. Files included on the manifest need to be standardised. This was problematic at the time using Composer archive classes mixed with git. Composer does have a specific set of classes for this already which I was reusing, but they were in flux at the time.
  2. JSON data being JSON, it needs to canonicalised reliably across clients but has no native capacity for this. I was using the very simple Bencode which was the actual data form being signed.

Maybe this will all offer some inspiration or food for discussion and, by all means, borrow and steal as needed.

@alcohol
Copy link
Member

alcohol commented Aug 19, 2015

This might also be related to #38, and to a lesser degree, #1074.

@paragonie-scott
Copy link

@padraic Since your branch is mostly additions, it shouldn't be too much work to rebase against upstream/master.

@Seldaek Seldaek added this to the Later milestone Apr 18, 2016
blackcoder87 referenced this issue in IlchCMS/Ilch-2.0 Aug 18, 2016
…ries loaded with composer, PHP -> 5.5 (already used in many files)
@rugk
Copy link

rugk commented Oct 17, 2016

Any news here? I think adding support for verifying the downloaded files cryptographically would be a nice thing.
In this case there just remains one question: How is composer.json verified?

@alcohol
Copy link
Member

alcohol commented Oct 18, 2016

@rugk It is not. Everything we do is totally insecure and will explode in our faces any day now. Any day now...

On a serious note though; security is nice and all that, but if it detracts from usability and ease of access, it could end up causing users to turn away from their tooling instead. No users, no need for the tool. No need for the tool, no security needed.

I wonder if some form of security could be obtained through a Composer plugin, thereby making it completely optional. Also, not yet-another-feature we would have to maintain.

@paragonie-scott
Copy link

I wonder if some form of security could be obtained through a Composer plugin, thereby making it completely optional. Also, not yet-another-feature we would have to maintain.

Unless it was an enabled-by-default plugin, most people would never use such a feature.

Regardless, doing it right is a nontrivial problem and I'd be skeptical of any implementations before libsodium becomes a core extension and PHP < 7.2 (or whenever libsodium's adoption arrives) is widely EOL'd.

@alcohol
Copy link
Member

alcohol commented Oct 18, 2016

@paragonie-scott every plugin is enabled by default, if you install it.

@paragonie-scott
Copy link

But it's not installed by default. :)

@andrewhowdencom
Copy link

Looking to establish a chain of verification for our software supply, for which this is a requirement. If anyone is keen on working on this, I promise you it'll be appreciated!

@rugk
Copy link

rugk commented Nov 17, 2016

Maybe we could first get rid of the "low-prio/controversial" milestone? 😃

Security should never be "low-prio"…

@alcohol
Copy link
Member

alcohol commented Nov 17, 2016

@rugk Unfortunately, we (@composer team) have only limited experience in regards to security as far as this topic goes. Hence, it is low priority for us personally. We are open to discussions and contributions (discuss before contributing please) though!

@dzuelke
Copy link
Contributor

dzuelke commented Nov 17, 2016

The problem is not the implementation, the problem is the key/signing infrastructure...

@alcohol
Copy link
Member

alcohol commented Nov 17, 2016

Isn't that part of the implementation? :p

@paragonie-scott
Copy link

You could implement this in an hour with openssl_sign() and openssl_verify(). The problem is: which public key to trust, how to verify these weren't silently replaced, etc.

@andrewhowdencom
Copy link

andrewhowdencom commented Nov 17, 2016

@sarciszewski Perhaps this is a naive question, but can you do that out of band? Perhaps store "trusted" public keys in local composer configuration on the machine, or something.

Edit: I'd even consider just keeping the trusted public keys in composer.json, if that were some how possible and not insane.

Edit: This seems be the idea of the original author. I should read closer.

(My experience is also limited! I only know the concepts.)

@andrewhowdencom
Copy link

andrewhowdencom commented Jan 16, 2017

Similar work being carried out on Wordpress. https://ma.ttias.be/wordpress-get-secure-cryptographic-updates/

@Ocramius
Copy link
Contributor

For those tracking this, I started a brutally simple implementation at https://github.com/Roave/composer-gpg-verify, which relies on the GPG keyring and the fact that packages are downloaded with GIT (which includes signing/verification mechanisms out of the box).

It's still a bit raw, but the idea is to first make it work reliably, then move it to composer once it's "ready for everyone".

@robolmos
Copy link

Bump for 2019

@Ocramius
Copy link
Contributor

@robolmos bumping on OSS is basically asking for being scolded.

Please take the above suggestions and get involved yourself in first place instead.

@DiveRightIn
Copy link

@Ocramius @robolmos Take it offline.

@mpdude
Copy link
Contributor

mpdude commented Dec 28, 2019

In which cases do signatures add value over downloading the .zip files generated by GitHub over HTTPS?

If someone breaks into the maintainer's GitHub account and modifies code? Would it then require that maintainers build and sign releases personally/on their local machines?

If someone manages to tamper data fed to Packagist.org (webhooks?) or hijacks/breaks into your Packagist account?

If someone manages to forge HTTPS certificates?

@mpdude
Copy link
Contributor

mpdude commented Dec 28, 2019

The blog post from the initial comment seems to be no longer available but has been archived at https://web.archive.org/web/20150304203959/http://blog.astrumfutura.com/2015/03/securely-distributing-phars-pitfalls-and-solutions/.

Regarding Symfony and Fabien Potenciers article, the repo hosting the checksums is no longer available, at least not at the address mentioned in the blog.

So, as to the feature discussed here: Would it be a step in the right direction if...

  • package maintainers could include in their composer.json the URL where a detached, armored GPG signature for the dist version of their package can be found

  • that URL can contain a placeholder for the version that Composer decides to use

  • end users could specify in their root composer.json file which GPG key id (and optionally, which key server to) to trust for which package, optionally supporting wildcards for entire vendor/* namespaces,

  • Composer and/or a plug-in like the one from @Ocramius would maintain a GPG keyring in the vendor/composer folder, fetching the relevant keys

  • dist packages are verified after being downloaded, before unpacking, using the specified key,

  • for source packages using git, release tags are verified,

  • Composer would hint at install/update etc. for which packages “signature-URLs” are known, to promote/honor the practice of signing releases,

  • whether to accept only signed packages, abort on invalid signatures only, ignore signatures altogether etc. is left to the user through command line switches?

@paragonie-security
Copy link

In which cases do signatures add value over downloading the .zip files generated by GitHub over HTTPS?

HTTPS is HTTP over TLS. TLS is Transport Layer Security (emphasis ours).

What this means is that information is protected (confidentiality, integrity, authenticity) in transit. There is no integrity/authenticity protections for the data on the server.

What this means in practice is that an attacker capable of compromising a webserver can launch targeted malware attacks (e.g. what almost happened to WordPress).

That is why you need offline cryptographic signatures instead of "just" using HTTPS. (You want to do this in addition to using HTTPS. It's not an either/or scenario.)

Would it be a step in the right direction if...

Any solution that relies on GPG in 2020 (which is nearly upon us) should be discouraged in favor of modern tooling.

Paragon Initiative Enterprises is working on an important piece of the puzzle right this moment. When our library is complete, our intention is to update this ticket with instructions (which link to supporting material) for solving this problem. We want to make it as easy as possible for everyone.

@mpdude
Copy link
Contributor

mpdude commented Jan 2, 2020

I've tried to read up a bit on the topic and I must say that the challenge appears to be so big it is daunting.

In the one corner, there's GPG.

A tool with plenty of problems, also described as "90s crypto". With creepy UX. With no real native PHP support so we'd need to resort to having a command line version installed and doing system() calls. With a Web of Trust with severe design deficiencies and questionable GDPR compliance. With keyservers written in arcane programming languages and with design choices that make the network so vulnerable that it currently can be maintained in a very reduced form only and that even requires patches to GPG to make it accept some of the stripped-down keys provided.

Yet, it still seems to be the de-facto tool used by many Linux distros to sign their releases. It's the solution that at least Git provides some kind of support or integration for. It allows to use offline master keys to issue, authorize and revoke signing subkeys. The infrastructure (keyservers) to publish that information seems to be available, also if it is unclear to me if it would be scalable enough if it would be queried for keys every time somebody runs composer install or update.

In the other corner:

A collection of (partly ad-hoc?) solutions like using OpenSSL signatures the way Composer itself does. Or using something like Signify or Minisign.

For all those, there is no clear idea how and where the public keys, possibly subkeys (dealing with a team of maintainers?) and revocations could be published in a secure, auditable and authority-free manner.

And all that does not even try to address features like Userbase Consistency Validation.

IMO, Composer was also so successful because it made releasing packages that easy – just git tag and you're done (or can be done). Does anyone still remember what it took to bundle and publish a PEAR package?

If you take that as a baseline, anything that involves signatures and/or "crypto stuff" will multiply the work it takes for package maintainers to craft a release. At least, there would have to be some command to wrap up creating the signature and having a place to publish it.

Probably not an issue for the major projects that have good release processes in place, but possibly a no-go for the broad majority of FOSS packages out there maintained by people just trying to learn how to do things "the right way":tm:.

Paragon Initiative Enterprises is working on an important piece of the puzzle right this moment. When our library is complete, our intention is to update this ticket with instructions (which link to supporting material) for solving this problem. We want to make it as easy as possible for everyone.

I really value and appreciate the work and contributions you folks at PIE have done for the PHP community. So please don't get me wrong – but can we just wait for you to come up with a working implementation of a cryptographically secure, append-only log, a blockchain or similar?

Who is supposed to run and maintain all this, as a distributed system, at the necessary scale and reliability? Jordi and Niels? Even if it were as simple as downloading and running some P2P software, who would do it and why – what value and incentive would the average PHP user see in doing that? An abstract increase in "security in general"?

Operations and marketing aside, can we really build an architecture that sophisticated here at github.com/composer? Does it need to be an effort of the PHP community/ecosystem as a whole? Can we do without bigger entities/corporations providing support/funding somehow, without the solution becoming a proprietary product?

Is The Update Framework something we could piggy-back onto? Can it mostly provide conceptual guidance, or also enough implementation parts useful in the PHP environment? Free and working infrastructure that would make it worthwhile? And most of it all, would it allow us to come to solutions that are usable for a broad majority of the PHP community, also when doing things for fun and not for profit?

If it would help to get things along, I'd dare to go out to a local user group meeting tonight or step up on a conference stage and try to convince people why it would be worth learning about all this complicated crypto stuff. But that would require a credible narrative and a clear idea of where we're heading to... If more GPG-signed Git commits would help, let's preach that. But if not, what else...?

🤷🏻‍♂️

Update: https://core.trac.wordpress.org/ticket/39309#comment:89 is where signatures for the Wordpress core are discussed; basically read it from that comment on downwards. The challenges regarding key distribution are the same, and they're not even trying (to my understanding) to make this feature available to every theme and plugin developer but just for the core. Composer would have to do support signing keys, revocation and possibly rotation for every single vendor/provider.

@paragonie-security
Copy link

paragonie-security commented Jan 2, 2020

I've tried to read up a bit on the topic and I must say that the challenge appears to be so big it is daunting.

It's generally ill-advised to try to deep dive into a complicated problem space-- even ones without cryptography involved-- in one sitting.

The problems being solved here are like a Matryoshka doll of increasing complexity, but the end user experience won't require anyone to actually understand any of it if they don't want to.

How many cryptocurrency users understand how k-value reuse affects ECDSA security?

In the one corner, there's GPG.

A tool with plenty of problems, also described as "90s crypto". With creepy UX. With no real native PHP support so we'd need to resort to having a command line version installed and doing system() calls. With a Web of Trust with severe design deficiencies and questionable GDPR compliance. With keyservers written in arcane programming languages and with design choices that make the network so vulnerable that it currently can be maintained in a very reduced form only and that even requires patches to GPG to make it accept some of the stripped-down keys provided.

We agree with Latacora's assessment that PGP (OpenPGP, GnuPG, etc.) is a bad solution. The PHP-specific issues do make matters worse for anyone interested in pursuing PGP solutions, but if you discount PGP wholesale, they cease to matter.

This may sound obvious, but keep in mind: Eliminating the irrelevant is important for reducing cognitive load, which is imperative for making complex problem spaces less daunting.

Yet, it still seems to be the de-facto tool used by many Linux distros to sign their releases.

Due to historical reasons, not technical merits.

It's the solution that at least Git provides some kind of support or integration for.

Due to historical reasons, not technical merits.

It allows to use offline master keys to issue, authorize and revoke signing subkeys. The infrastructure (keyservers) to publish that information seems to be available, also if it is unclear to me if it would be scalable enough if it would be queried for keys every time somebody runs composer install or update.

PGP's keyserver infrastructure isn't great.

In the other corner:

A collection of (partly ad-hoc?) solutions like using OpenSSL signatures the way Composer itself does. Or using something like Signify or Minisign.

This isn't a 1v1, though.

Signify/Minisign are cool, but they assume and out-of-band public key distribution mechanism which largely reduces to trust on first use without any audit trail.

For all those, there is no clear idea how and where the public keys, possibly subkeys (dealing with a team of maintainers?) and revocations could be published in a secure, auditable and authority-free manner.

Correct for PGP and ad-hoc OpenSSL-based signature proposals.

And all that does not even try to address features like Userbase Consistency Validation.

IMO, Composer was also so successful because it made releasing packages that easy – just git tag and you're done (or can be done). Does anyone still remember what it took to bundle and publish a PEAR package?

If you take that as a baseline, anything that involves signatures and/or "crypto stuff" will multiply the work it takes for package maintainers to craft a release. At least, there would have to be some command to wrap up creating the signature and having a place to publish it.

Correct, there would have to be. And our final proposal will include such machinations.

Probably not an issue for the major projects that have good release processes in place, but possibly a no-go for the broad majority of FOSS packages out there maintained by people just trying to learn how to do things "the right way"™️.

Paragon Initiative Enterprises is working on an important piece of the puzzle right this moment. When our library is complete, our intention is to update this ticket with instructions (which link to supporting material) for solving this problem. We want to make it as easy as possible for everyone.

I really value and appreciate the work and contributions you folks at PIE have done for the PHP community. So please don't get me wrong – but can we just wait for you to come up with a working implementation of a cryptographically secure, append-only log, a blockchain or similar?

You mean like Chronicle? That's one of the underpinnings of the Gossamer PKI, which is how we intend to solve this problem at scale.

Who is supposed to run and maintain all this, as a distributed system, at the necessary scale and reliability? Jordi and Niels? Even if it were as simple as downloading and running some P2P software, who would do it and why – what value and incentive would the average PHP user see in doing that? An abstract increase in "security in general"?

At a super high-level overview, our plan for 2020 is as follows:

  1. Do Gossamer things.
    • It doesn't really matter for the sake of this discussion what those things are, only that they need to be done before we move onto step two. We'll discuss them elsewhere. At some point we're going to be doing game theory simulations in another repository.
  2. Create a Composer plugin that includes a release command, a verify command, and a concept of a "verification policy" (e.g. default-require, default-optional, and a list of exclusions for either ruleset) to be dropped into composer.json.
  3. Send a pull request to Packagist, which contains the necessary window-dressing to get a Gossamer-backed public key/update distribution channel up and running.
  4. Do real world testing with the currently-optional Composer plugin.
  5. Design and open source training material, workshops, laboratory projects, etc. for getting PHP developers used to signing/verifying releases, or configuring their projects to require all dependencies be signed.
  6. Once everyone is happy with the security, UX, performance, and availability: make the plugin a core feature of Composer, hopefully in version 2.0.0.
    • The default policy will be lax as we onboard the entire ecosystem. We have no illusions of that not taking many years to accomplish.
  7. Eventually switch the default to "enforce", probably in Composer 3.0.0.
  8. At some point between points 6 and 7, we'll be working with NIST to deliver post-quantum secure signatures to a future version of libgossamer.

The amount of work for Jordi and Niels to support the changes for Packagist will be minimal: Setup a Chronicle instance on a server, run a script to populate it with initial seed data, merge a pull request. The rest of the launch work should be done already, and most of the ongoing maintenance work will be minimal (e.g. making sure they have adequate disk space).

Operations and marketing aside, can we really build an architecture that sophisticated here at github.com/composer? Does it need to be an effort of the PHP community/ecosystem as a whole? Can we do without bigger entities/corporations providing support/funding somehow, without the solution becoming a proprietary product?

Yes, we can.

Those words might seem hollow coming from the account of a for-profit company.

The entire point of Gossamer is to be a FLOSS solution that doesn't hinder FLOSS workflows or step on FLOSS values.

The reason the PKI exists is to ensure developers control their own signing keys, and if any government wants to introduce a stealth backdoor, they can't. (Especially if they want to introduce a targeted, stealth backdoor.)

Is The Update Framework something we could piggy-back onto?

We like TUF, but it doesn't address the scale we need to operate at. Public key distribution is a larger problem.

Can it mostly provide conceptual guidance, or also enough implementation parts useful in the PHP environment?

There are several reasons we're building libgossamer as a standalone project, rather than a monolith, but mostly:

  1. We want it to be easily forked and replaced, should the community deem it necessary.
  2. We want it to be useful for many different projects.
    • Though we're focusing on WordPress and Composer out of the gate, there are certainly several message board or content management systems that provide their own plugin marketplace that would benefit from a standalone library and several reference implementations.
  3. We want it to be easily ported to other languages.
    • This isn't just a strategic thing where we want to make secure updates the rule rather than the exception, regardless of programming language or framework (though that is true).
    • We eventually want anyone to be able to write developer tools in any language, for any other language, without having to write a line of crypto code themselves.
    • We also want it to be drop-dead simple to verify other ecosystems (e.g. an AWS lambda function in Java that verifies the entire ledger for PHP or Node.js).

Free and working infrastructure that would make it worthwhile?

Free for whom?

Our plan is to make this cost developers $0, and to be freely available without restriction.

We can't promise that there will be a $0 infrastructure cost. There's always a cost (even insignificant) to adding code to any project, whether you see it or not.

And most of it all, would it allow us to come to solutions that are usable for a broad majority of the PHP community, also when doing things for fun and not for profit?

Absolutely.

If it would help to get things along, I'd dare to go out to a local user group meeting tonight or step up on a conference stage and try to convince people why it would be worth learning about all this complicated crypto stuff. But that would require a credible narrative and a clear idea of where we're heading to... If more GPG-signed Git commits would help, let's preach that. But if not, what else...?

🤷🏻‍♂️

We're still in the process of working on libgossamer. Our proposal for Composer/Packagist is yet to come, but will land in early 2020 and hopefully be discussed to the point of satisfaction before the year is over.

Update: https://core.trac.wordpress.org/ticket/39309#comment:89 is where signatures for the Wordpress core are discussed; basically read it from that comment on downwards. The challenges regarding key distribution are the same,

Very similar, yes.

and they're not even trying (to my understanding) to make this feature available to every theme and plugin developer but just for the core.

That's not quite correct.

  • WP Trac 39309 is about core update signing.
  • Theme/Plugin signing is going to be a future ticket, once we're ready to move forward.

Composer would have to do support signing keys, revocation and possibly rotation for every single vendor/provider.

Rotation doesn't buy you much, but Gossamer supports revocation for both signing keys and updates. It even has a concept of a "super provider" which can act on behalf of all users (but cannot bypass ledger validation).

@mpdude
Copy link
Contributor

mpdude commented Jan 2, 2020

Any chance we can attack this with a "think big start small" mindset?

What if, for example, maintainers with a packagist.com account could manage their public signing keys there? Keys could be valid for their vendor/ namespace prefix, and we could have some kind of public "info" page where all the keys added and revoked for a particular account could be seen.

Sure, that's not the same as the full-scale Gossamer solution and yes, there are probably a dozen of attack methods and things that may still be exploited. But wouldn't that solution still be better than what we currently have?

I mean, at least we could have separate accounts on different platforms (at packagist.com and GitHub.com for most users) where keys and/or code would be managed.

Packagist has to pull and scan source repos anyway; so it could also fetch a signatures file from the repo (maybe always committed on the master branch?) and include those in the index and/or make them somehow available. Not end-2-end solution, obviously, but again, better than nothing?

Maybe that way we could start with simple tools and raise awareness for the topic, and slowly get everybody used to what is necessary? If everybody learns how to use a particular command or tool to sign their releases, and they manage their keys on Packagist, we could at a later time still move the lower-level parts to a platform like the one you devise. As long as the end-user experience remains consistent and we don't scrap all the tools and processes we've promoted, most people should be fine with that.

So what do you think – can we get X% of the security level for Y% of the work, with X > Y or even X >> Y?

@alcohol
Copy link
Member

alcohol commented Jun 10, 2021

On this subject, https://sigstore.dev/ could also be interesting to keep an eye on.

@effulgentsia
Copy link
Contributor

Is The Update Framework something we could piggy-back onto? Can it mostly provide conceptual guidance, or also enough implementation parts useful in the PHP environment?

FYI that for Drupal we've been working on https://github.com/php-tuf/php-tuf (a PHP implementation of the TUF client library) and https://github.com/php-tuf/composer-integration (a Composer plugin that uses that PHP-TUF library to validate files downloaded by Composer). Neither is ready for production use yet, but we're working on getting it there.

Those client libraries only work if the package repository implements the server-side portion of the TUF spec. We're currently working on testing and deploying Rugged to drupal.org, which provides the package repositories for Drupal packages. If Packagist were interested in deploying Rugged (or a different TUF implementation) to packagist.org, that would be fabulous for Drupal (since Drupal also depends on Symfony and other components on Packagist), but I'm not qualified to say whether or not that's the right solution for Packagist.

I skimmed, but haven't yet fully processed, all of the comments on this issue, to learn more about where the overlaps and differences are between TUF and the other proposals here. I don't know when I'll have the time to do that, but I thought I'd write this comment here before doing that, in case this info is helpful to anyone.

@stof
Copy link
Contributor

stof commented Oct 3, 2023

Given that Packagist does not serve the package files but only the metadata, is it even feasible to implement TUF ?

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

No branches or pull requests