PEP 480 – Überstehen eines PyPI-Kompromisses: Ende-zu-Ende-Signierung von Paketen
- Autor:
- Trishank Karthik Kuppusamy <karthik at trishank.com>, Vladimir Diaz <vladimir.diaz at nyu.edu>, Justin Cappos <jcappos at nyu.edu>, Marina Moore <mm9693 at nyu.edu>
- BDFL-Delegate:
- Donald Stufft <donald at stufft.io>
- Discussions-To:
- Discourse thread
- Status:
- Entwurf
- Typ:
- Standards Track
- Thema:
- Packaging
- Benötigt:
- 458
- Erstellt:
- 08-Okt-2014
Inhaltsverzeichnis
- Zusammenfassung
- PEP Status
- Begründung
- Bedrohungsmodell
- Definitionen
- Maximale Sicherheitsmodell
- Ende-zu-Ende-Signierung
- Metadatensignaturen, Schlüsselverwaltung und Signierung von Distributionen
- Analyse von Schlüsselkompromittierungen
- Anhang A: PyPI Build Farm und Ende-zu-Ende-Signierung
- Referenzen
- Danksagungen
- Urheberrecht
Zusammenfassung
Es wird eine Erweiterung zu PEP 458 vorgeschlagen, die Unterstützung für Ende-zu-Ende-Signierung und das maximale Sicherheitsmodell hinzufügt. Ende-zu-Ende-Signierung ermöglicht es sowohl PyPI als auch Entwicklern, die von Clients heruntergeladenen Distributionen zu signieren. Das von PEP 458 vorgeschlagene minimale Sicherheitsmodell unterstützt die kontinuierliche Bereitstellung von Distributionen (da sie mit Online-Schlüsseln signiert werden), aber dieses Modell schützt die Distributionen nicht im Falle eines Kompromittierung von PyPI. Im minimalen Sicherheitsmodell können Angreifer, die die auf der PyPI-Infrastruktur gespeicherten Signierschlüssel kompromittiert haben, bösartige Distributionen signieren. Das in diesem PEP beschriebene maximale Sicherheitsmodell behält die Vorteile von PEP 458 bei (z. B. sofortige Verfügbarkeit von auf PyPI hochgeladenen Distributionen), stellt aber zusätzlich sicher, dass Endbenutzer nicht dem Risiko ausgesetzt sind, gefälschte Software zu installieren, falls PyPI kompromittiert wird.
Dieses PEP erfordert einige Änderungen an der PyPI-Infrastruktur und einige vorgeschlagene Änderungen für Entwickler, die an der Ende-zu-Ende-Signierung teilnehmen möchten. Diese Änderungen umfassen die Aktualisierung des Metadaten-Layouts von PEP 458, um Delegationen an Entwicklerschlüssel aufzunehmen, das Hinzufügen eines Prozesses zur Registrierung von Entwicklerschlüsseln bei PyPI und eine Änderung des Upload-Workflows für Entwickler, die Ende-zu-Ende-Signierung nutzen. Alle diese Änderungen werden später in diesem PEP detailliert beschrieben. Paketmanager, die Ende-zu-Ende-Signierung nutzen möchten, müssen keine zusätzlichen Arbeiten über das hinaus leisten, was für den Konsum der in PEP 458 beschriebenen Metadaten erforderlich ist.
Dieses PEP diskutiert die Änderungen, die an PEP 458 vorgenommen wurden, schließt jedoch dessen informative Elemente aus, um sich hauptsächlich auf das maximale Sicherheitsmodell zu konzentrieren. Zum Beispiel werden ein Überblick über The Update Framework oder die grundlegenden Mechanismen in PEP 458 hier nicht behandelt. Die Änderungen an PEP 458 umfassen Modifikationen am Snapshot-Prozess, an der Analyse von Schlüsselkompromittierungen, am Auditing von Snapshots und an den Schritten, die im Falle einer PyPI-Kompromittierung unternommen werden sollten. Der Signierungs- und Schlüsselverwaltungsprozess, den PyPI EMPFEHLEN KANN, wird diskutiert, aber nicht streng definiert. Wie der Release-Prozess zur Verwaltung von Schlüsseln und Metadaten implementiert werden sollte, bleibt den Implementierern der Signierungstools überlassen. Das heißt, dieses PEP legt den erwarteten kryptografischen Schlüsseltyp und das Signaturformat fest, die von Entwicklern hochgeladen werden MÜSSEN, um die Ende-zu-Ende-Verifizierung von Distributionen zu unterstützen.
PEP Status
Die Community diskutierte dieses PEP von 2014 bis 2018. Aufgrund des für die Implementierung dieses PEP erforderlichen Arbeitsaufwands wurde die Diskussion bis nach der Genehmigung für den Vorläuferschritt in PEP 458 verschoben. Mitte 2020 ist PEP 458 genehmigt und die Implementierung ist im Gange, und die PEP-Autoren streben die Genehmigung an, um die entsprechende Finanzierung für die Implementierung zu sichern.
Begründung
PEP 458 schlägt vor, wie PyPI mit The Update Framework (TUF) [2] integriert werden sollte. Es erklärt, wie moderne Paketmanager wie pip sicherer gemacht werden können und welche Arten von Angriffen verhindert werden können, wenn PyPI serverseitig geändert wird, um TUF-Metadaten einzuschließen. Paketmanager können auf die auf PyPI verfügbaren TUF-Metadaten verweisen, um Distributionen sicherer herunterzuladen.
PEP 458 beschreibt auch das Metadaten-Layout des PyPI-Repositorys und verwendet das minimale Sicherheitsmodell, das die kontinuierliche Bereitstellung von Projekten unterstützt und Online-Kryptografieschlüssel zur Signierung der von Entwicklern hochgeladenen Distributionen verwendet. Obwohl das minimale Sicherheitsmodell gegen die meisten Angriffe auf Software-Aktualisierungsprogramme schützt [5] [6], kann es verbessert werden, um Ende-zu-Ende-Signierung zu unterstützen und gefälschte Distributionen im Falle einer Kompromittierung von PyPI zu verbieten.
PEP 480 baut auf PEP 458 auf, indem es Unterstützung für die Entwicklersignierung hinzufügt und die Abhängigkeit von Online-Schlüsseln reduziert, um bösartige Distributionen zu verhindern. Die Hauptstärke von PEP 458 und dem minimalen Sicherheitsmodell ist der automatisierte und vereinfachte Release-Prozess: Entwickler können Distributionen hochladen und dann ihre Distributionen von PyPI signieren lassen. Ein Großteil des Release-Prozesses wird durch Online-Rollen automatisiert gehandhabt, und dieser Ansatz erfordert die Speicherung kryptografischer Signierschlüssel auf der PyPI-Infrastruktur. Leider sind kryptografische Schlüssel, die online gespeichert werden, anfällig für Diebstahl. Das in diesem PEP vorgeschlagene maximale Sicherheitsmodell erlaubt es Entwicklern, die von ihnen für PyPI-Benutzer bereitgestellten Distributionen zu signieren und setzt Endbenutzer nicht dem Risiko aus, bösartige Distributionen herunterzuladen, wenn die auf der PyPI-Infrastruktur gespeicherten Online-Schlüssel kompromittiert werden.
Bedrohungsmodell
Das Bedrohungsmodell geht von Folgendem aus:
- Offline-Schlüssel sind sicher und werden sicher gespeichert.
- Angreifer können mindestens einen der vertrauenswürdigen Online-Schlüssel von PyPI kompromittieren, und zwar entweder gleichzeitig oder über einen Zeitraum hinweg.
- Angreifer können auf Client-Anfragen reagieren.
- Angreifer können beliebig viele Entwicklerschlüssel für Projekte kontrollieren, die ein Client nicht installieren möchte.
Angreifer gelten als erfolgreich, wenn sie einen Client dazu bringen können, eine andere als die aktuellste Version der Software zu installieren (oder installiert zu lassen), die der Client aktualisiert. Wenn ein Angreifer die Installation von Updates verhindert, ist sein Ziel, dass Clients nicht merken, dass etwas schiefgelaufen ist.
Definitionen
Die Schlüsselwörter „MUSS“, „DARF NICHT“, „ERFORDERLICH“, „SOLL“, „SOLL NICHT“, „EMPFOHLEN“, „KANN“ und „OPTIONAL“ in diesem Dokument sind wie in RFC 2119 beschrieben zu interpretieren.
Dieses PEP konzentriert sich auf die Integration von TUF mit PyPI; der Leser wird jedoch ermutigt, sich über die Designprinzipien von TUF zu informieren [2]. Es wird auch EMPFOHLEN, dass der Leser mit der TUF-Spezifikation [3] und PEP 458 (das dieses PEP erweitert) vertraut ist.
Die in diesem PEP verwendeten Begriffe sind im Python Packaging Glossary [4] definiert: *Projekt*, *Release*, *Distribution*.
Die in diesem PEP verwendeten Begriffe werden wie folgt definiert:
- Distributionsdatei: Eine versionierte Archivdatei, die Python-Pakete, Module und andere Ressourcendateien enthält, die zur Verteilung eines Releases verwendet werden. Die Begriffe *Distributionsdatei*, *Distributionspaket* [4] oder einfach *Distribution* oder *Paket* können in diesem PEP austauschbar verwendet werden.
- Simple Index: Die HTML-Seite, die interne Links zu Distributionsdateien enthält.
- Target-Dateien: Als Faustregel gelten Target-Dateien alle Dateien auf PyPI, deren Integrität mit TUF garantiert werden sollte. Typischerweise sind dies Distributionsdateien und PyPI-Metadaten wie Simple Indices.
- Rollen: Rollen in TUF umfassen die Menge der Aktionen, zu denen eine Partei berechtigt ist, einschließlich dessen, welche Metadaten sie signieren darf und für welche Pakete sie verantwortlich ist. Es gibt eine *Root*-Rolle in PyPI. Es gibt mehrere Rollen, deren Verantwortlichkeiten direkt oder indirekt von der *Root*-Rolle delegiert werden. Der Begriff „Top-Level-Rolle“ bezieht sich auf die *Root*-Rolle und jede von der *Root*-Rolle delegierte Rolle. Jede Rolle hat eine einzelne Metadatendatei, für die sie vertrauenswürdig ist.
- Metadaten: Metadaten sind Dateien, die Rollen, andere Metadaten und Target-Dateien beschreiben.
- Repository: Ein Repository ist eine Ressource, die aus benannten Metadaten und Target-Dateien besteht. Clients fordern Metadaten und Target-Dateien an, die in einem Repository gespeichert sind.
- Konsistenter Snapshot: Eine Sammlung von TUF-Metadaten und Target-Dateien, die den vollständigen Zustand aller Projekte auf PyPI zu einem bestimmten Zeitpunkt erfassen.
- Entwickler: Der Besitzer oder Betreuer eines Projekts, der berechtigt ist, TUF-Metadaten sowie Distributionsmetadaten und -dateien für ein bestimmtes Projekt zu aktualisieren.
- Online-Schlüssel: Ein privater kryptografischer Schlüssel, der auf der PyPI-Serverinfrastruktur gespeichert sein MUSS. Dies ermöglicht normalerweise die automatisierte Signierung mit dem Schlüssel. Ein Angreifer, der die PyPI-Infrastruktur kompromittiert, kann diese Schlüssel sofort lesen.
- Offline-Schlüssel: Ein privater kryptografischer Schlüssel, der unabhängig von der PyPI-Serverinfrastruktur gespeichert sein MUSS. Dies verhindert die automatisierte Signierung mit dem Schlüssel. Ein Angreifer, der die PyPI-Infrastruktur kompromittiert, kann diesen Schlüssel nicht sofort lesen.
- Schwellenwert-Signaturverfahren: Eine Rolle kann ihre Widerstandsfähigkeit gegen Schlüsselkompromittierungen erhöhen, indem sie festlegt, dass mindestens t von n Schlüsseln erforderlich sind, um ihre Metadaten zu signieren. Eine Kompromittierung von t-1 Schlüsseln reicht nicht aus, um die Rolle selbst zu kompromittieren. Wenn angegeben wird, dass eine Rolle (t, n) Schlüssel benötigt, beschreibt dies die Schwellenwert-Signatur-Eigenschaft.
Maximale Sicherheitsmodell
Das maximale Sicherheitsmodell ermöglicht es Entwicklern, ihre Projekte zu signieren und signierte Metadaten auf PyPI hochzuladen. In dem in diesem PEP vorgeschlagenen Modell wären Angreifer, falls die PyPI-Infrastruktur kompromittiert würde, nicht in der Lage, bösartige Versionen eines *beanspruchten* Projekts zu servieren, ohne Zugriff auf den Entwicklerschlüssel dieses Projekts zu haben. Abbildung 1 zeigt die Änderungen am Metadaten-Layout des minimalen Sicherheitsmodells, nämlich dass Entwicklerrollen nun unterstützt werden und drei neue delegierte Rollen existieren: *claimed* (beansprucht), *recently-claimed* (kürzlich beansprucht) und *unclaimed* (unbeansprucht). Die Rolle *bins* aus dem minimalen Sicherheitsmodell wurde in *unclaimed* umbenannt und kann alle Projekte enthalten, die nicht zu *claimed* hinzugefügt wurden. Die Rolle *unclaimed* funktioniert wie zuvor (d. h. wie in PEP 458 erklärt, Projekte, die dieser Rolle hinzugefügt werden, werden von PyPI mit einem Online-Schlüssel signiert). Offline-Schlüssel von Entwicklern gewährleisten die Stärke des maximalen Sicherheitsmodells gegenüber dem minimalen Modell. Obwohl das minimale Sicherheitsmodell die kontinuierliche Bereitstellung von Projekten unterstützt, werden alle Projekte mit einem Online-Schlüssel signiert. Das heißt, ein Angreifer kann Pakete im minimalen Sicherheitsmodell korrumpieren, aber nicht im maximalen Modell, ohne auch einen Entwicklerschlüssel zu kompromittieren.
Abbildung 1: Überblick über das Metadaten-Layout im maximalen Sicherheitsmodell. Das maximale Sicherheitsmodell unterstützt kontinuierliche Bereitstellung und übersteht Schlüsselkompromittierungen.
Projekte, die von Entwicklern signiert und zum ersten Mal auf PyPI hochgeladen werden, werden zur Rolle *recently-claimed* hinzugefügt. Die Rolle *recently-claimed* verwendet einen Online-Schlüssel, sodass Projekte, die zum ersten Mal hochgeladen werden, sofort für Clients verfügbar sind. Nach einiger Zeit können PyPI-Administratoren Projekte, die in *recently-claimed* aufgeführt sind, periodisch (z. B. jeden Monat) in die Rolle *claimed* verschieben, um maximale Sicherheit zu gewährleisten. Die Rolle *claimed* verwendet einen Offline-Schlüssel, sodass Projekte, die dieser Rolle hinzugefügt werden, bei einer Kompromittierung von PyPI nicht leicht gefälscht werden können.
Die Rolle *recently-claimed* ist von der Rolle *unclaimed* getrennt, aus Gründen der Benutzerfreundlichkeit und Effizienz, nicht der Sicherheit. Wenn neue Projektdelegationen am Anfang der *unclaimed*-Metadaten hinzugefügt würden, müssten die *unclaimed*-Metadaten jedes Mal neu heruntergeladen werden, wenn ein Projekt einen Schlüssel erhält. Durch die Trennung neuer Projekte wird die abgerufene Datenmenge reduziert. Aus Sicht der Benutzerfreundlichkeit ist es für Administratoren auch einfacher zu sehen, welche Projekte nun beansprucht sind. Diese Information ist beim Verschieben von Schlüsseln von *recently-claimed* nach *claimed* erforderlich, was im Abschnitt „Erstellung konsistenter Snapshots“ näher erläutert wird.
Ende-zu-Ende-Signierung
Ende-zu-Ende-Signierung ermöglicht es sowohl PyPI als auch Entwicklern, die von Clients heruntergeladenen Metadaten zu signieren. PyPI ist vertrauenswürdig, hochgeladene Projekte für Clients verfügbar zu machen (PyPI signiert die Metadaten für diesen Teil des Prozesses), und Entwickler signieren die Distributionen, die sie auf PyPI hochladen.
Um Vertrauen in ein Projekt zu delegieren, müssen Entwickler mindestens einen öffentlichen Schlüssel an PyPI übermitteln. Entwickler können mehrere öffentliche Schlüssel für dasselbe Projekt übermitteln (z. B. einen Schlüssel für jeden Betreuer des Projekts). PyPI nimmt alle öffentlichen Schlüssel des Projekts und fügt sie zu übergeordneten Metadaten hinzu, die PyPI dann signiert. Nach der anfänglichen Vertrauenseinrichtung müssen Entwickler Distributionen, die sie auf PyPI hochladen, mit mindestens einem entsprechenden privaten Schlüssel des öffentlichen Schlüssels signieren. Die von Entwicklern auf PyPI hochgeladenen signierten TUF-Metadaten enthalten Informationen wie die Dateigröße und den Hash der Distribution, die Paketmanager zur Verifizierung heruntergeladener Distributionen verwenden.
Die praktischen Auswirkungen der Ende-zu-Ende-Signierung sind der zusätzliche administrative Aufwand, der für die Delegierung von Vertrauen an ein Projekt erforderlich ist, und die signierten Metadaten, die Entwickler zusammen mit der Distribution auf PyPI hochladen MÜSSEN. Insbesondere wird von PyPI erwartet, dass es Metadaten periodisch mit einem Offline-Schlüssel signiert, indem Projekte zur Metadatendatei *claimed* hinzugefügt und diese signiert werden. Im Gegensatz dazu werden Projekte im minimalen Sicherheitsmodell nur jemals mit einem Online-Schlüssel signiert. Ende-zu-Ende-Signierung erfordert zwar manuelle Eingriffe zur Vertrauensdelegation (d. h. zum Signieren von Metadaten mit einem Offline-Schlüssel), dies ist jedoch ein einmaliger Aufwand, und Projekte erhalten danach stärkere Schutzmechanismen gegen PyPI-Kompromittierungen.
Metadatensignaturen, Schlüsselverwaltung und Signierung von Distributionen
Dieser Abschnitt behandelt die Tools, das Signaturschema und die Signierungsmethoden, die PyPI Implementierern der Signierungstools EMPFEHLEN KANN. Von Entwicklern wird erwartet, dass sie diese Tools verwenden, um Distributionen zu signieren und auf PyPI hochzuladen. Um die in den folgenden Unterabschnitten besprochenen empfohlenen Tools und Schemata zusammenzufassen: Entwickler KÖNNEN kryptografische Schlüssel generieren und Metadaten (mit dem Ed25519-Signaturschema) auf eine automatisierte Weise signieren, wobei die Metadaten die für die Verifizierung der Authentizität der Distribution erforderlichen Informationen enthalten. Entwickler laden dann Metadaten auf PyPI hoch, wo sie für den Download durch Paketmanager wie pip verfügbar sind (d. h. Paketmanager, die TUF-Metadaten unterstützen). Der gesamte Prozess ist für die Endbenutzer (die einen Paketmanager verwenden, der TUF unterstützt) transparent, die Distributionen von PyPI herunterladen.
Die ersten drei Unterabschnitte (Kryptografisches Signaturschema, Kryptografische Schlüsseldateien und Schlüsselverwaltung) behandeln die kryptografischen Komponenten des Entwickler-Release-Prozesses. Das heißt, welchen Schlüsseltyp PyPI unterstützt, wie Schlüssel gespeichert und wie Schlüssel generiert werden können. Die beiden Unterabschnitte, die den ersten drei folgen, befassen sich mit den PyPI-Modulen, die zur Unterstützung von TUF-Metadaten modifiziert WERDEN SOLLTEN. Zum Beispiel sind Twine und Distutils zwei Projekte, die modifiziert WERDEN SOLLTEN. Schließlich behandelt der letzte Unterabschnitt die automatisierte Schlüsselverwaltung und Signierungslösung, die für die Signierungstools EMPFOHLEN WIRD.
Das Design von TUF ist flexibel in Bezug auf kryptografische Schlüsseltypen, Signaturen und Signierungsmethoden. Die in den folgenden Abschnitten diskutierten Tools, Modifikationen und Methoden sind EMPFEHLUNGEN für die Implementierer der Signierungstools.
Kryptografisches Signaturschema: Ed25519
Der mit CPython ausgelieferte Paketmanager (pip) MUSS auf Nicht-CPython-Interpretern funktionieren und darf keine Abhängigkeiten haben, die kompiliert werden müssen (d. h. die PyPI+TUF-Integration DARF KEINE Kompilierung von C-Erweiterungen erfordern, um kryptografische Signaturen zu verifizieren). Die Verifizierung von Signaturen MUSS in Python erfolgen, und die Verifizierung von RSA-Signaturen [8] kann in reinem Python aus Geschwindigkeitsgründen unpraktisch sein. Daher KANN PyPI das Ed25519-Signaturschema verwenden.
Ed25519 [9] ist ein Public-Key-Signiersystem, das kleine kryptografische Signaturen und Schlüssel verwendet. Eine reine Python-Implementierung des Ed25519-Signaturschemas ist verfügbar. Die Verifizierung von Ed25519-Signaturen ist auch in Python schnell.
Kryptografische Schlüsseldateien
Die Implementierung KANN Schlüsseldateien mit AES-256-CTR-Modus verschlüsseln und Passwörter mit PBKDF2-HMAC-SHA256 (standardmäßig 100.000 Iterationen, kann aber vom Entwickler überschrieben werden) stärken. Die aktuelle Python-Implementierung von TUF kann jede kryptografische Bibliothek verwenden (Unterstützung für PyCA-Kryptografie wird in Zukunft hinzugefügt), kann die Standardanzahl von PBKDF2-Iterationen überschreiben und das KDF nach Belieben anpassen.
Schlüsselverwaltung: miniLock
Eine einfach zu bedienende Lösung zur Schlüsselverwaltung wird benötigt. Eine Lösung besteht darin, einen privaten Schlüssel aus einem Passwort abzuleiten, damit Entwickler kryptografische Schlüsseldateien nicht über mehrere Computer hinweg verwalten müssen. miniLock ist ein Beispiel dafür, wie dies geschehen kann. Entwickler können den kryptografischen Schlüssel als sekundäres Passwort betrachten. miniLock funktioniert auch gut mit einem Signaturschema wie Ed25519, das nur einen sehr kleinen Schlüssel benötigt.
Tools für Drittanbieter-Uploads: Twine
Tools von Drittanbietern wie Twine KÖNNEN (wenn sie Distributionen mit TUF-Metadaten unterstützen möchten) modifiziert werden, um Entwicklerprojekte zu signieren und auf PyPI hochzuladen. Twine ist ein Dienstprogramm zur Interaktion mit PyPI, das TLS zum Hochladen von Distributionen verwendet und MITM-Angriffe auf Benutzernamen und Passwörter verhindert.
Build-Backends
Build-Backends KÖNNEN modifiziert werden, um Metadaten zu signieren und signierte Distributionen auf PyPI hochzuladen.
Automatisierte Signierungslösung
Eine einfach zu bedienende Lösung zur Schlüsselverwaltung wird für Entwickler EMPFOHLEN. Ein Ansatz ist die Generierung eines kryptografischen privaten Schlüssels aus einem Benutzerpasswort, ähnlich wie bei miniLock. Obwohl Entwicklersignaturen optional bleiben können, ist dieser Ansatz möglicherweise unzureichend aufgrund der großen Anzahl potenziell unsignierter Abhängigkeiten, die jede Distribution haben kann. Wenn eine dieser Abhängigkeiten unsigniert ist, negiert dies jeden Vorteil, den das Projekt durch die Signierung seiner eigenen Distribution erzielt (d. h. Angreifer müssten nur eine der unsignierten Abhängigkeiten kompromittieren, um Endbenutzer anzugreifen). Die Anforderung, dass Entwickler Distributionen manuell signieren und Schlüssel verwalten, wird voraussichtlich dazu führen, dass die Schlüsselsignierung eine ungenutzte Funktion bleibt.
Eine standardmäßige, von PyPI vermittelte Schlüsselverwaltungs- und PaketSignierungsLösung, die für Entwickler transparent ist und kein Key Escrow (Teilen von verschlüsselten privaten Schlüsseln mit PyPI) erfordert, wird für die Signierungstools EMPFOHLEN. Darüber hinaus SOLLTEN die Signierungstools das Teilen von privaten Schlüsseln über mehrere Rechner eines jeden Entwicklers umgehen. Das bedeutet, dass die Schlüsselverwaltungslösung mehrere Schlüssel für jedes Projekt unterstützen SOLLTE.
Das Folgende skizziert eine automatisierte Signierungslösung, der ein neuer Entwickler folgen KÖNNTE, um eine Distribution auf PyPI hochzuladen:
- Registrieren Sie ein PyPI-Projekt.
- Geben Sie ein sekundäres Passwort ein (unabhängig vom PyPI-Benutzerkonto-Passwort).
- Optional: Fügen Sie dem PyPI-Benutzerkonto des Entwicklers eine neue Identität von einem zweiten Rechner hinzu (nach einer Passwortabfrage).
- Projekt hochladen.
- Optional: Andere Betreuer, die mit dem Projekt verbunden sind, können sich anmelden und ein sekundäres Passwort eingeben, um ihre Identität zum Projekt hinzuzufügen.
Schritt 1 ist das normale Verfahren, das Entwickler befolgen, um ein PyPI-Projekt zu registrieren.
Schritt 2 generiert eine verschlüsselte Schlüsseldatei (privat), lädt einen Ed25519-öffentlichen Schlüssel auf PyPI hoch und signiert die für die Distribution generierten TUF-Metadaten.
Das optionale Hinzufügen einer neuen Identität von einem zweiten Rechner durch einfaches Eingeben eines Passworts in Schritt 3 generiert ebenfalls eine verschlüsselte private Schlüsseldatei und lädt einen Ed25519-öffentlichen Schlüssel auf PyPI hoch. Separate Identitäten KÖNNEN erstellt werden, um einem Entwickler zu ermöglichen, Releases auf mehreren Maschinen zu signieren. Eine vorhandene verifizierte Identität (deren öffentlicher Schlüssel in den Projektdaten oder auf PyPI hochgeladen ist) signiert neue Identitäten. Standardmäßig hat die Projektmetadaten einen Signaturschwellenwert von „1“, und andere verifizierte Identitäten können neue Releases erstellen, um den Schwellenwert zu erfüllen.
Schritt 4 lädt die Distributionsdatei und die TUF-Metadaten auf PyPI hoch. Der Abschnitt „Snapshot-Prozess“ beschreibt im Detail das Verfahren, das Entwickler zum Hochladen einer Distribution auf PyPI befolgen.
Schritt 5 ermöglicht es anderen Betreuern, eine verschlüsselte Schlüsseldatei auf ähnliche Weise wie in Schritt 2 zu generieren. Diese Schlüssel SOLLTEN auf PyPI hochgeladen und zu den TUF-Metadaten hinzugefügt werden. Dieser Schlüssel KANN zum Hochladen zukünftiger Releases des Projekts verwendet werden.
Die Generierung kryptografischer Dateien und Signaturen ist im Standardfall für Entwickler transparent: Entwickler müssen nicht wissen, dass Pakete automatisch signiert werden. Die Signierungstools sollten jedoch flexibel sein; Entwickler möchten möglicherweise ihre eigenen Schlüssel generieren und die Schlüsselverwaltung selbst übernehmen. In diesem Fall können Entwickler einfach ihre öffentlichen Schlüssel auf PyPI hochladen.
Die Repository- und Entwickler-TUF-Tools unterstützen derzeit alle zuvor genannten Empfehlungen, mit Ausnahme der automatisierten Signierungslösung, die zu Distlib, Twine und anderen Drittanbieter-Signierungstools hinzugefügt WERDEN SOLLTE. Die automatisierte Signierungslösung ruft verfügbare Repository-Tool-Funktionen auf, um Metadaten zu signieren und kryptografische Schlüsseldateien zu generieren.
Snapshot-Prozess
Der Snapshot-Prozess ist recht einfach und SOLLTE automatisiert werden. Der Snapshot-Prozess MUSS den neuesten Arbeitsdatensatz von *root*, *targets* und delegierten Rollen im Speicher halten. Etwa jede Minute signiert der Snapshot-Prozess diesen neuesten Arbeitsdatensatz. (Zur Erinnerung: Projekt-Uploads informieren den Snapshot-Prozess kontinuierlich über die neuesten delegierten Metadaten auf eine nebenläufigkeitsgeschützte Weise. Der Snapshot-Prozess signiert tatsächlich eine Kopie des neuesten Arbeitsdatensatzes, während der neueste Arbeitsdatensatz im Speicher mit Informationen aktualisiert wird, die kontinuierlich von den Projekt-Transaktionsprozessen kommuniziert werden.) Der Snapshot-Prozess MUSS neue *timestamp*-Metadaten generieren und signieren, die die im vorherigen Schritt generierten Metadaten (root, targets und delegierte Rollen) verbürgen. Schließlich MUSS der Snapshot-Prozess die neuen *timestamp*- und *snapshot*-Metadaten, die den neuesten Snapshot darstellen, für Clients verfügbar machen.
Ein *claimed* oder *recently-claimed* Projekt muss in seiner Transaktion auf PyPI nicht nur Targets (einen Simple Index sowie Distributionen), sondern auch TUF-Metadaten hochladen. Das Projekt KANN dies tun, indem es eine ZIP-Datei mit zwei Verzeichnissen hochlädt: /metadata/ (enthält delegierte Targets-Metadatendateien) und /targets/ (enthält Targets wie den Simple Index des Projekts und Distributionen, die von den delegierten Targets-Metadaten signiert sind).
Immer wenn das Projekt Metadaten oder Target-Dateien auf PyPI hochlädt, SOLLTE PyPI die Projekt-TUF-Metadaten auf mindestens die folgenden Eigenschaften überprüfen:
- Eine Schwellenwertanzahl der von PyPI für dieses Projekt registrierten Entwicklerschlüssel MUSS die delegierte Targets-Metadatendatei signiert haben, die die „Wurzel“ der Targets für dieses Projekt darstellt (z. B. metadata/targets/ projekt.txt).
- Die Signaturen der delegierten Targets-Metadatendateien MÜSSEN gültig sein.
- Die delegierten Targets-Metadatendateien DÜRFEN NICHT abgelaufen sein.
- Die delegierten Targets-Metadaten MÜSSEN konsistent mit den Targets sein.
- Ein Delegator DURF NICHT Targets delegieren, die ihm nicht von einem anderen Delegator delegiert wurden.
- Ein Delegierter DURF NICHT Targets signieren, die ihm nicht von einem Delegator delegiert wurden.
Wenn PyPI sich entscheidet, die Projekt-TUF-Metadaten zu überprüfen, KANN PyPI sich entscheiden, jegliche Metadaten oder Target-Dateien abzulehnen, die diese Anforderungen nicht erfüllen.
PyPI MUSS die Zugriffskontrolle durchsetzen, indem sichergestellt wird, dass jedes Projekt nur auf die TUF-Metadaten schreiben kann, für die es verantwortlich ist. Dies MUSS geschehen, indem sichergestellt wird, dass Projekt-Upload-Prozesse in die richtigen Metadaten und an die richtigen Speicherorte innerhalb dieser Metadaten schreiben. Zum Beispiel MUSS ein Projekt-Upload-Prozess für ein unbeanspruchtes Projekt in die richtigen Target-Pfade in den richtigen delegierten *unclaimed*-Metadaten für die Targets des Projekts schreiben.
In seltenen Fällen KANN PyPI das TUF-Metadatenformat für Projekte rückwärts-inkompatibel erweitern wollen. Beachten Sie, dass PyPI nicht in der Lage sein wird, vorhandene TUF-Metadaten automatisch im Namen von Projekten neu zu schreiben, um die Metadaten in das neue rückwärts-inkompatible Format zu aktualisieren, da dies die Signaturen der Metadaten, wie sie von Entwicklerschlüsseln signiert wurden, ungültig machen würde. Stattdessen SOLLTEN Paketmanager so geschrieben werden, dass sie mehrere inkompatible Versionen von TUF-Metadaten erkennen und verarbeiten können, damit *claimed*- und *recently-claimed*-Projekten eine angemessene Zeit eingeräumt werden kann, ihre Metadaten in neuere, aber rückwärts-inkompatible Formate zu migrieren. Ein Mechanismus zur Handhabung dieser Versionsänderung wird in TAP 14 beschrieben.
Wenn PyPI schließlich der Festplattenspeicher ausgeht, um einen neuen konsistenten Snapshot zu erstellen, KANN PyPI dann einen „Mark-and-Sweep“-Algorithmus verwenden, um ausreichend veraltete konsistente Snapshots zu löschen. Das heißt, es werden nur veraltete Metadaten wie *timestamp* und *snapshot*, die nicht mehr verwendet werden, gelöscht. Insbesondere, um den neuesten konsistenten Snapshot zu erhalten, würde PyPI Objekte durchlaufen – beginnend mit der Wurzel (timestamp) – des neuesten konsistenten Snapshots, alle besuchten Objekte markieren und alle unmarkierten Objekte löschen. Die letzten paar konsistenten Snapshots können auf ähnliche Weise aufbewahrt werden. Das Löschen eines konsistenten Snapshots führt dazu, dass Clients bei jeder Anfrage nach einem Target des gelöschten konsistenten Snapshots nichts anderes als HTTP 404-Fehler sehen. Clients SOLLTEN dann ihre Anfragen wie zuvor mit dem neuesten konsistenten Snapshot erneut versuchen.
Alle Paketmanager, die TUF-Metadaten unterstützen, MÜSSEN so modifiziert werden, dass sie jede Metadaten- und Target-Datei (mit Ausnahme von *timestamp*-Metadaten) herunterladen, indem sie in der Anfrage für die Datei den kryptografischen Hash der Datei im Dateinamen einschließen. Gemäß der im nächsten Unterabschnitt EMPFOHLENEN Konvention wird eine Anfrage für die Datei unter filename.ext in die entsprechende Anfrage für die Datei unter digest.filename umgewandelt.
Schließlich SOLLTE PyPI ein Transaktionsprotokoll verwenden, um Projekt-Transaktionsprozesse und Warteschlangen aufzuzeichnen, damit die Wiederherstellung nach einem Serverausfall erleichtert wird.
Erstellung konsistenter Snapshots
PyPI ist dafür verantwortlich, je nach Projekt entweder die Metadaten *claimed*, *recently-claimed* oder *unclaimed* und die zugehörigen delegierten Metadaten zu aktualisieren. Jedes Projekt MUSS seinen Satz von Metadaten und Targets in einer einzigen Transaktion hochladen. Der hochgeladene Dateisatz wird als „Projekttransaktion“ bezeichnet. Wie PyPI Dateien in einer Projekttransaktion validieren KANN, wird in einem späteren Abschnitt erläutert. Der Schwerpunkt dieses Abschnitts liegt darauf, wie PyPI auf eine Projekttransaktion reagieren wird.
Jede Metadaten- und Target-Datei MUSS in ihrem Dateinamen den Hex-Digest ihres BLAKE2b-256-Hashes enthalten, den PyPI nach dem Hochladen der Dateien dem Dateinamen voranstellen KANN. Für dieses PEP wird EMPFOHLEN, dass PyPI eine einfache Konvention der Form *digest.filename* annimmt, wobei filename der ursprüngliche Dateiname ohne eine Kopie des Hashes ist und digest der Hex-Digest des Hashes ist.
Wenn ein unbeanspruchtes Projekt eine neue Transaktion hochlädt, MUSS ein Projekt-Transaktionsprozess alle neuen Target-Dateien und die relevanten delegierten *unclaimed*-Metadaten hinzufügen. Der Projekt-Upload-Prozess MUSS den Snapshot-Prozess über neue delegierte *unclaimed*-Metadaten informieren.
Wenn ein *recently-claimed*-Projekt eine neue Transaktion hochlädt, MUSS ein Projekt-Upload-Prozess alle neuen Target-Dateien und die delegierten Targets-Metadaten für das Projekt hinzufügen. Wenn das Projekt neu ist, MUSS der Projekt-Upload-Prozess auch neue *recently-claimed*-Metadaten mit den öffentlichen Schlüsseln (die Teil der Transaktion sein MÜSSEN) für das Projekt hinzufügen. *Recently-claimed*-Projekte haben einen von der Upload-Prozess gesetzten Schwellenwert von „1“. Schließlich MUSS der Projekt-Upload-Prozess den Snapshot-Prozess über neue *recently-claimed*-Metadaten sowie den aktuellen Satz von delegierten Targets-Metadaten für das Projekt informieren.
Der Upload-Prozess für ein *claimed*-Projekt ist leicht anders, da PyPI-Administratoren Projekte periodisch (ein manueller Prozess, der alle zwei Wochen bis zu einem Monat dauern KANN) von der Rolle *recently-claimed* in die Rolle *claimed* verschieben. (Das Verschieben eines Projekts von *recently-claimed* nach *claimed* ist ein manueller Prozess, da PyPI-Administratoren einen Offline-Schlüssel verwenden müssen, um die Distribution des *claimed*-Projekts zu signieren.) Ein Projekt-Upload-Prozess MUSS dann neue *recently-claimed*- und *claimed*-Metadaten hinzufügen, um diese Migration widerzuspiegeln. Wie bei einem *recently-claimed*-Projekt MUSS der Projekt-Upload-Prozess immer alle neuen Target-Dateien und delegierten Targets-Metadaten für das *claimed*-Projekt hinzufügen. Schließlich MUSS der Projekt-Upload-Prozess den Prozess für konsistente Snapshots über neue *recently-claimed*- oder *claimed*-Metadaten sowie den aktuellen Satz von delegierten Targets-Metadaten für das Projekt informieren.
Projekt-Upload-Prozesse SOLLTEN automatisiert werden, außer wenn PyPI-Administratoren ein Projekt von der Rolle *recently-claimed* in die Rolle *claimed* verschieben. Projekt-Upload-Prozesse MÜSSEN auch atomar angewendet werden: Entweder werden alle Metadaten und Target-Dateien hinzugefügt oder keine davon. Die Projekt-Transaktionsprozesse und der Snapshot-Prozess SOLLTEN gleichzeitig arbeiten. Schließlich SOLLTEN Projekt-Upload-Prozesse die neuesten *claimed*, *recently-claimed* und *unclaimed*-Metadaten im Speicher halten, damit sie in neuen konsistenten Snapshots korrekt aktualisiert werden.
Die Warteschlange KANN parallel in der Reihenfolge ihres Erscheinens verarbeitet werden, vorausgesetzt, die folgenden Regeln werden beachtet:
- Kein Paar von Projekt-Upload-Prozessen darf gleichzeitig am selben Projekt arbeiten.
- Kein Paar von Projekt-Upload-Prozessen darf gleichzeitig an *unclaimed*-Projekten arbeiten, die zur selben delegierten *unclaimed*-Rolle gehören.
- Kein Paar von Projekt-Upload-Prozessen darf gleichzeitig an neuen *recently-claimed*-Projekten arbeiten.
- Kein Paar von Projekt-Upload-Prozessen darf gleichzeitig an neuen *claimed*-Projekten arbeiten.
- Kein Projekt-Upload-Prozess darf an einem neuen *claimed*-Projekt arbeiten, während ein anderer Projekt-Upload-Prozess an einem neuen *recently-claimed*-Projekt arbeitet und umgekehrt.
Diese Regeln MÜSSEN befolgt werden, um sicherzustellen, dass Metadaten nicht inkonsistent gelesen oder geschrieben werden.
Auditing von Snapshots
Wenn eine bösartige Partei PyPI kompromittiert, kann sie beliebige Dateien mit einem der Online-Schlüssel signieren. Die Rollen mit Offline-Schlüsseln (d. h. *root* und *targets*) sind weiterhin geschützt. Um sich sicher von einem Repository-Kompromittierung zu erholen, sollten Snapshots auditiert werden, um sicherzustellen, dass Dateien nur auf vertrauenswürdige Versionen zurückgesetzt werden.
Wenn ein Repository-Kompromittierung erkannt wurde, muss die Integrität von drei Arten von Informationen validiert werden:
- Wenn die Online-Schlüssel des Repositorys kompromittiert wurden, können sie widerrufen werden, indem die *targets*-Rolle neue Metadaten signiert, die an einen neuen Schlüssel delegiert werden.
- Wenn die Rollenmetadaten im Repository geändert wurden, wirkt sich dies auf die von Online-Schlüsseln signierten Metadaten aus. Alle Rolleninformationen, die seit der Kompromittierung erstellt wurden, sollten verworfen werden. Infolgedessen müssen Entwickler neuer Projekte ihre Projekte neu registrieren.
- Wenn die Pakete selbst manipuliert wurden, können sie anhand der gespeicherten Hash-Informationen für Pakete validiert werden, die vor der Kompromittierung in vertrauenswürdigen Metadaten vorhanden waren. Ebenso können neue Distributionen, die von Entwicklern in der *claimed*-Rolle signiert wurden, sicher beibehalten werden. Jede Distribution, die von Entwicklern in den Rollen *recently-claimed* oder *unclaimed* signiert wurde, sollte jedoch verworfen werden.
Um Snapshots im Falle einer Kompromittierung sicher wiederherstellen zu können, SOLLTE PyPI eine kleine Anzahl eigener Spiegelserver unterhalten, um PyPI-Snapshots nach einem bestimmten Zeitplan zu kopieren. Das Spiegelprotokoll kann für diesen Zweck sofort verwendet werden. Die Spiegelserver müssen gesichert und isoliert sein, sodass sie nur für das Spiegeln von PyPI verantwortlich sind. Die Spiegelserver können gegeneinander geprüft werden, um versehentliche oder bösartige Fehler zu erkennen.
Ein anderer Ansatz besteht darin, periodisch den kryptografischen Hash jedes Snapshots zu generieren und ihn zu twittern. Beispielsweise kann ein Benutzer nach Erhalt des Tweets die tatsächlichen Metadaten vorlegen, und die Repository-Betreuer können dann den kryptografischen Hash der Metadaten verifizieren. Alternativ kann PyPI periodisch eigene Versionen von Snapshots archivieren, anstatt sich auf extern bereitgestellte Metadaten zu verlassen. In diesem Fall SOLLTE PyPI den kryptografischen Hash jedes Pakets im Repository nehmen und diese Daten auf einem Offline-Gerät speichern. Wenn sich ein Paket-Hash geändert hat, deutet dies auf einen Angriff hin.
Angriffe, die unterschiedliche Versionen von Metadaten ausliefern oder eine Paketversion auf einer bestimmten Version einfrieren, können von TUF mit Techniken wie impliziter Schlüsselwiderrufung und Erkennung von Metadaten-Fehlübereinstimmungen behandelt werden [2].
Analyse von Schlüsselkompromittierungen
Dieses PEP hat das maximale Sicherheitsmodell, die TUF-Rollen, die hinzugefügt werden sollten, um die kontinuierliche Bereitstellung von Distributionen zu unterstützen, die Generierung und Signierung der Metadaten jeder Rolle sowie die Unterstützung von Distributionen, die von Entwicklern signiert wurden, behandelt. Die verbleibenden Abschnitte erörtern, wie PyPI Repository-Metadaten auditieren SOLLTE und welche Methoden PyPI zur Erkennung und Wiederherstellung nach einer PyPI-Kompromittierung einsetzen kann.
Tabelle 1 fasst einige der möglichen Angriffe zusammen, wenn eine Schwellenanzahl von privaten kryptografischen Schlüsseln (die zu beliebigen PyPI-Rollen gehören) kompromittiert wird. Die linkeste Spalte listet die kompromittierten Rollen (oder eine Kombination von Rollen) auf, und die Spalten rechts zeigen, ob die kompromittierten Rollen die Clients anfällig für bösartige Updates, Freeze-Angriffe oder Metadaten-Inkonsistenz-Angriffe machen.
| Rollenkompromittierung | Bösartige Updates | Freeze-Angriff | Metadaten-Inkonsistenz-Angriffe |
|---|---|---|---|
| timestamp | NEIN snapshot und targets oder beliebige delegierte Rollen müssen kooperieren | JA begrenzt durch die früheste Ablaufzeit von root, targets oder bin Metadaten | NEIN snapshot muss kooperieren |
| snapshot | NEIN timestamp und targets oder beliebige delegierte Rollen müssen kooperieren | NEIN timestamp muss kooperieren | NEIN timestamp muss kooperieren |
| timestamp UND snapshot | NEIN targets oder beliebige delegierte Rollen müssen kooperieren | JA begrenzt durch die früheste Ablaufzeit von root, targets oder bin Metadaten | JA begrenzt durch die früheste Ablaufzeit von root, targets oder bin Metadaten |
| targets ODER claimed ODER recently-claimed ODER unclaimed ODER project | NEIN timestamp und snapshot müssen kooperieren | NICHT ANWENDBAR benötigt timestamp und snapshot | NICHT ANWENDBAR benötigt timestamp und snapshot |
| (timestamp UND snapshot) UND project | JA | JA begrenzt durch die früheste Ablaufzeit von root, targets oder bin Metadaten | JA begrenzt durch die früheste Ablaufzeit von root, targets oder bin Metadaten |
| (timestamp UND snapshot) UND (recently-claimed ODER unclaimed) | JA, aber nur von Projekten, die nicht von claimed delegiert wurden | JA, begrenzt durch die früheste Ablaufzeit von root, targets, claimed, recently-claimed, project oder unclaimed Metadaten | JA, begrenzt durch die früheste Ablaufzeit von root, targets, claimed, recently-claimed, project oder unclaimed Metadaten |
| (timestamp UND snapshot) UND (targets ODER claimed) | JA | JA, begrenzt durch die früheste Ablaufzeit von root, targets, claimed, recently-claimed, project oder unclaimed Metadaten | JA, begrenzt durch die früheste Ablaufzeit von root, targets, claimed, recently-claimed, project oder unclaimed Metadaten |
| root | JA | JA | JA |
Tabelle 1: Angriffe, die durch die Kompromittierung bestimmter Kombinationen von Rollenschlüsseln möglich sind. Im September 2013 wurde gezeigt, wie die damalige neueste Version von pip anfällig für diese Angriffe war und wie TUF Benutzer davor schützen konnte [7]. Von Offline-Schlüsseln signierte Rollen sind fett.
Beachten Sie, dass die Kompromittierung von targets oder einer delegierten Rolle (mit Ausnahme der Projekt-Targets-Metadaten) einem Angreifer nicht sofort erlaubt, bösartige Updates auszuliefern. Der Angreifer muss auch die Rollen timestamp und snapshot kompromittieren (die beide online sind und daher wahrscheinlicher kompromittiert werden). Das bedeutet, dass man, um einen beliebigen Angriff zu starten, nicht nur in der Lage sein muss, als Man-in-the-Middle zu agieren, sondern auch den timestamp-Schlüssel kompromittieren muss (oder die root-Schlüssel kompromittieren und einen neuen timestamp-Schlüssel signieren muss). Um einen anderen Angriff als einen Freeze-Angriff zu starten, muss man auch den snapshot-Schlüssel kompromittieren. Schließlich kann eine Kompromittierung der PyPI-Infrastruktur zu bösartigen Updates von recently-claimed-Projekten führen, da die Schlüssel für diese Rollen online sind.
Im Falle einer Schlüsselkompromittierung
Eine Schlüsselkompromittierung bedeutet, dass eine Schwellenanzahl von Schlüsseln von Entwicklern oder Rollen auf PyPI sowie der PyPI-Infrastruktur kompromittiert und zum Signieren neuer Metadaten auf PyPI verwendet wurde.
Wenn eine Schwellenanzahl von Entwicklerschlüsseln eines Projekts kompromittiert wurde, MUSS das Projekt folgende Schritte unternehmen:
- Die Projektmetadaten und Targets MÜSSEN auf den letzten bekannten guten konsistenten Snapshot wiederhergestellt werden, bei dem das Projekt nicht als kompromittiert bekannt war. Dies kann geschehen, indem Entwickler alle Targets neu paketieren und mit den neuen Schlüsseln neu signieren.
- Die Metadaten des Projekts MÜSSEN inkrementell mit Versionsnummern versehen, ihre Ablaufzeiten entsprechend verlängert und ihre Signaturen erneuert werden.
Währenddessen MUSS PyPI folgende Schritte unternehmen:
- Die kompromittierten Entwicklerschlüssel aus der Rolle recently-claimed oder claimed widerrufen. Dies geschieht durch Ersetzen der kompromittierten Entwicklerschlüssel durch neu ausgestellte Entwicklerschlüssel.
- Ein neuer zeitgestempelter konsistenter Snapshot MUSS ausgestellt werden.
Wenn eine Schwellenanzahl von timestamp, snapshot, recently-claimed oder unclaimed Schlüsseln kompromittiert wurde, MUSS PyPI folgende Schritte unternehmen:
- Widerrufen Sie die Schlüssel der Rollen timestamp, snapshot und targets aus der root-Rolle. Dies geschieht durch Ersetzen der kompromittierten timestamp, snapshot und targets Schlüssel durch neu ausgestellte Schlüssel.
- Widerrufen Sie die Schlüssel recently-claimed und unclaimed aus der targets-Rolle, indem Sie ihre Schlüssel durch neu ausgestellte Schlüssel ersetzen. Signieren Sie die neuen Metadaten der targets-Rolle und verwerfen Sie die neuen Schlüssel (da dies, wie wir bereits erklärt haben, die Sicherheit der targets-Metadaten erhöht).
- Löschen Sie alle Targets oder Delegationen in der recently-claimed-Rolle und löschen Sie alle zugehörigen delegierten Target-Metadaten. Neu registrierte Projekte SOLLTEN ihre Entwicklerschlüssel erneut bei PyPI registrieren.
- Alle Targets der Rollen recently-claimed und unclaimed SOLLTEN mit dem letzten bekannten guten konsistenten Snapshot verglichen werden, bei dem keine der timestamp, snapshot, recently-claimed oder unclaimed Schlüssel als kompromittiert bekannt waren. Hinzugefügte, aktualisierte oder gelöschte Targets im kompromittierten konsistenten Snapshot, die nicht mit dem letzten bekannten guten konsistenten Snapshot übereinstimmen, SOLLTEN auf ihre vorherigen Versionen wiederhergestellt werden. Nach Sicherstellung der Integrität aller unclaimed Targets MÜSSEN die unclaimed Metadaten neu generiert werden.
- Die Metadaten recently-claimed und unclaimed MÜSSEN inkrementell mit Versionsnummern versehen, ihre Ablaufzeiten entsprechend verlängert und ihre Signaturen erneuert werden.
- Ein neuer zeitgestempelter konsistenter Snapshot MUSS ausgestellt werden.
Dies würde präventiv alle diese Rollen schützen, auch wenn nur eine davon kompromittiert wurde.
Wenn eine Schwellenanzahl der targets- oder claimed-Schlüssel kompromittiert wurde, gibt es wenig, was ein Angreifer tun könnte, ohne die timestamp- und snapshot-Schlüssel. In diesem Fall MUSS PyPI einfach die kompromittierten targets- oder claimed-Schlüssel widerrufen, indem es sie in den Rollen root und targets durch neue Schlüssel ersetzt.
Wenn eine Schwellenanzahl der timestamp-, snapshot- und claimed-Schlüssel kompromittiert wurde, MUSS PyPI folgende Schritte zusätzlich zu den Schritten unternehmen, die bei Kompromittierung der timestamp- oder snapshot-Schlüssel ergriffen werden:
- Widerrufen Sie die Schlüssel der claimed-Rolle aus der targets-Rolle und ersetzen Sie sie durch neu ausgestellte Schlüssel.
- Alle Projekt-Targets der claimed-Rollen SOLLTEN mit dem letzten bekannten guten konsistenten Snapshot verglichen werden, bei dem keine der timestamp-, snapshot- oder claimed-Schlüssel als kompromittiert bekannt waren. Hinzugefügte, aktualisierte oder gelöschte Targets im kompromittierten konsistenten Snapshot, die nicht mit dem letzten bekannten guten konsistenten Snapshot übereinstimmen, KÖNNEN auf ihre vorherigen Versionen wiederhergestellt werden. Nach Sicherstellung der Integrität aller claimed Projekt-Targets MÜSSEN die claimed-Metadaten neu generiert werden.
- Die claimed-Metadaten MÜSSEN inkrementell mit Versionsnummern versehen, ihre Ablaufzeiten entsprechend verlängert und ihre Signaturen erneuert werden.
Das Befolgen dieser Schritte würde präventiv alle diese Rollen schützen, auch wenn nur eine davon kompromittiert wurde.
Wenn eine Schwellenanzahl von root-Schlüsseln kompromittiert wurde, MUSS PyPI die Schritte unternehmen, die bei Kompromittierung der targets-Rolle ergriffen wurden. Alle root-Schlüssel müssen ebenfalls ersetzt werden.
Es wird auch EMPFOHLEN, dass PyPI Kompromittierungen ausreichend mit Sicherheitsbulletins dokumentiert. Diese Sicherheitsbulletins sind am informativsten, wenn Benutzer von pip-mit-TUF ein Projekt nicht installieren oder aktualisieren können, weil die Schlüssel für die Rollen timestamp, snapshot oder root nicht mehr gültig sind. Benutzer könnten dann die PyPI-Website besuchen, um Sicherheitsbulletins zu konsultieren, die erklären könnten, warum Benutzer nicht mehr installieren oder aktualisieren können, und dann entsprechende Maßnahmen ergreifen. Wenn eine Schwellenanzahl von root-Schlüsseln aufgrund einer Kompromittierung nicht widerrufen wurde, können neue root-Metadaten sicher aktualisiert werden, da eine Schwellenanzahl bestehender root-Schlüssel zur Signierung der Integrität der neuen root-Metadaten verwendet wird. TUF-Clients können die Integrität der neuen root-Metadaten mit einer Schwellenanzahl von zuvor bekannten root-Schlüsseln verifizieren. Dies wird der übliche Fall sein. Im schlimmsten Fall, in dem eine Schwellenanzahl von root-Schlüsseln aufgrund einer Kompromittierung widerrufen wurde, kann ein Endbenutzer wählen, neue root-Metadaten mit Out-of-band-Mechanismen zu aktualisieren.
Anhang A: PyPI Build Farm und Ende-zu-Ende-Signierung
PyPI-Administratoren beabsichtigen, eine zentrale Build-Farm zu unterstützen. Die PyPI-Build-Farm wird automatisch ein Wheel für jede Distribution generieren, die von Entwicklern hochgeladen wird, auf der PyPI-Infrastruktur und auf unterstützten Plattformen. Paketmanager werden wahrscheinlich Projekte installieren, indem sie diese PyPI-Wheels (die viel schneller installiert werden können als Quellcode-Distributionen) anstelle der von Entwicklern signierten Quellcode-Distributionen herunterladen. Die Auswirkungen einer zentralen Build-Farm mit End-to-End-Signierung SOLLTEN untersucht werden, bevor das maximale Sicherheitsmodell implementiert wird.
Ein Problem bei einer zentralen Build-Farm und End-to-End-Signierung ist, dass Entwickler unwahrscheinlich sind, Wheel-Distributionen zu signieren, sobald sie auf der PyPI-Infrastruktur generiert wurden. Die Generierung von Wheels aus Quellcode-Distributionen, die von Entwicklern signiert wurden, kann jedoch immer noch von Vorteil sein, vorausgesetzt, die Erstellung von Wheels ist ein deterministischer Prozess. Wenn deterministische Builds nicht machbar sind, können Entwickler das Vertrauen in diese Wheels an eine PyPI-Rolle delegieren, die mit einem Online-Schlüssel für Wheels signiert.
Referenzen
Danksagungen
Dieses Material basiert auf Arbeiten, die von der National Science Foundation unter den Grants Nr. CNS-1345049 und CNS-0959138 unterstützt werden. Alle Meinungen, Erkenntnisse und Schlussfolgerungen oder Empfehlungen, die in diesem Material ausgedrückt werden, sind die des/der Autor(en) und spiegeln nicht notwendigerweise die Ansichten der National Science Foundation wider.
Wir danken Alyssa Coghlan, Daniel Holth, Donald Stufft, Sumana Harihareswara und der distutils-sig-Community im Allgemeinen dafür, dass sie uns geholfen haben, darüber nachzudenken, wie TUF nützlich und effizient mit PyPI integriert werden kann.
Roger Dingledine, Sebastian Hahn, Nick Mathewson, Martin Peck und Justin Samuel halfen uns bei der Gestaltung von TUF aus seinem Vorgänger Thandy des Tor-Projekts.
Wir würdigen die Bemühungen von Konstantin Andrianov, Geremy Condra, Zane Fisher, Justin Samuel, Tian Tian, Santiago Torres, John Ward und Yuyu Zheng zur Entwicklung von TUF.
Urheberrecht
Dieses Dokument wurde gemeinfrei erklärt.
Quelle: https://github.com/python/peps/blob/main/peps/pep-0480.rst
Zuletzt geändert: 2025-02-01 08:55:40 GMT