Skip to content

Implement signed index support #308

@zooba

Description

@zooba

We want to be able to validate that at least our python.org index has not been tampered with, while not excluding other sources from providing their own index (e.g. by requiring that they have access to our certificates, or even their own).

My proposed approach:

  • add install.source_settings config that contains a mapping from source URL to additional settings
  • add settings for requires_signature, required_root_subject, required_publisher_subject, required_publisher_eku1. Also add these to the schema for feeds, though we won't be using them for the python.org feeds
  • set these settings by default for our default feed URL. Absent by default for custom feeds
  • when accessing a feed, we add .p7s to its URL to get a detached Authenticode signature
  • if the feed requires_signature and the signature file is missing, does not validate against the OS's certificate store, or does not match the other settings, we print a warning prompt before processing it. This prompt defaults to "no/abort", and if confirm=False then it always aborts
  • if the signature is valid, we print a prominent "validated" message, so that if it ever goes missing it should be fairly obvious to users that something has changed
  • if the feed has no settings, we parse it and look for its own requirements, then reprocess as above.
  • feeds without a requires_signature get a subtle warning - something like "skipping verification". This is to help discoverability of the feature for custom feed owners, without making it seem like an unverified feed is inherently problematic

The aim is to allow us to have secure default settings for the vast majority of our users, without turning the install manager into a proprietary downloader. We embed our certificate details in the client to make it more difficult for an attacker to remove the specification, but allow referencing them from the feed to allow downstreams to more easily enable their own checks. We require OS verification to handle certificate revocation, rather than trying to do it ourselves, but allow (optional) restricting the certificate to prevent an attacker switching the client's expectations. We use Authenticode rather than another mechanism because our code signing certificate is our best protected secret, and so the level of trust matches between the binaries we provide and our index.

And just to be clear, there is no evidence that anyone has attempted to hijack our index, and this issue is not motivated by any recent reports towards Python. It is motivated by our assessment of the ecosystem right now, and the fact that multiple recent supply chain attacks have targeted download pages and tools of popular software, and so (along with other procedural measures), we want to make sure that Python stays ahead of the attackers.

Footnotes

  1. The EKU is an identifying marker added by Azure Trusted Signing that lets us use their root certificate name and our EKU to validate

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions