← All posts
dependency confusionsupply chain securityvibe codingAI coding toolspackage security

How to Protect Against Dependency Confusion in Vibe-Coded Apps

O

OverMCP Team

Quick answer

Dependency confusion is a supply chain attack where a malicious package with the same name as an internal private package is published to a public registry. Vibe-coded apps are especially vulnerable because AI tools often suggest package names that might already exist publicly, or they might accidentally include internal-scope packages without proper scoping. To protect your app, always scope your internal packages (e.g., @mycompany/package-name), lock dependency versions, and use a registry that enforces private package resolution first.

What is dependency confusion and why should vibe-coders care?

Dependency confusion (also known as namespace confusion or substitution attack) happens when a package manager resolves a dependency name to a public registry instead of a private one. For example, if your app uses an internal package called "auth-utils" and someone publishes a malicious "auth-utils" to npm, your build might pull the malicious version instead of your private one. This is particularly dangerous for vibe-coded apps because AI coding tools like Cursor, Bolt.new, and Lovable often generate code that references packages by name without explicit scoping. A simple npm install auth-utils might install the wrong thing.

In 2024, security researchers found that many AI-generated projects included package names that were typosquatted or already existed as malicious packages. The speed of vibe coding means developers rarely double-check every dependency name. This blog post walks you through how to prevent dependency confusion attacks in your AI-built apps.

What to check first

Before you dive into fixes, audit your existing vibe-coded project for potential dependency confusion risks. Here's a checklist:

  • [ ] List all dependencies in package.json (or equivalent) and separate internal vs. public packages.
  • [ ] For each internal package, check if it's scoped (e.g., @company/package). If not, it's vulnerable.
  • [ ] Verify that your package manager is configured to resolve private packages before public ones (e.g., .npmrc registry settings).
  • [ ] Check if any dependency names are common words that could be easily squatted.
  • [ ] Review your lock file (package-lock.json, yarn.lock, pnpm-lock.yaml) to ensure all resolved versions match your private registry.
  • [ ] Use a free AI app security scanner to detect exposed secrets or misconfigurations that might hint at dependency issues.
  • [ ] If your app was built with Bolt.new or similar, check if it auto-installed any packages you didn't explicitly approve.
  • Step-by-step fix: How to secure your vibe-coded app from dependency confusion

    Step 1: Scope all internal packages

    If your internal package isn't scoped, rename it now. For npm, scoped packages follow the format @scope/package-name. For example, if you have an internal package called "my-app-utils", rename it to @mycompany/my-app-utils. Update all references in your codebase.

    Step 2: Configure your package manager to block public packages with the same name as your scoped packages

    For npm, add a .npmrc file with:

    @mycompany:registry=https://registry.npmjs.org/
    //registry.npmjs.org/:_authToken=${NPM_TOKEN}

    But more importantly, use a private registry like npm Enterprise, GitHub Packages, or Verdaccio. Then configure your package manager to only resolve scoped packages from your private registry.

    For yarn, use .yarnrc.yml:

    npmScopes:
      mycompany:
        npmRegistryServer: "https://npm.pkg.github.com"

    Step 3: Pin dependency versions and use lockfiles

    Never use ranges like "^1.0.0" for internal packages. Always pin exact versions:

    "@mycompany/auth-utils": "1.2.3"

    Commit your lockfile to version control. This ensures that every install uses the exact same version, even if a malicious package is later published.

    Step 4: Verify package integrity

    Use Subresource Integrity (SRI) checks or npm's integrity field in lockfiles. For npm, you can run npm audit and check for unexpected changes. For critical packages, consider using tools that verify package hashes.

    Step 5: Monitor for suspicious packages

    Set up continuous monitoring. A tool like OverMCP's continuous security monitoring can alert you if a new package with the same name as your internal package appears on a public registry. You can also use the secret leak scanner to check if any tokens or credentials are accidentally exposed in your dependencies.

    Step 6: Remove unused dependencies

    AI-generated code often includes unused packages. Run npm prune or similar to remove them. Fewer dependencies mean fewer attack surfaces.

    Common mistakes vibe-coded apps make

  • No scoping: AI tools often generate imports like import { something } from 'my-internal-lib' without the @scope prefix. This is a direct invitation for dependency confusion.
  • Using generic package names: Names like "utils", "helpers", "config" are prime targets for typosquatting. AI tends to suggest these generic names.
  • No lockfile committed: Many vibe-coded projects start as a quick prototype and .gitignore includes lockfiles. This is dangerous because you lose reproducibility.
  • Trusting AI suggestions blindly: If Cursor or Copilot suggests installing a package, verify it exists on your private registry first. I've seen cases where AI suggested a package name that was already a malicious package on npm.
  • Not using a private registry at all: Solo developers often skip setting up a private registry and rely on npm's public registry even for internal code. This is fine for open-source projects, but if your internal code is proprietary, using a private registry is essential.
  • How OverMCP helps

    OverMCP is designed to catch exactly these kinds of supply chain issues in vibe-coded apps. When you connect your Vercel project, OverMCP scans your dependencies and checks for signs of dependency confusion, exposed secrets, and misconfigurations. It's like having a security reviewer that understands the unique risks of AI-generated code.

    FAQ

    What is dependency confusion in simple terms?

    Dependency confusion occurs when a package manager mistakenly installs a public package instead of a private one because they share the same name. Attackers can publish malicious packages to public registries with names that match your internal packages, and your build might download the malicious version.

    How do I know if my vibe-coded app is vulnerable to dependency confusion?

    Check your package.json for any dependencies that are not scoped (prefixed with @yourcompany/). Also, verify that your package manager is configured to resolve private packages from a private registry first. If you use generic names like "auth" or "db-utils" without scoping, you are vulnerable.

    Can AI coding tools cause dependency confusion?

    Yes. AI coding tools like Cursor, Bolt.new, and Lovable often generate code that references packages by name. If the AI suggests an unscoped name that coincidentally matches an existing public package, your app could inadvertently pull the public version. Always review AI-generated imports and scope your packages.

    ---

    Protect your vibe-coded app from supply chain attacks. Use [OverMCP's free AI app security scanner](https://www.overmcp.com/) to check for dependency confusion and other vulnerabilities before your next deploy.

    Is your app secure?

    Free scan in 30 seconds. No signup needed.

    Scan My App Free