Dependency Confusion
Reading time: 10 minutes
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
Basic Information
Dependency Confusion (जिसे प्रतिस्थापन हमले भी कहा जाता है) तब होता है जब एक पैकेज प्रबंधक एक निर्भरता नाम को एक अनपेक्षित, कम-विश्वसनीय रजिस्ट्रि/स्रोत (आमतौर पर एक सार्वजनिक रजिस्ट्रि) से हल करता है, बजाय इसके कि इसे इच्छित निजी/आंतरिक रजिस्ट्रि से हल किया जाए। इससे आमतौर पर एक हमलावर-नियंत्रित पैकेज की स्थापना होती है।
सामान्य मूल कारण:
- टाइपोसक्वाटिंग/गलत स्पेलिंग:
reqests
कोrequests
के बजाय आयात करना (सार्वजनिक रजिस्ट्रि से हल होता है)। - गैर-मौजूद/परित्यक्त आंतरिक पैकेज:
company-logging
को आयात करना जो अब आंतरिक रूप से मौजूद नहीं है, इसलिए हल करने वाला सार्वजनिक रजिस्ट्रियों में देखता है और एक हमलावर का पैकेज पाता है। - कई रजिस्ट्रियों में संस्करण प्राथमिकता: एक आंतरिक
company-requests
को आयात करना जबकि हल करने वाले को सार्वजनिक रजिस्ट्रियों को भी क्वेरी करने की अनुमति है और एक हमलावर द्वारा सार्वजनिक रूप से प्रकाशित "सर्वश्रेष्ठ"/नया संस्करण पसंद करता है।
मुख्य विचार: यदि हल करने वाला एक ही पैकेज नाम के लिए कई रजिस्ट्रियों को देख सकता है और "सर्वश्रेष्ठ" उम्मीदवार को वैश्विक रूप से चुनने की अनुमति है, तो आप कमजोर हैं जब तक कि आप समाधान को सीमित नहीं करते।
Exploitation
warning
सभी मामलों में, हमलावर को केवल एक दुर्भावनापूर्ण पैकेज प्रकाशित करने की आवश्यकता होती है जिसका नाम उस निर्भरता के समान है जिसे आपका निर्माण सार्वजनिक रजिस्ट्रि से हल करता है। स्थापना-समय हुक (जैसे, npm स्क्रिप्ट) या आयात-समय कोड पथ अक्सर कोड निष्पादन देते हैं।
Misspelled & Inexistent
यदि आपका प्रोजेक्ट एक लाइब्रेरी का संदर्भ देता है जो निजी रजिस्ट्रि में उपलब्ध नहीं है, और आपका उपकरण सार्वजनिक रजिस्ट्रि पर वापस जाता है, तो एक हमलावर उस नाम के साथ एक दुर्भावनापूर्ण पैकेज सार्वजनिक रजिस्ट्रि में डाल सकता है। आपके रनर/CI/dev मशीनें इसे लाएंगी और निष्पादित करेंगी।
Unspecified Version / “Best-version” selection across indexes
डेवलपर्स अक्सर संस्करणों को अनपिन करते हैं या व्यापक रेंज की अनुमति देते हैं। जब एक हल करने वाला आंतरिक और सार्वजनिक सूचियों के साथ कॉन्फ़िगर किया जाता है, तो यह स्रोत की परवाह किए बिना नवीनतम संस्करण का चयन कर सकता है। आंतरिक नामों जैसे requests-company
के लिए, यदि आंतरिक सूची में 1.0.1
है लेकिन एक हमलावर सार्वजनिक रजिस्ट्रि में 1.0.2
प्रकाशित करता है और आपका हल करने वाला दोनों पर विचार करता है, तो सार्वजनिक पैकेज जीत सकता है।
AWS Fix
यह कमजोरियां AWS CodeArtifact में पाई गई थीं (इस ब्लॉग पोस्ट में विवरण पढ़ें)। AWS ने निर्भरताओं/फीड को आंतरिक बनाम बाहरी के रूप में चिह्नित करने के लिए नियंत्रण जोड़े ताकि क्लाइंट "आंतरिक" नामों को अपस्ट्रीम सार्वजनिक रजिस्ट्रियों से न लाए।
Finding Vulnerable Libraries
निर्भरता भ्रम के बारे में मूल पोस्ट में लेखक ने हजारों उजागर मैनिफेस्ट (जैसे, package.json
, requirements.txt
, लॉकफाइल) की खोज की ताकि आंतरिक पैकेज नामों का अनुमान लगाया जा सके और फिर उच्च-संस्करण वाले पैकेजों को सार्वजनिक रजिस्ट्रियों में प्रकाशित किया जा सके।
Practical Attacker Playbook (for red teams in authorized tests)
- Enumerate names:
- मैनिफेस्ट/लॉक फ़ाइलों और आंतरिक नाम स्थानों के लिए रिपोजिटरी और CI कॉन्फ़िगरेशन को ग्रेप करें।
- संगठन-विशिष्ट उपसर्गों की तलाश करें (जैसे,
@company/*
,company-*
, आंतरिक groupIds, NuGet ID पैटर्न, Go के लिए निजी मॉड्यूल पथ, आदि)। - उपलब्धता के लिए सार्वजनिक रजिस्ट्रियों की जांच करें:
- यदि नाम सार्वजनिक रूप से अनरजिस्टर्ड है, तो इसे रजिस्टर करें; यदि यह मौजूद है, तो आंतरिक पारगमन नामों को लक्षित करके उपनिर्भरता हाइजैकिंग का प्रयास करें।
- प्राथमिकता के साथ प्रकाशित करें:
- एक सेमवर चुनें जो "जीतता" है (जैसे, एक बहुत उच्च संस्करण) या हल करने वाले के नियमों से मेल खाता है।
- जहां लागू हो, न्यूनतम स्थापना-समय निष्पादन शामिल करें (जैसे, npm
preinstall
/install
/postinstall
स्क्रिप्ट)। पायथन के लिए, आयात-समय निष्पादन पथों को प्राथमिकता दें, क्योंकि पहिए आमतौर पर स्थापना पर मनमाना कोड निष्पादित नहीं करते हैं। - नियंत्रण का एक्सफिल:
- सुनिश्चित करें कि CI से आपके नियंत्रित एंडपॉइंट तक आउटबाउंड की अनुमति है; अन्यथा, कोड निष्पादन को साबित करने के लिए DNS क्वेरी या त्रुटि संदेशों का उपयोग करें।
caution
हमेशा लिखित प्राधिकरण प्राप्त करें, संलग्नक के लिए अद्वितीय पैकेज नाम/संस्करण का उपयोग करें, और परीक्षण समाप्त होने पर तुरंत अनप्रकाशित करें या सफाई का समन्वय करें।
Defender Playbook (what actually prevents confusion)
उच्च-स्तरीय रणनीतियाँ जो पारिस्थितिक तंत्रों में काम करती हैं:
- अद्वितीय आंतरिक नाम स्थानों का उपयोग करें और उन्हें एकल रजिस्ट्रि से बांधें।
- समाधान के समय पर विश्वास स्तरों को मिलाने से बचें। अनुमोदित सार्वजनिक पैकेज को प्रॉक्सी करने के लिए एकल आंतरिक रजिस्ट्रि को प्राथमिकता दें, बजाय इसके कि पैकेज प्रबंधकों को आंतरिक और सार्वजनिक एंडपॉइंट दोनों दें।
- उन प्रबंधकों के लिए जो इसे समर्थन करते हैं, पैकेजों को विशिष्ट स्रोतों से मानचित्रित करें (रजिस्ट्रियों के बीच कोई वैश्विक "सर्वश्रेष्ठ-संस्करण" नहीं)।
- पिन और लॉक:
- उन लॉकफाइलों का उपयोग करें जो हल की गई रजिस्ट्रि URLs को रिकॉर्ड करती हैं (npm/yarn/pnpm) या हैश/प्रमाणन पिनिंग का उपयोग करें (pip
--require-hashes
, Gradle निर्भरता सत्यापन)। - रजिस्ट्रि/नेटवर्क स्तर पर आंतरिक नामों के लिए सार्वजनिक फॉलबैक को अवरुद्ध करें।
- भविष्य के स्क्वाट को रोकने के लिए जब संभव हो, सार्वजनिक रजिस्ट्रियों में अपने आंतरिक नामों को आरक्षित करें।
Ecosystem Notes and Secure Config Snippets
नीचे व्यावहारिक, न्यूनतम कॉन्फ़िगरेशन हैं जो निर्भरता भ्रम को कम या समाप्त करने के लिए हैं। इन्हें CI और डेवलपर वातावरण में लागू करने को प्राथमिकता दें।
JavaScript/TypeScript (npm, Yarn, pnpm)
- सभी आंतरिक कोड के लिए स्कोप्ड पैकेज का उपयोग करें और स्कोप को अपने निजी रजिस्ट्रि पर पिन करें।
- CI में इंस्टॉलेशन को अपरिवर्तनीय रखें (npm लॉकफाइल,
yarn install --immutable
)।
.npmrc (प्रोजेक्ट-स्तरीय)
# 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 (आंतरिक पैकेज के लिए)
{
"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
संचालन संबंधी सुझाव:
- केवल
@company
स्कोप के भीतर आंतरिक पैकेज प्रकाशित करें। - तृतीय-पक्ष पैकेज के लिए, अपने निजी प्रॉक्सी/मिरर के माध्यम से सार्वजनिक रजिस्ट्री की अनुमति दें, सीधे ग्राहकों से नहीं।
- ट्रेसबिलिटी बढ़ाने के लिए सार्वजनिक पैकेज के लिए npm पैकेज उत्पत्ति सक्षम करने पर विचार करें (यह अपने आप में भ्रम को रोकता नहीं है)।
Python (pip / Poetry)
मुख्य नियम: विश्वास स्तरों को मिलाने के लिए --extra-index-url
का उपयोग न करें। या तो:
- एकल आंतरिक इंडेक्स को उजागर करें जो अनुमोदित PyPI पैकेजों को प्रॉक्सी और कैश करता है, या
- स्पष्ट इंडेक्स चयन और हैश पिनिंग का उपयोग करें।
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
pip-tools के साथ हैश किए गए आवश्यकताएँ उत्पन्न करें:
# From pyproject.toml or requirements.in
pip-compile --generate-hashes -o requirements.txt
pip install --require-hashes -r requirements.txt
यदि आपको सार्वजनिक PyPI तक पहुंचना है, तो इसे अपने आंतरिक प्रॉक्सी के माध्यम से करें और वहां एक स्पष्ट अनुमति सूची बनाए रखें। CI में --extra-index-url
से बचें।
.NET (NuGet)
पैकेज आईडी पैटर्न को स्पष्ट स्रोतों से जोड़ने और अप्रत्याशित फीड से समाधान को रोकने के लिए पैकेज स्रोत मैपिंग का उपयोग करें।
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 (सभी को आंतरिक में मिरर करें; POMs में ad-hoc repos को Enforcer के माध्यम से अनुमति न दें):
<settings>
<mirrors>
<mirror>
<id>internal-mirror</id>
<mirrorOf>*</mirrorOf>
<url>https://maven.corp.example/repository/group</url>
</mirror>
</mirrors>
</settings>
Enforcer को POMs में घोषित रिपॉजिटरीज़ को प्रतिबंधित करने और आपके मिरर के उपयोग को मजबूर करने के लिए जोड़ें:
<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: निर्भरता को केंद्रीकृत और लॉक करें।
- केवल
settings.gradle(.kts)
में रिपॉजिटरी लागू करें:
dependencyResolutionManagement {
repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
repositories {
maven { url = uri("https://maven.corp.example/repository/group") }
}
}
- निर्भरता सत्यापन (चेकसम/हस्ताक्षर) सक्षम करें और
gradle/verification-metadata.xml
को कमिट करें।
गो मॉड्यूल
निजी मॉड्यूल को इस तरह से कॉन्फ़िगर करें कि सार्वजनिक प्रॉक्सी और चेकसम DB का उनके लिए उपयोग न किया जाए।
# 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)
क्रेट्स.io को अनुमोदित आंतरिक मिरर या विक्रेता निर्देशिका के साथ बदलें; मनमाने सार्वजनिक फॉलबैक की अनुमति न दें।
.cargo/config.toml
[source.crates-io]
replace-with = "corp-mirror"
[source.corp-mirror]
registry = "https://crates-mirror.corp.example/index"
प्रकाशन के लिए, --registry
के साथ स्पष्ट रहें और क्रेडेंशियल्स को लक्षित रजिस्ट्री तक सीमित रखें।
Ruby (Bundler)
स्रोत ब्लॉकों का उपयोग करें और मल्टीसोर्स Gemfiles को अक्षम करें ताकि जेम्स केवल इच्छित रिपॉजिटरी से आएं।
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
कॉन्फ़िग स्तर पर लागू करें:
bundle config set disable_multisource true
CI/CD और रजिस्ट्र्री नियंत्रण जो मदद करते हैं
- प्राइवेट रजिस्ट्र्री एकल इनग्रेस के रूप में:
- Artifactory/Nexus/CodeArtifact/GitHub Packages/Azure Artifacts का उपयोग करें जो एकमात्र एंडपॉइंट है जिसे डेवलपर्स/CI पहुंच सकते हैं।
- ब्लॉक/अनुमति नियम लागू करें ताकि आंतरिक नामस्थान कभी भी अपस्ट्रीम सार्वजनिक स्रोतों से हल न हों।
- लॉकफाइल्स CI में अपरिवर्तनीय हैं:
- npm:
package-lock.json
को कमिट करें,npm ci
का उपयोग करें। - Yarn:
yarn.lock
को कमिट करें,yarn install --immutable
का उपयोग करें। - Python: हैश किए गए
requirements.txt
को कमिट करें,--require-hashes
को लागू करें। - Gradle:
verification-metadata.xml
को कमिट करें और अज्ञात आर्टिफैक्ट्स पर विफल हों। - आउटबाउंड ईग्रेस नियंत्रण: CI से सार्वजनिक रजिस्ट्रियों तक सीधे पहुंच को ब्लॉक करें सिवाय स्वीकृत प्रॉक्सी के माध्यम से।
- नाम आरक्षण: जहां समर्थित हो, अपने आंतरिक नामों/नामस्थान को सार्वजनिक रजिस्ट्रियों में पूर्व-रजिस्टर करें।
- पैकेज प्रॉवेनेंस / अटेस्टेशन: जब सार्वजनिक पैकेज प्रकाशित करें, तो छेड़छाड़ को नीचे की ओर अधिक पहचानने योग्य बनाने के लिए प्रॉवेनेंस/अटेस्टेशन सक्षम करें।
संदर्भ
- https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610
- https://zego.engineering/dependency-confusion-in-aws-codeartifact-86b9ff68963d
- https://learn.microsoft.com/en-us/nuget/consume-packages/package-source-mapping
- https://yarnpkg.com/configuration/yarnrc/
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।