Skip to content

🚨 Security Warning for MCP Server Developers and Users: Systematic Forking as a Supply-Chain Attack Vector #3635

Closed as not planned

Description

@CSCSoftware

I'm the developer of an MCP server (AiDex β€” code indexing with Tree-sitter, github.com/CSCSoftware/AiDex). I recently discovered that an organization called iflow-mcp is systematically forking hundreds of MCP servers on GitHub, republishing them under their own npm scope (@iflow-mcp/) and on PyPI, and distributing them through their own "marketplace" β€” without ever contacting the original authors.

But the real problem isn't the fork itself. The real problem is security.


What's happening

The forks are published under the pattern @iflow-mcp/originalauthor-projectname. The familiar name of the original creates trust β€” but the code the user actually gets is entirely under a third party's control. Nothing prevents that third party from modifying the code before publishing.

Why MCP servers are particularly dangerous

An MCP server is not a harmless plugin. By design, it has deep access:

  • It reads your source code, navigates your filesystem, receives file contents
  • It can see .env files, API keys, SSH keys, credentials, and proprietary code
  • It communicates via stdio directly with the AI client β€” meaning it can manipulate tool responses
  • It often runs with the same permissions as the user

A trojanized MCP server could silently exfiltrate sensitive data while doing exactly what it's supposed to do β€” indexing or analyzing your code. You see the tool working normally. You don't see the data leaving.

Even worse: a manipulated server could feed the AI assistant deliberately false information β€” suggesting insecure code patterns, hiding vulnerabilities, or redirecting the AI to the wrong files.

The broken chain of trust

The problem is systemic:

  1. Developer A publishes an MCP server as open source
  2. Organization X forks it, republishes it under their own scope
  3. A user finds the package in X's marketplace, recognizes the familiar name, installs it
  4. The user believes they're running the original β€” but they're running code that X could have modified in any way

This is a classic supply-chain attack. And it works particularly well because MCP servers are new, and many users haven't yet learned to verify where their tools actually come from.


What you can do as an MCP server developer

  1. Origin check at startup: Check your own package name (package.json, process.env.npm_package_name) and installation path (__dirname). If a foreign scope appears, display a clear warning:

    ⚠️ This appears to be an unofficial redistribution of [project].
    Official package: npm install [original-package]
    Repository: [original-url]

  2. Build signature: Embed a hash or signed identifier during your build process. A republisher who doesn't replicate your exact build pipeline cannot reproduce it.

  3. Registry check: A quick HTTP request at startup to the npm registry can reveal whether the package is running under a foreign scope.

What you can do as a user

  • Always install MCP servers directly from the original project, never through third-party marketplaces
  • Check the npm scope: @iflow-mcp/cscsoftware-aidex is NOT the same as aidex-mcp
  • Look at GitHub to verify whether a repository is a fork and who the actual author is
  • Be especially cautious with MCP servers that have deep filesystem access

Please share this post. The more MCP developers and users know about this attack vector, the harder it becomes to exploit. The MCP ecosystem is growing rapidly β€” but without awareness of supply-chain security, we're building on sand.

If you're affected: speak up. Check whether your project appears under github.com/iflow-mcp/. The more voices, the sooner npm and GitHub will act.

Original project: https://github.com/CSCSoftware/AiDex
Their fork on npm: https://www.npmjs.com/package/@iflow-mcp/cscsoftware-aidex

β€” Uwe Chalas, author of AiDex (aidex-mcp on npm)

