MCP servers are the new attack surface
An MCP server is a program your AI assistant starts on your machine, with your environment, your files and whatever tokens you put in its config. It is installed by name, often re-downloaded on every launch, and its tool descriptions are read by a model that does what text tells it to. In most teams nobody reviewed any of that. It was one line in a JSON file, pasted from a README.
In 2025 attackers noticed. Each of the incidents below is public, each one is small, and together they describe the whole surface: the package, the transport, the tool and the agent's own reach.
Five incidents, five layers
The package: a server that blind-copied every email
In September 2025 an npm package called postmark-mcp, which let an assistant send email through Postmark, turned malicious. Postmark's own statement is direct: "A malicious actor created a fake package on npm impersonating our name, built trust over 15 versions, then added a backdoor in version 1.0.16 that secretly BCC'd emails to an external server." Postmark had never published an MCP server on npm.
The detail that matters is "built trust over 15 versions". An MCP server launched as npx postmark-mcp with no version resolves the latest release every time the host starts. Fifteen good versions earned the line in the config file; the sixteenth arrived on its own.
The transport: a proxy that ran the server's commands
mcp-remote lets a local assistant talk to a remote MCP server. In July 2025 it got CVE-2025-6514, rated 9.6: connecting to an untrusted server could execute operating system commands on the client, through "crafted input from the authorization_endpoint response URL." Versions from 0.0.5 up to 0.1.16 were affected. The server you connect to is part of your attack surface, and so is every hop of the connection.
The developer tool: a debugger anyone could drive
The MCP Inspector, used to test servers during development, shipped CVE-2025-49596, rated 9.4: the "lack of authentication between the Inspector client and proxy" allowed unauthenticated requests to launch MCP commands over stdio. Fixed in 0.14.1.
The tool: a sandbox with a prefix bug
The reference filesystem server restricts the model to allowed directories. CVE-2025-53110 showed that earlier versions "could allow access to unintended files in cases where the prefix matches an allowed directory." A path check that compares prefixes treats /home/me/project-secrets as inside /home/me/project. Fixed in 2025.7.1.
The agent: a public issue that read private repositories
In May 2025 researchers showed that a malicious issue in a public repository could steer an agent using a GitHub MCP integration. Asked to look at open issues, the agent read the planted text, followed it, and made information from the user's private repositories public. The researchers placed the root cause in the setup rather than the server's code: tokens with access across many repositories, and agents left on "always allow". They also said plainly that "there is no easy solution to the architectural issue."
A sixth story belongs here, although it is filed under supply chain. The malicious Nx versions of August 2025 reportedly used the AI coding CLIs already installed on developer machines, started with flags that switch off their permission prompts, to search for secrets. The agent did not need a vulnerability. It needed someone to have removed its guardrails.
What the incidents have in common
Strip the names off and five weaknesses remain:
- Unpinned launches. The host runs whatever the registry serves today.
- Vulnerable versions. A known CVE in the server or the proxy.
- Too much reach. A filesystem mount at the home directory, a token that covers every repository.
- Secrets in the config. A token typed into an
envblock that sits next to project files. - Untrusted text in the model's context. Tool descriptions, tool results and issue bodies that the model treats as instructions.
The first four are visible in files on disk. The fifth is visible only partly, and it is worth being exact about which part.
What Vulkro checks
Your MCP configs: vulkro mcp-audit
vulkro mcp-audit reads the MCP configs on your machine and in your project (Claude Desktop, Cursor, Windsurf, VS Code, Cline, Continue, Gemini and a project's .mcp.json) and reports:
MCP-001: a server launched throughnpxoruvxwith no version pin, thepostmark-mcpshape. High when the server has filesystem scope.MCP-002: a git install pointed at a mutable ref.MCP-003: a filesystem server mounted at/, the home directory or a shallow folder under it. A prefix bug like CVE-2025-53110 matters far less when the allowed root is one project folder.MCP-004: a credential literal in anenvblock instead of a${VAR}reference, Critical when it matches a real provider format.MCP-005andMCP-007: a cleartexthttp://endpoint, including one passed to a proxy such asmcp-remoteon its command line.MCP-006: a pinned server version on the compromised-release list.
It is part of the Free tier, it reads local files only, and it exits non-zero on findings so it can run in CI.
Your repository: vulkro scan
The regular scan reads the agent files in a repository as well as its code:
AGENT-005flags the same unpinned or plaintext MCP server in a committed config, andAGENT-006a server name defined twice with two different commands.AGENT-001andAGENT-002flag instruction files (CLAUDE.md,AGENTS.md, skills) that try to override the operator or hide instructions in invisible characters or comments.AGENT-004flags hooks that fetch from the network, pipe into a shell or read a credential path.AGENT-007flags a credential path handed to a hook or MCP server, andAGENT-008a live credential pasted into an instruction file.AGENT-AUTONOMY-001flags an agent CLI started with a permission-bypass flag, the Nx shape.- When an MCP server or proxy is a dependency in your lockfile, it is matched against advisories like any other package. A project pinned to
mcp-remote0.1.10 comes back with CVE-2025-6514 at Critical, andpostmark-mcp1.0.16 as a known-malicious package.
The server you are building: vulkro scan-mcp-server
If you write MCP servers, vulkro scan-mcp-server reads their source (TypeScript and Python SDKs) for eight shapes, including tool descriptions built from non-literal input (MCP-SERVER-001), a caller-supplied path, URL or command reaching a sensitive sink without validation (MCP-SERVER-002), descriptions computed at request time so they can change after approval (MCP-SERVER-003) and sensitive tools with no auth (MCP-SERVER-008).
An honest limit: MCP-SERVER-002 counts a resolve-then-startswith check as validation. CVE-2025-53110 is proof that such a check can itself be wrong. The rule finds the handler with no check at all; it does not prove that a check you wrote is correct.
The text the model reads: Vulkro Labs
The fifth weakness, instructions hidden in text, is where Vulkro Labs comes in. warden scans a server's tool manifest for prompt injection, tool poisoning, hidden characters, tool shadowing and exfiltration sinks, and with --result it scans untrusted content an agent received: a tool result, a fetched page, an issue body. lock fingerprints the tools you approved, and drift reports what changed since, field by field. inspect gives a single verdict on a server before you add it. The Labs commands are free and keyless and run on your machine.
What none of this does is see the scope of a token. The GitHub case was about a token with access to every repository and an agent allowed to use it without asking. A config file does not say what a token can reach, so no file scan can rank that risk for you. The fixes the researchers recommend are operational: one repository per session, least-privilege tokens, and confirmation on actions that write in public.
Start with one command
Run vulkro mcp-audit on your own machine. It takes seconds, needs no account, and the first finding is usually an unpinned server you added months ago and forgot. Then run vulkro scan on the repository your agent works in.
Vulkro Core covers the code and configs; Vulkro Labs covers what the agent reads. To install, start here.
Sources
- Postmark, Information regarding the malicious postmark-mcp package, September 2025
- GitHub Advisory Database, GHSA-6xpm-ggf7-wc3p (CVE-2025-6514): mcp-remote OS command injection, July 2025
- GitHub Advisory Database, GHSA-7f8r-222p-6f5g (CVE-2025-49596): MCP Inspector proxy lacks authentication, June 2025
- GitHub Advisory Database, GHSA-hc55-p739-j48w (CVE-2025-53110): filesystem server path validation bypass, July 2025
- DevClass, Researchers warn of prompt injection vulnerability in GitHub MCP with no obvious fix, 27 May 2025
- The Hacker News, Malicious Nx packages in s1ngularity attack, August 2025
