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}}