In dependency confusion, how does an attacker learn your internal package names?
answer
- a name, not a credential
- the attacker never touches your index
- look at what your repos ship
- lock files, bundles, images, stack traces
- obscurity is not a control
basics
~20 sInternal package names are not secrets. They leak through lock files in public repositories, shipped front-end bundles, container images, stack traces and CI logs. The attacker needs no access to your private index, only the name.
solid answer
~50 sThe only input a dependency confusion attacker needs is a name, and names leak constantly. A private module path shows up in a stack trace pasted into a public issue or printed on an error page; a lock file or manifest committed to an open-source repository lists internal packages including transitive internal ones; shipped JavaScript bundles and source maps carry the names of internal libraries; a published container image ships the manifest of everything installed inside it; CI logs, public design docs and job postings name internal libraries too. None of this requires touching your private index — the attacker registers the name on the public index, which is free and open to anyone. So treat internal names as public information: name obscurity is not a control, and an authenticated private index protects your artifacts, not your namespace.
go deeper
Be ready to list concrete places an internal package name becomes public: a lock file in a public repo, a shipped front-end bundle, a container image, a stack trace, a CI log. Say plainly that the attacker needs the name and nothing else.
Explain why the private index is irrelevant to disclosure, and separate a name that is merely knowable from a name someone else has already registered publicly. Note that transitive internal packages leak through lock files even when nobody imports them directly.
Show you would actually enumerate exposure rather than assume it: know which of your namespaces exist on public indexes today, who owns them, and which repositories, images and bundles you publish carry internal names.
Own the framing that names are public by default, so no programme should depend on keeping them secret. The organisational question is where the authoritative list of internal namespaces lives and who is accountable for checking it, especially after an acquisition.
## The attack needs one thing: a name Dependency confusion works because a build can be persuaded to fetch a package from a public source when the maintainers intended an internal one. Everything else in the attack is cheap and public: registering a name on a public package index costs nothing, takes minutes, and requires no relationship with the target. The scarce input is knowing which name to register — and in practice that input is rarely scarce at all. A useful way to hold this: your private index protects *artifacts*. It does not protect *names*. Authentication, network restrictions and access reviews on the index all govern who can download or publish your builds. The attacker never asks your index for anything. ## Where names leak **Public source repositories.** The most common leak is a manifest or lock file in a repository the company itself open-sourced. Lock files are especially generous: they enumerate the whole resolved graph, so internal packages that appear only as transitive dependencies of other internal packages are listed by name and version. Nobody reviews a lock file diff for disclosure. **Shipped client code.** Front-end bundles retain module identifiers, and if source maps are published the original internal package structure is fully readable. Anything you ship to a browser, you have published. **Container images.** A published image contains the installed package metadata for its language runtime. Pulling the image and listing what is installed inside is a normal, unauthenticated operation. **Stack traces and error output.** Consider a service whose private module path appears in a stack trace posted to a public forum, a status page, or an unhandled error rendered to end users. In ecosystems where the module path *is* the import identifier, that trace hands over the exact string a build will later resolve. A fresh checkout on a developer machine that has not been configured for the private path will then resolve that path through a public proxy — to whoever registered it. **CI and build logs.** Logs from a public repository's pipeline, or logs attached to a public bug report, routinely print resolution output naming every package fetched. **Humans.** Conference talks, engineering blog posts, job adverts ("experience with our internal `acme-*` platform libraries") and support tickets all name internal libraries. Post-acquisition, the acquired company's names are frequently already documented publicly before integration even begins. ## Latent versus live exposure It helps to separate two states. A name is **latently exposed** when it is known or guessable but nobody has registered it publicly — the attack is one publish away and you would not notice the transition. A name is **live** when someone else already owns it on a public index. Both matter, but they call for different urgency, and the only way to know which state a given name is in is to check the public index for it. Assuming your names are unregistered because they are unusual is not checking. ## Why obscurity fails as a control Three reasons. First, disclosure is a one-way ratchet: a name printed once in a public trace cannot be un-published, and search engines and archives keep it. Second, the guessing bar is low — organisations use consistent prefixes, so learning one internal name teaches the shape of the rest, and a company's public repositories reveal the naming convention even when no internal manifest is exposed. Third, the party who must keep the secret is everyone who has ever pushed code, pasted a log or shipped a bundle, which is not a population that can hold a secret. An insider makes it trivial: someone with nothing more than read access to the internal index — a contractor, an intern, a departing employee — can list the whole private namespace without doing anything that looks like an attack, then publish externally where the organisation has no control at all. ## What this means in an interview The expected answer is a list of concrete leak surfaces plus the reasoning above them: names are inputs, not secrets, and the attacker never touches your infrastructure to obtain them. A candidate who answers "they would have to breach our network first" has the direction of the attack backwards — the malicious package is published *outward*, to a source your build already trusts enough to consult. Fixing this is therefore not a disclosure exercise; it is a decision about what a build is allowed to resolve, which is a separate topic. What you owe here is the recognition that the name is already out, or one screenshot away from it.
- If none of our internal names have ever been registered publicly, are we fine?No — that is latent exposure, not safety. Registration on a public index is free, instant and open to anyone, so the gap between 'unregistered' and 'owned by a stranger' is one publish. The exposure is the combination of a knowable name and a build willing to consult a public source; only one of those changes when someone registers it.
- Which leak surface do teams most often miss?Lock files in the company's own public repositories, because they list internal packages that appear only as transitive dependencies — names nobody thinks of as exposed. Shipped source maps are a close second: they reconstruct the internal module layout of front-end code that was published deliberately.
- Does putting authentication on the private index reduce this exposure?Barely. Authentication stops outsiders downloading or publishing your artifacts, which is worth having, but the attack never queries your index. It also does not help against someone who legitimately holds read access and simply reads the list of names. Names leak from what you publish, not from what your index serves.
Your private index is a locked warehouse. Dependency confusion does not pick the lock — it puts up a shop sign with your warehouse's name on the public high street, and waits for your own delivery driver to walk in.
saying these in an interview costs you the question
- Our internal names are obscure enough that nobody would guess them
- The private index needs a token, so the namespace is protected
- The attacker would have to get inside our network first
- Only names in open-source repositories count as exposed
- Read-only access to the internal index discloses nothing useful