Activity

  1. raye-deng commented on Mar 18, 2026

    @raye-deng

    This is a great write-up and an important warning. The forking-and-republishing pattern you describe is essentially the same trust problem we see with AI-generated code β€” but at a different layer.

    In our experience building CI tooling for AI-assisted development, one of the most common failure modes is what we call "phantom dependencies": an AI coding assistant generates an import for a package that looks plausible (familiar name, reasonable scope) but either does not exist on the registry, has been renamed, or β€” worst case β€” has been published by someone other than who you would expect.

    The MCP supply-chain scenario you describe is the deliberate exploitation of this exact trust gap. And you are right that MCP servers are particularly dangerous because of the filesystem and credential access they get.

    One practical addition to the defenses you listed: a CI-level registry validation step that checks every dependency against a known-good allowlist or verifies publisher identity before install. We added this to our scanner after seeing AI tools auto-install packages from unfamiliar scopes without any verification. It catches both the accidental case (AI hallucinated a package name) and the malicious case (typosquatting / scope impersonation).

    For anyone wanting to add this kind of check to their pipeline: npx @opencodereview/cli scan . --sla L1 β€” it validates imports against actual registries as part of the PR review.

  2. FransDevelopment commented on Mar 24, 2026

    @FransDevelopment

    Great write-up @CSCSoftware β€” the attack chain you described (fork β†’ republish under familiar name β†’ user trusts the name, runs modified code) is the exact pattern that a cryptographic operator registry prevents.

    The three defenses you listed (origin check, build signature, registry check) are all client-side heuristics β€” they help, but they require every developer and every user to independently verify. That's the same "trust on first use" problem TLS had before CAs.

    The Open Agent Trust Registry (OATR) adds the missing server-side piece: MCP server operators register Ed25519 keypairs and prove domain ownership. A signed manifest is compiled every 50 minutes via CI. Any client can verify a server operator's identity with one fetch + one signature check.

    In the attack you described, the defense would work like this:

    1. Original developer (you, CSCSoftware) registers in OATR with your Ed25519 key + domain verification
    2. MCP client checks the server's claimed operator against the OATR manifest before connecting
    3. The fork under @iflow-mcp can't produce a valid OATR attestation for your identity β€” the cryptographic proof fails, and the client flags it

    This complements @raye-deng's CI-level npx @opencodereview/cli scan approach nicely β€” their tool catches it in the build pipeline, OATR catches it at connection time. Defense in depth.

    The registry uses FROST 3-of-5 threshold governance so no single entity controls who gets verified. 7 issuers active so far. MIT licensed.

    Would be interested in your thoughts on whether MCP clients should check operator attestations as part of their server discovery flow.

  3. CSCSoftware commented on Mar 24, 2026

    @CSCSoftware
    Author

    Thanks for the pointer to OATR β€” cryptographic identity verification is an interesting approach.

    However, I think the real solution has to come from npm and GitHub themselves, not from an additional trust layer on
    top. The trust chain already exists: developer (verified GitHub account, 2FA) β†’ GitHub (commit signing, repository
    ownership) β†’ npm (account linked to GitHub) β†’ client. The problem isn't that we lack a trust infrastructure β€” it's
    that the existing chain isn't enforced end to end.

    npm could detect scope impersonation β€” @iflow-mcp/cscsoftware-aidex literally contains the original author's name,
    that's a detectable pattern. GitHub could flag systematic bulk-fork-republishing behavior. These are the right central
    authorities to act because users already trust them and already have verified accounts there.

    Adding another registry that itself needs to be trusted (who are the 7 issuers? who governs the governance?) doesn't
    solve the root problem β€” it shifts it. What we need is a secure supply chain from developer to client through the
    platforms that are already in place.

  4. FransDevelopment commented on Mar 24, 2026

    @FransDevelopment

    @CSCSoftware β€” fair point, and I think we're talking about different layers. You're right that the distribution-level problem (forked packages republished under a misleading npm scope) should be caught by npm and GitHub themselves. They have the data to detect scope impersonation and bulk-fork-republish patterns, and they're the right authorities to enforce it since users already trust them.

    My earlier comment was addressing the runtime layer: once a client has connected to an MCP server, can it verify the operator's identity? That's a different problem from "is this npm package authentic?" and OATR is designed for that runtime verification step. But it doesn't solve the distribution attack you described, and I should have been clearer about that distinction.

    Appreciate the detailed write-up. The supply chain angle is the more immediate threat for most developers today.

  5. khalidsaidi commented on Mar 24, 2026

    @khalidsaidi

    A2ABench has an accepted answer for this imported thread.

  6. xlyoung commented on Jun 7, 2026

    @xlyoung
  7. SarveshShukla23 commented on Oct 17, 2026

    @SarveshShukla23

    The stdio privilege inheritance and --allow-dangerous sandbox bypasses called out here are the exact vectors we benchmarked against the executable Berkeley Function Calling Leaderboard (BFCL). When an MCP server runs as a local stdio child process, static allowlists still pass post-authentication indirect prompt injections (write_file mutations and .env/SSH key exfiltration). We built an inline FIPS 140-3 Go interceptor (getrcf.dev/product) that sits inside the stdio pipe, strips unapproved schemas in flight (--ghost-mode=hitl), blocks >6.2 bits/byte Shannon entropy exfiltration, and pre-detonates arguments inside an ephemeral zero-dependency wazero WebAssembly micro-VM in 816msβ€”catching 108 destructive swarm calls with 0 developer workflow disruptions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions