Benennung in der Lieferkette
Jeder kann ein Paket namens acme-auth veröffentlichen. Ihr Build könnte es installieren.
So funktioniert Dependency Confusion, und sie endet damit, dass fremder Code in Ihrem Build läuft. Die gefährdeten Namen sind die in Ihren eigenen Manifesten, und SourceAnt hat bereits jeden einzelnen davon bewertet.
Wie es passiert
Kein Exploit und kein raffinierter Trick. Nur ein Name, der niemandem gehört.
- 01
Sie lesen einen Namen
Ihr internes Paket heißt acme-auth. Der Name steht in einer Lockfile in einem öffentlichen Repository, in einem Stack Trace, in einem Job-Log oder in einem Blogbeitrag, den einer Ihrer Entwickler geschrieben hat.
- 02
Sie veröffentlichen ihn
Jeder kann acme-auth in der öffentlichen Registry registrieren. Es kostet nichts und dauert eine Minute. Sie setzen die Version höher als Ihre.
- 03
Ihr Build nimmt deren Version
Je nachdem, wie Ihr Installer konfiguriert ist, kann ein öffentliches Paket das private überstimmen. Nun läuft deren Install-Skript dort, wo Ihr Build läuft, mit allem, worauf Ihr Build zugreifen kann.
Die Lösung ist wohlbekannt: den Namen besitzen oder die Quelle festlegen, aus der er stammen muss. Der schwierige Teil ist zu wissen, welche Ihrer Namen exponiert sind, und diese Liste steht nirgendwo geschrieben.
Warum SourceAnt es weiß
Es musste entscheiden, wie weit es dem Namen trauen durfte
Wenn SourceAnt ein Manifest liest und eine Abhängigkeit von einem Namen sieht, den eines Ihrer eigenen Repositories veröffentlicht, schlägt es die Beziehung vor. Zuerst fragt es, ob der Name seinen Eigentümer trägt.
Ein Name, der seinen Eigentümer trägt, lässt sich nur Ihnen und niemandem sonst zuordnen, daher kommt der Vorschlag mit voller Konfidenz zurück. Ein bloßes Wort erhält eine niedrigere Bewertung, weil die öffentliche Registry auch für dieses Wort antworten kann. Die Zahl ist kein Absicherungsmittel. Sie ist die Form der Exposition.
Die gewünschte Liste ist also ein Filter, den Sie bereits ausführen können.
Der Name trägt seinen Eigentümer. Niemand sonst kann ihn veröffentlichen.
Ein bloßes Wort. Es lässt sich wahrscheinlich Ihnen zuordnen, und ein Fremder könnte es morgen übernehmen.
Zwei Ihrer Repositories veröffentlichen denselben Namen. Das ist mehrdeutig, daher wird nichts vorgeschlagen statt eines Münzwurfs.
Drei davon können nicht übernommen werden. Eines kann es.
Die meisten Ökosysteme setzen den Eigentümer in den Namen. Python nicht.
| Ökosystem | Ein Name von Ihnen | Wer ihn veröffentlichen kann |
|---|---|---|
| Composer | acme/auth | Nur Sie Der Vendor ist Teil des Namens. Niemand sonst kann ihn veröffentlichen. |
| Go | github.com/acme/auth | Nur Sie Der Modulpfad ist ein Host, den Sie kontrollieren. |
| npm | @acme/auth | Nur Sie Eigentum, wenn gescoped. Ein bloßer Name nicht. |
| PyPI | acme-auth | Jeder PyPI-Namen tragen keinen Eigentümer. Es gibt keine gescopte Form, zu der man wechseln könnte. |
Wenn Ihre internen Pakete Python sind, gehört jedes einzelne davon zur zweiten Gruppe. Das ist kein Fehler in der Inferenz. Es ist das, was PyPI-Namen sind.
Dann haben Sie eine Liste und zwei Möglichkeiten, sie zu schließen
Den Namen übernehmen oder die Registry daran hindern, für ihn zu antworten
Registrieren Sie ihn öffentlich, damit niemand sonst es kann, verschieben Sie das Paket hinter einen Scope, den Sie besitzen, oder legen Sie die Quelle fest, aus der Ihr Installer es auflösen darf.
Schreiben Sie die auf, mit denen Sie leben möchten
Halten Sie ihn als Constraint mit Ihrer Begründung fest. Die nächste Person, die ihn findet, oder der nächste Agent liest die Entscheidung, statt sie neu aufzuwerfen.
Setzen Sie Ihr System auf den Eintrag
Betreiben Sie den Open Core auf Ihrer eigenen Infrastruktur oder starten Sie im gehosteten Workspace. Der Graph ist in beiden Fällen portabel.