From e2552b1eaaeaac35ec36b6ee22c51a7f40dccb31 Mon Sep 17 00:00:00 2001 From: Translator Date: Thu, 21 Aug 2025 02:42:08 +0000 Subject: [PATCH] Translated ['', 'src/pentesting-web/dependency-confusion.md'] to pl --- src/pentesting-web/dependency-confusion.md | 259 +++++++++++++++++++-- 1 file changed, 243 insertions(+), 16 deletions(-) diff --git a/src/pentesting-web/dependency-confusion.md b/src/pentesting-web/dependency-confusion.md index 146db2264..9e10b4f07 100644 --- a/src/pentesting-web/dependency-confusion.md +++ b/src/pentesting-web/dependency-confusion.md @@ -5,41 +5,268 @@ ## Basic Information -W skrócie, luka w zależności z powodu pomyłki występuje, gdy projekt używa biblioteki o **błędnie napisanej** nazwie, **nieistniejącej** lub z **niesprecyzowaną wersją**, a używane repozytorium zależności pozwala na **zbieranie zaktualizowanych wersji z publicznych** repozytoriów. +Dependency Confusion (znane również jako ataki substytucyjne) występuje, gdy menedżer pakietów rozwiązuje nazwę zależności z niezamierzonego, mniej zaufanego rejestru/źródła (zwykle publicznego rejestru) zamiast zamierzonego prywatnego/wewnętrznego. Zwykle prowadzi to do zainstalowania pakietu kontrolowanego przez atakującego. + +Typowe przyczyny: +- Typosquatting/błędne pisanie: Importowanie `reqests` zamiast `requests` (rozwiązuje z publicznego rejestru). +- Nieistniejący/porzucony wewnętrzny pakiet: Importowanie `company-logging`, który już nie istnieje wewnętrznie, więc resolver szuka w publicznych rejestrach i znajduje pakiet atakującego. +- Preferencje wersji w różnych rejestrach: Importowanie wewnętrznego `company-requests`, podczas gdy resolver ma również prawo do zapytań w publicznych rejestrach i preferuje „najlepszą” / nowszą wersję opublikowaną publicznie przez atakującego. + +Kluczowa idea: Jeśli resolver może zobaczyć wiele rejestrów dla tej samej nazwy pakietu i ma prawo wybrać „najlepszego” kandydata globalnie, jesteś narażony, chyba że ograniczysz rozwiązywanie. -- **Błędnie napisana**: Import **`reqests`** zamiast `requests` -- **Nieistniejąca**: Import `company-logging`, wewnętrznej biblioteki, która **już nie istnieje** -- **Niesprecyzowana wersja**: Import **wewnętrznej** **istniejącej** biblioteki `company-requests`, ale repozytorium sprawdza **publiczne repozytoria**, aby zobaczyć, czy są **nowsze wersje**. ## Exploitation > [!WARNING] -> W każdym przypadku atakujący musi tylko opublikować **złośliwy pakiet o nazwie** bibliotek używanych przez firmę ofiary. +> W każdym przypadku atakujący musi tylko opublikować złośliwy pakiet o tej samej nazwie, co zależność, którą twoja kompilacja rozwiązuje z publicznego rejestru. Hooki w czasie instalacji (np. skrypty npm) lub ścieżki kodu w czasie importu często dają możliwość wykonania kodu. ### Misspelled & Inexistent -Jeśli twoja firma próbuje **zaimportować bibliotekę, która nie jest wewnętrzna**, istnieje duże prawdopodobieństwo, że repozytorium bibliotek będzie jej szukać w **publicznych repozytoriach**. Jeśli atakujący ją stworzył, twój kod i działające maszyny prawdopodobnie zostaną skompromitowane. +Jeśli twój projekt odnosi się do biblioteki, która nie jest dostępna w prywatnym rejestrze, a twoje narzędzia wracają do publicznego rejestru, atakujący może umieścić złośliwy pakiet o tej nazwie w publicznym rejestrze. Twoje maszyny wykonawcze/CI/deweloperskie pobiorą i wykonają go. -### Unspecified Version +### Unspecified Version / “Best-version” selection across indexes + +Programiści często pozostawiają wersje nieprzypisane lub pozwalają na szerokie zakresy. Gdy resolver jest skonfigurowany z zarówno wewnętrznymi, jak i publicznymi indeksami, może wybrać najnowszą wersję niezależnie od źródła. Dla wewnętrznych nazw, takich jak `requests-company`, jeśli wewnętrzny indeks ma `1.0.1`, ale atakujący publikuje `1.0.2` w publicznym rejestrze i twój resolver bierze pod uwagę obie, pakiet publiczny może wygrać. -Bardzo często programiści **nie określają żadnej wersji** używanej biblioteki lub określają tylko **główną wersję**. Wtedy interpreter spróbuje pobrać **najnowocześniejszą wersję** spełniającą te wymagania.\ -Jeśli biblioteka jest **znaną zewnętrzną biblioteką** (jak python `requests`), **atakujący nie może wiele zrobić**, ponieważ nie będzie w stanie stworzyć biblioteki o nazwie `requests` (chyba że jest jej oryginalnym autorem).\ -Jednak jeśli biblioteka jest **wewnętrzna**, jak `requests-company` w tym przykładzie, jeśli **repozytorium biblioteki** pozwala na **sprawdzanie nowych wersji również zewnętrznie**, będzie szukać nowszej wersji dostępnej publicznie.\ -Więc jeśli **atakujący wie**, że firma używa biblioteki `requests-company` **wersja 1.0.1** (pozwala na drobne aktualizacje). Może **opublikować** bibliotekę `requests-company` **wersja 1.0.2**, a firma **użyje tej biblioteki zamiast** wewnętrznej. ## AWS Fix -Ta luka została znaleziona w AWS **CodeArtifact** (przeczytaj [**szczegóły w tym poście na blogu**](https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d)).\ -AWS naprawiło to, pozwalając na określenie, czy biblioteka jest wewnętrzna czy zewnętrzna, aby uniknąć pobierania wewnętrznych zależności z zewnętrznych repozytoriów. +Ta podatność została znaleziona w AWS CodeArtifact (przeczytaj szczegóły w tym poście na blogu). AWS dodało kontrole, aby oznaczyć zależności/źródła jako wewnętrzne lub zewnętrzne, aby klient nie pobierał „wewnętrznych” nazw z upstream publicznych rejestrów. + ## Finding Vulnerable Libraries -W [**oryginalnym poście o zależności z powodu pomyłki**](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610) autor przeszukał tysiące ujawnionych plików package.json zawierających zależności projektów javascript. +W oryginalnym poście na temat zamieszania z zależnościami autor szukał tysięcy ujawnionych manifestów (np. `package.json`, `requirements.txt`, pliki blokady), aby wywnioskować wewnętrzne nazwy pakietów, a następnie publikował pakiety o wyższych wersjach w publicznych rejestrach. -## References + +## Practical Attacker Playbook (for red teams in authorized tests) + +- Enumerate names: +- Grep repos and CI configs for manifest/lock files and internal namespaces. +- Look for organization-specific prefixes (e.g., `@company/*`, `company-*`, internal groupIds, NuGet ID patterns, private module paths for Go, etc.). +- Check public registries for availability: +- If the name is unregistered publicly, register it; if it exists, attempt subdependency hijacking by targeting internal transitive names. +- Publish with precedence: +- Choose a semver that “wins” (e.g., a very high version) or matches resolver rules. +- Include minimal install-time execution where applicable (e.g., npm `preinstall`/`install`/`postinstall` scripts). For Python, prefer import-time execution paths, as wheels typically don’t execute arbitrary code on install. +- Exfil control: +- Ensure outbound is allowed from CI to your controlled endpoint; otherwise use DNS queries or error messages as a side-channel to prove code execution. + +> [!CAUTION] +> Always get written authorization, use unique package names/versions for the engagement, and immediately unpublish or coordinate cleanup when testing concludes. + + +## Defender Playbook (what actually prevents confusion) + +High-level strategies that work across ecosystems: +- Use unique internal namespaces and bind them to a single registry. +- Avoid mixing trust levels at resolution time. Prefer a single internal registry that proxies approved public packages instead of giving package managers both internal and public endpoints. +- For managers that support it, map packages to specific sources (no global “best-version” across registries). +- Pin and lock: +- Use lockfiles that record the resolved registry URLs (npm/yarn/pnpm) or use hash/attestation pinning (pip `--require-hashes`, Gradle dependency verification). +- Block public fallback for internal names at the registry/network layer. +- Reserve your internal names in public registries when feasible to prevent future squat. + + +## Ecosystem Notes and Secure Config Snippets + +Below are pragmatic, minimal configs to reduce or eliminate dependency confusion. Prefer enforcing these in CI and developer environments. + +### JavaScript/TypeScript (npm, Yarn, pnpm) + +- Use scoped packages for all internal code and pin the scope to your private registry. +- Keep installs immutable in CI (npm lockfile, `yarn install --immutable`). + +.npmrc (project-level) +``` +# 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 (dla wewnętrznego pakietu) +``` +{ +"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 +``` +Operational tips: +- Publikuj tylko wewnętrzne pakiety w obrębie zakresu `@company`. +- W przypadku pakietów zewnętrznych, zezwól na publiczny rejestr za pośrednictwem swojego prywatnego proxy/lustra, a nie bezpośrednio z klientów. +- Rozważ włączenie pochodzenia pakietów npm dla publicznych pakietów, które publikujesz, aby zwiększyć śledzenie (samo w sobie nie zapobiega pomieszaniu). + +### Python (pip / Poetry) + +Zasada podstawowa: Nie używaj `--extra-index-url`, aby mieszać poziomy zaufania. Albo: +- Udostępnij jeden wewnętrzny indeks, który proxy i buforuje zatwierdzone pakiety PyPI, albo +- Użyj jawnego wyboru indeksu i przypinania haszy. + +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 +``` +Wygeneruj zhaszowane wymagania za pomocą pip-tools: +``` +# From pyproject.toml or requirements.in +pip-compile --generate-hashes -o requirements.txt +pip install --require-hashes -r requirements.txt +``` +Jeśli musisz uzyskać dostęp do publicznego PyPI, zrób to przez swój wewnętrzny proxy i utrzymuj tam wyraźną listę dozwolonych źródeł. Unikaj `--extra-index-url` w CI. + +### .NET (NuGet) + +Użyj mapowania źródeł pakietów, aby powiązać wzorce identyfikatorów pakietów z wyraźnymi źródłami i zapobiec rozwiązywaniu z nieoczekiwanych źródeł. + +nuget.config +``` + + + + + + + + + + + + + + + + + +``` +### Java (Maven/Gradle) + +Maven settings.xml (lustro wszystko do wewnętrznego; zabroń repozytoriów ad-hoc w POM-ach za pomocą Enforcer): +``` + + + +internal-mirror +* +https://maven.corp.example/repository/group + + + +``` +Dodaj Enforcer, aby zablokować repozytoria zadeklarowane w POM-ach i wymusić użycie swojego lustra: +``` + +org.apache.maven.plugins +maven-enforcer-plugin +3.6.1 + + +enforce-no-repositories +enforce + + + + + + + + +``` +Gradle: Centralizuj i zablokuj zależności. +- Wymuszaj repozytoria tylko w `settings.gradle(.kts)`: +``` +dependencyResolutionManagement { +repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS +repositories { +maven { url = uri("https://maven.corp.example/repository/group") } +} +} +``` +- Włącz weryfikację zależności (sumy kontrolne/podpisy) i zatwierdź `gradle/verification-metadata.xml`. + +### Go Modules + +Skonfiguruj prywatne moduły, aby publiczny proxy i baza danych sum kontrolnych nie były używane dla nich. +``` +# 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) + +Zastąp crates.io zatwierdzonym wewnętrznym lustrem lub katalogiem dostawcy dla kompilacji; nie zezwalaj na dowolne publiczne zapasowe źródło. + +.cargo/config.toml +``` +[source.crates-io] +replace-with = "corp-mirror" + +[source.corp-mirror] +registry = "https://crates-mirror.corp.example/index" +``` +Aby opublikować, bądź dokładny z `--registry` i ogranicz dane uwierzytelniające do docelowego rejestru. + +### Ruby (Bundler) + +Użyj bloków źródłowych i wyłącz multisource Gemfiles, aby gemy pochodziły tylko z zamierzonego repozytorium. + +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 +``` +Wymuś na poziomie konfiguracji: +``` +bundle config set disable_multisource true +``` +## CI/CD i Kontrole Rejestru, Które Pomagają + +- Prywatny rejestr jako pojedynczy punkt dostępu: +- Użyj Artifactory/Nexus/CodeArtifact/GitHub Packages/Azure Artifacts jako jedynego punktu, do którego mogą uzyskać dostęp deweloperzy/CI. +- Wprowadź zasady blokowania/zezwalania, aby wewnętrzne przestrzenie nazw nigdy nie były rozwiązywane z publicznych źródeł upstream. +- Pliki blokad są niemutowalne w CI: +- npm: zatwierdź `package-lock.json`, użyj `npm ci`. +- Yarn: zatwierdź `yarn.lock`, użyj `yarn install --immutable`. +- Python: zatwierdź haszowany `requirements.txt`, wymuś `--require-hashes`. +- Gradle: zatwierdź `verification-metadata.xml` i niepowodzenie w przypadku nieznanych artefaktów. +- Kontrola wychodzącego ruchu: zablokuj bezpośredni dostęp z CI do publicznych rejestrów, z wyjątkiem zatwierdzonego proxy. +- Rezerwacja nazw: wstępnie zarejestruj swoje wewnętrzne nazwy/przestrzenie nazw w publicznych rejestrach, gdzie to możliwe. +- Pochodzenie pakietów / zaświadczenia: podczas publikowania publicznych pakietów włącz pochodzenie/zaświadczenia, aby uczynić manipulacje bardziej wykrywalnymi w dalszej kolejności. + +## Odniesienia - [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}}