SEC-103Recommended
Fetch private packages only from your own registry
Install packages with internal names only from your private registry. The public registry must never be able to answer for them.
How to do it
Skip this rule when you use no private packages. An attacker can publish a public package with your internal name and a higher version. Some package managers then install it, with all the build's secrets in reach. pip searches every index with no priority, so --extra-index-url next to a private index is unsafe. Give every internal npm package a scope, such as @example-shop/, and map that scope to the private registry. Register the same scope on the public registry too, so nobody else can claim it. For Python, set --index-url to one private mirror that proxies the public index and refuses your internal names from upstream. Install from the lock file as lock and audit dependencies says.
Examples
INI example
# .npmrc: the scope can only come from the private registry
@example-shop:registry=https://npm.internal.example.com/
INI example 2
# pip.conf: one index, a private mirror of the public one
[global]
index-url = https://pypi.internal.example.com/simple/
How to check
Search the build files, pip.conf, requirements*.txt and every .npmrc for extra-index-url. No match is found. Every internal npm package name starts with a scope. For each scope, npm config get @example-shop:registry prints the private registry, and the scope is owned by your organisation on the public registry.
Sources
Related rules
- Lock and audit dependencies in Security testing
- Use npm with a lock file for JavaScript packages in Software choices
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/adversarial-testing/supply-chain-and-setup/dependency-confusion">Agent Wranglers security testing playbook</a>. In code you write, add a comment next to it with the same link.