R-CON
confused
Go CLI that checks a project's dependency manifest against public registries to flag packages that could be hijacked via dependency confusion.
OVERVIEW
confused (github.com/visma-prodsec/confused), written in Go by Joona Hoikkala at Visma, automates the check behind the dependency-confusion attack class first popularized publicly in 2021: it reads a project's dependency manifest — package.json for npm, requirements.txt for pip, composer.json, a Maven pom.xml, or a Gemfile — and looks up every listed package name against the corresponding public registry.
Any internal-looking package name that resolves to nothing on the public registry is flagged as a candidate: if a company's internal build tooling ever resolves that same name from the public registry instead of its intended private one — a common misconfiguration — an attacker who publishes a same-named package publicly can get it installed and executed inside the company's build pipeline. confused only reports the gap; it does not publish anything itself.
USE CASES
Practical use cases
- 01
Scanning a client's package.json, requirements.txt, or similar manifest for internal package names missing from the public registry.
- 02
Auditing multiple ecosystems (npm, PyPI, RubyGems, Maven, Composer) in one pass across a monorepo.
- 03
Feeding a supply-chain section of the report with concrete package names that need private-registry scoping or namespace claiming.
- 04
Running as a periodic CI check to catch a newly introduced internal-looking dependency before it ships.
QUICK START
During recon on a client's codebase or CI configuration, to flag internal-looking package names that have no matching entry on the public registry and could be squatted.
- Get the client's dependency manifest(s) — package.json, requirements.txt, etc. — in scope for review.
- Install confused with go install or a prebuilt release binary.
- Run it against the manifest with the -l flag set to the matching ecosystem.
- Review the flagged package names that have no public-registry match.
- Recommend private-registry scoping or defensive namespace claiming for each flagged package — never attempt to publish a same-named package yourself.
confused -l npm package.jsonBEFORE YOU RUN IT
What to check before running it
A flagged package name is a candidate risk, not a confirmed vulnerability — it also depends on how the client's build tooling is configured to resolve private scopes, which confused doesn't test directly.
Never actually register or publish a package under a flagged name on a public registry without explicit written authorization — doing so affects a shared public registry and other users, not just the client, and can trigger real installs outside the engagement.
Manifest files can reference private, org-scoped packages by design (e.g. npm's @org/ scoping); confirm a flag is a genuine confusion risk before reporting it, not an intentional private scope.