Translated ['', 'src/pentesting-web/dependency-confusion.md'] to de

This commit is contained in:
Translator 2025-08-21 02:41:31 +00:00
parent a7990f163a
commit 5588c8041e

View File

@ -5,41 +5,268 @@
## Grundinformationen
Zusammenfassend tritt eine Dependency Confusion-Sicherheitsanfälligkeit auf, wenn ein Projekt eine Bibliothek mit einem **falsch geschriebenen** Namen, **nicht existierenden** oder mit einer **nicht angegebenen Version** verwendet und das verwendete Abhängigkeitsrepository es erlaubt, **aktualisierte Versionen aus öffentlichen** Repositories zu **sammeln**.
Dependency Confusion (auch bekannt als Substitution-Angriffe) tritt auf, wenn ein Paketmanager einen Abhängigkeitsnamen aus einem unbeabsichtigten, weniger vertrauenswürdigen Registry/Quelle (in der Regel einer öffentlichen Registry) anstelle der beabsichtigten privaten/internen auflöst. Dies führt typischerweise zur Installation eines von einem Angreifer kontrollierten Pakets.
Häufige Ursachen:
- Typosquatting/Rechtschreibfehler: Importieren von `reqests` anstelle von `requests` (wird aus der öffentlichen Registry aufgelöst).
- Nicht vorhandenes/verlassenes internes Paket: Importieren von `company-logging`, das intern nicht mehr existiert, sodass der Resolver in öffentlichen Registries nachschaut und ein Paket eines Angreifers findet.
- Versionspräferenz über mehrere Registries: Importieren eines internen `company-requests`, während der Resolver auch öffentliche Registries abfragen darf und die „beste“/neuere Version bevorzugt, die öffentlich von einem Angreifer veröffentlicht wurde.
Kernidee: Wenn der Resolver mehrere Registries für denselben Paketnamen sehen kann und berechtigt ist, den „besten“ Kandidaten global auszuwählen, sind Sie anfällig, es sei denn, Sie schränken die Auflösung ein.
- **Falsch geschrieben**: Importiere **`reqests`** anstelle von `requests`
- **Nicht existent**: Importiere `company-logging`, eine interne Bibliothek, die **nicht mehr existiert**
- **Nicht angegebene Version**: Importiere eine **interne** **existierende** `company-requests`-Bibliothek, aber das Repo überprüft **öffentliche Repos**, um zu sehen, ob es **größere Versionen** gibt.
## Ausnutzung
> [!WARNING]
> In allen Fällen muss der Angreifer nur ein **bösartiges Paket mit dem Namen** der von der Opferfirma verwendeten Bibliotheken veröffentlichen.
> In allen Fällen muss der Angreifer nur ein bösartiges Paket mit demselben Namen wie die Abhängigkeit veröffentlichen, die Ihr Build aus einer öffentlichen Registry auflöst. Installationszeit-Hooks (z. B. npm-Skripte) oder Importzeit-Codepfade bieten oft die Möglichkeit zur Codeausführung.
### Falsch geschrieben & Nicht existent
### Falsch geschriebene & nicht vorhandene
Wenn deine Firma versucht, eine **Bibliothek zu importieren, die nicht intern ist**, wird das Bibliotheksrepo höchstwahrscheinlich danach in **öffentlichen Repositories** suchen. Wenn ein Angreifer sie erstellt hat, ist es sehr wahrscheinlich, dass dein Code und die laufenden Maschinen kompromittiert werden.
Wenn Ihr Projekt auf eine Bibliothek verweist, die in der privaten Registry nicht verfügbar ist, und Ihre Tools auf eine öffentliche Registry zurückgreifen, kann ein Angreifer ein bösartiges Paket mit diesem Namen in der öffentlichen Registry bereitstellen. Ihre Runner/CI/Entwicklungsmaschinen werden es abrufen und ausführen.
### Nicht angegebene Version
### Unbestimmte Version / „Beste-Version“-Auswahl über Indizes
Entwickler lassen häufig Versionen ungenau oder erlauben weite Bereiche. Wenn ein Resolver sowohl mit internen als auch mit öffentlichen Indizes konfiguriert ist, kann er die neueste Version unabhängig von der Quelle auswählen. Für interne Namen wie `requests-company`, wenn der interne Index `1.0.1` hat, aber ein Angreifer `1.0.2` in die öffentliche Registry veröffentlicht und Ihr Resolver beide berücksichtigt, kann das öffentliche Paket gewinnen.
Es ist sehr häufig, dass Entwickler **keine Version** der verwendeten Bibliothek angeben oder nur eine **Hauptversion** angeben. Dann versucht der Interpreter, die **neueste Version** herunterzuladen, die diesen Anforderungen entspricht.\
Wenn die Bibliothek eine **bekannte externe Bibliothek** (wie python `requests`) ist, kann ein **Angreifer nicht viel tun**, da er keine Bibliothek mit dem Namen `requests` erstellen kann (es sei denn, er ist der ursprüngliche Autor).\
Wenn die Bibliothek jedoch **intern** ist, wie `requests-company` in diesem Beispiel, und das **Bibliotheksrepo** es erlaubt, **auch extern nach neuen Versionen zu suchen**, wird es nach einer neueren Version suchen, die öffentlich verfügbar ist.\
Wenn ein **Angreifer weiß**, dass die Firma die `requests-company`-Bibliothek **Version 1.0.1** verwendet (kleine Updates erlaubt). Kann er die Bibliothek `requests-company` **Version 1.0.2** **veröffentlichen** und die Firma wird **diese Bibliothek anstelle** der internen verwenden.
## AWS Fix
Diese Sicherheitsanfälligkeit wurde in AWS **CodeArtifact** gefunden (lies die [**Details in diesem Blogbeitrag**](https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d)).\
AWS hat dies behoben, indem es erlaubt, anzugeben, ob eine Bibliothek intern oder extern ist, um zu vermeiden, dass interne Abhängigkeiten aus externen Repositories heruntergeladen werden.
Diese Schwachstelle wurde in AWS CodeArtifact gefunden (lesen Sie die Einzelheiten in diesem Blogbeitrag). AWS hat Kontrollen hinzugefügt, um Abhängigkeiten/Feeds als intern oder extern zu kennzeichnen, sodass der Client keine „internen“ Namen aus upstream öffentlichen Registries abruft.
## Finden von verwundbaren Bibliotheken
Im [**ursprünglichen Beitrag über Dependency Confusion**](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610) suchte der Autor nach Tausenden von exponierten package.json-Dateien, die die Abhängigkeiten von JavaScript-Projekten enthielten.
Im ursprünglichen Beitrag über Dependency Confusion suchte der Autor nach Tausenden von exponierten Manifests (z. B. `package.json`, `requirements.txt`, Lockfiles), um interne Paketnamen abzuleiten und dann höherversionierte Pakete in öffentlichen Registries zu veröffentlichen.
## Praktisches Angreifer-Playbook (für Red Teams in autorisierten Tests)
- Namen auflisten:
- Grep-Repos und CI-Konfigurationen nach Manifest-/Lock-Dateien und internen Namensräumen durchsuchen.
- Nach organisationsspezifischen Präfixen suchen (z. B. `@company/*`, `company-*`, interne groupIds, NuGet-ID-Muster, private Modulpfade für Go usw.).
- Verfügbarkeit in öffentlichen Registries überprüfen:
- Wenn der Name öffentlich nicht registriert ist, registrieren Sie ihn; wenn er existiert, versuchen Sie, Subabhängigkeits-Hijacking durch gezielte interne transitive Namen.
- Mit Priorität veröffentlichen:
- Wählen Sie eine Semver, die „gewinnt“ (z. B. eine sehr hohe Version) oder den Regeln des Resolvers entspricht.
- Minimale Ausführung zur Installationszeit einfügen, wo anwendbar (z. B. npm `preinstall`/`install`/`postinstall`-Skripte). Für Python bevorzugen Sie Ausführungspfade zur Importzeit, da Wheels typischerweise keinen beliebigen Code bei der Installation ausführen.
- Exfil-Kontrolle:
- Stellen Sie sicher, dass ausgehende Verbindungen von CI zu Ihrem kontrollierten Endpunkt erlaubt sind; andernfalls verwenden Sie DNS-Abfragen oder Fehlermeldungen als Seitenkanal, um die Codeausführung nachzuweisen.
> [!CAUTION]
> Holen Sie sich immer eine schriftliche Genehmigung, verwenden Sie eindeutige Paketnamen/-versionen für das Engagement und veröffentlichen Sie sofort oder koordinieren Sie die Bereinigung, wenn die Tests abgeschlossen sind.
## Verteidiger-Playbook (was tatsächlich Verwirrung verhindert)
Hochrangige Strategien, die in verschiedenen Ökosystemen funktionieren:
- Verwenden Sie eindeutige interne Namensräume und binden Sie sie an eine einzige Registry.
- Vermeiden Sie es, Vertrauensstufen zur Auflösungszeit zu mischen. Bevorzugen Sie eine einzige interne Registry, die genehmigte öffentliche Pakete proxy, anstatt Paketmanagern sowohl interne als auch öffentliche Endpunkte zu geben.
- Für Manager, die es unterstützen, Pakete bestimmten Quellen zuzuordnen (keine globale „beste Version“ über Registries).
- Festlegen und Sperren:
- Verwenden Sie Lockfiles, die die aufgelösten Registry-URLs aufzeichnen (npm/yarn/pnpm) oder verwenden Sie Hash-/Attestierungs-Pinning (pip `--require-hashes`, Gradle-Abhängigkeitsüberprüfung).
- Blockieren Sie öffentliche Rückfälle für interne Namen auf der Registry-/Netzwerkschicht.
- Reservieren Sie Ihre internen Namen in öffentlichen Registries, wenn möglich, um zukünftiges Squatting zu verhindern.
## Ökosystemnotizen und sichere Konfigurationssnippets
Im Folgenden finden Sie pragmatische, minimale Konfigurationen zur Reduzierung oder Beseitigung von Dependency Confusion. Bevorzugen Sie es, diese in CI- und Entwicklerumgebungen durchzusetzen.
### JavaScript/TypeScript (npm, Yarn, pnpm)
- Verwenden Sie Scoped-Pakete für gesamten internen Code und binden Sie den Scope an Ihre private Registry.
- Halten Sie Installationen in CI unveränderlich (npm Lockfile, `yarn install --immutable`).
.npmrc (Projektebene)
```
# Bind internal scope to private registry; do not allow public fallback for @company/*
@company:registry=https://registry.corp.example/npm/
# Always authenticate to the private registry
//registry.corp.example/npm/:_authToken=${NPM_TOKEN}
strict-ssl=true
```
package.json (für internes Paket)
```
{
"name": "@company/api-client",
"version": "1.2.3",
"private": false,
"publishConfig": {
"registry": "https://registry.corp.example/npm/",
"access": "restricted"
}
}
```
Yarn Berry (.yarnrc.yml)
```
npmScopes:
company:
npmRegistryServer: "https://registry.corp.example/npm/"
npmAlwaysAuth: true
# CI should fail if lockfile would change
enableImmutableInstalls: true
```
Betriebliche Tipps:
- Veröffentlichen Sie interne Pakete nur innerhalb des `@company`-Scopes.
- Für Drittanbieter-Pakete erlauben Sie das öffentliche Registry über Ihren privaten Proxy/Spiegel, nicht direkt von Clients.
- Erwägen Sie, die Herkunft von npm-Paketen für öffentliche Pakete, die Sie veröffentlichen, zu aktivieren, um die Rückverfolgbarkeit zu erhöhen (verhindert nicht von sich aus Verwirrung).
### Python (pip / Poetry)
Kernregel: Verwenden Sie `--extra-index-url` nicht, um Vertrauensstufen zu mischen. Entweder:
- Stellen Sie einen einzigen internen Index bereit, der genehmigte PyPI-Pakete proxy und zwischenspeichert, oder
- Verwenden Sie eine explizite Indexauswahl und Hash-Pinning.
pip.conf
```
[global]
index-url = https://pypi.corp.example/simple
# Disallow source distributions when possible
only-binary = :all:
# Lock with hashes generated via pip-tools
require-hashes = true
```
Generiere gehashte Anforderungen mit pip-tools:
```
# From pyproject.toml or requirements.in
pip-compile --generate-hashes -o requirements.txt
pip install --require-hashes -r requirements.txt
```
Wenn Sie auf das öffentliche PyPI zugreifen müssen, tun Sie dies über Ihren internen Proxy und führen Sie dort eine explizite Erlaubenliste. Vermeiden Sie `--extra-index-url` in CI.
### .NET (NuGet)
Verwenden Sie Package Source Mapping, um Paket-ID-Muster mit expliziten Quellen zu verknüpfen und die Auflösung von unerwarteten Feeds zu verhindern.
nuget.config
```
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="corp" value="https://nuget.corp.example/v3/index.json" />
</packageSources>
<packageSourceMapping>
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="corp">
<package pattern="Company.*" />
<package pattern="Internal.Utilities" />
</packageSource>
</packageSourceMapping>
</configuration>
```
### Java (Maven/Gradle)
Maven settings.xml (alle auf intern spiegeln; ad-hoc Repos in POMs über Enforcer nicht zulassen):
```
<settings>
<mirrors>
<mirror>
<id>internal-mirror</id>
<mirrorOf>*</mirrorOf>
<url>https://maven.corp.example/repository/group</url>
</mirror>
</mirrors>
</settings>
```
Fügen Sie Enforcer hinzu, um in POMs deklarierte Repositories zu verbannen und die Verwendung Ihres Mirrors zu erzwingen:
```
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<id>enforce-no-repositories</id>
<goals><goal>enforce</goal></goals>
<configuration>
<rules>
<requireNoRepositories />
</rules>
</configuration>
</execution>
</executions>
</plugin>
```
Gradle: Abhängigkeiten zentralisieren und sperren.
- Erzwingen Sie Repositories nur in `settings.gradle(.kts)`:
```
dependencyResolutionManagement {
repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
repositories {
maven { url = uri("https://maven.corp.example/repository/group") }
}
}
```
- Aktivieren Sie die Abhängigkeitsüberprüfung (Prüfziffern/Signaturen) und committen Sie `gradle/verification-metadata.xml`.
### Go-Module
Konfigurieren Sie private Module, damit der öffentliche Proxy und die Prüfzifferndatenbank nicht für sie verwendet werden.
```
# Use corporate proxy first, then public proxy as fallback
export GOPROXY=https://goproxy.corp.example,https://proxy.golang.org
# Mark private paths to skip proxy and checksum db
export GOPRIVATE=*.corp.example.com,github.com/your-org/*
export GONOSUMDB=*.corp.example.com,github.com/your-org/*
```
### Rust (Cargo)
Ersetzen Sie crates.io durch einen genehmigten internen Mirror oder ein Vendor-Verzeichnis für Builds; erlauben Sie keinen beliebigen öffentlichen Fallback.
.cargo/config.toml
```
[source.crates-io]
replace-with = "corp-mirror"
[source.corp-mirror]
registry = "https://crates-mirror.corp.example/index"
```
Für die Veröffentlichung seien Sie explizit mit `--registry` und halten Sie die Anmeldeinformationen auf das Ziel-Registry beschränkt.
### Ruby (Bundler)
Verwenden Sie Quellblöcke und deaktivieren Sie Multisource-Gemfiles, damit Gems nur aus dem beabsichtigten Repository stammen.
Gemfile
```
source "https://gems.corp.example"
source "https://rubygems.org" do
gem "rails"
gem "pg"
end
source "https://gems.corp.example" do
gem "company-logging"
end
```
Auf Konfigurationsebene durchsetzen:
```
bundle config set disable_multisource true
```
## CI/CD und Registry-Kontrollen, die helfen
- Private Registry als einziger Zugang:
- Verwenden Sie Artifactory/Nexus/CodeArtifact/GitHub Packages/Azure Artifacts als den einzigen Endpunkt, den Entwickler/CI erreichen können.
- Implementieren Sie Block-/Erlauben-Regeln, damit interne Namespaces niemals von öffentlichen Quellen aufwärts aufgelöst werden.
- Lockfiles sind in CI unveränderlich:
- npm: commit `package-lock.json`, verwenden Sie `npm ci`.
- Yarn: commit `yarn.lock`, verwenden Sie `yarn install --immutable`.
- Python: commit gehashtes `requirements.txt`, erzwingen Sie `--require-hashes`.
- Gradle: commit `verification-metadata.xml` und schlagen Sie bei unbekannten Artefakten fehl.
- Ausgehende Egress-Kontrolle: blockieren Sie den direkten Zugriff von CI auf öffentliche Registries, außer über den genehmigten Proxy.
- Namensreservierung: registrieren Sie Ihre internen Namen/Namensräume in öffentlichen Registries, wo unterstützt.
- Paketherkunft / Bestätigungen: aktivieren Sie bei der Veröffentlichung öffentlicher Pakete Herkunft/Bestätigungen, um Manipulationen downstream leichter erkennbar zu machen.
## Referenzen
- [https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610)
- [https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d](https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d)
- [https://learn.microsoft.com/en-us/nuget/consume-packages/package-source-mapping](https://learn.microsoft.com/en-us/nuget/consume-packages/package-source-mapping)
- [https://yarnpkg.com/configuration/yarnrc/](https://yarnpkg.com/configuration/yarnrc/)
{{#include ../banners/hacktricks-training.md}}