Skip to content
OPS // KITitspentest.sh

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.

Official siteBack to catalog

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.

  1. Get the client's dependency manifest(s) — package.json, requirements.txt, etc. — in scope for review.
  2. Install confused with go install or a prebuilt release binary.
  3. Run it against the manifest with the -l flag set to the matching ecosystem.
  4. Review the flagged package names that have no public-registry match.
  5. 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.json

BEFORE 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.

KEEP EXPLORING

View the whole phase →