Large Language ModelsGenerate imagesGenerate videos

OWASP MCP Top 10: Every Risk Explained With Examples

A plain-English walk through all ten risks in the OWASP MCP Top 10, from leaked tokens and tool poisoning to shadow servers and context over-sharing. Each entry has a documented attack, a clear fix, and a one-week plan to apply them in order.

OWASP MCP Top 10: Every Risk Explained With Examples
Cristian Da Conceicao
Founder of Picasso IA

A single MCP server can hand an AI agent your repositories, your inbox, and your database in one afternoon, and approving it often takes one click. That convenience is exactly what the OWASP MCP Top 10 exists to push back on. It names the ten risks most likely to sink a Model Context Protocol deployment, from leaked tokens to servers nobody on the security team knows about. This article goes through every entry in order, shows what the attack looks like with a real or documented example, and closes each section with the fix worth doing first.

The list comes from the OWASP MCP Top 10 project, version 2025, led by Vandana Verma Sehgal. The project page currently lists it in a beta and pilot testing phase, so wording and ordering may still move. Treat the ten entries as a shared vocabulary rather than a finished standard.

What the OWASP MCP Top 10 Is

MCP is the protocol that lets a model call tools. An MCP client (the app hosting the model) connects to one or more MCP servers, and each server exposes tools, resources, and prompts the model can use. Every one of those connections is a trust decision: the server trusts the client to behave, the client trusts the server's descriptions and outputs, and the model trusts whatever text lands in its context window.

The Top 10 maps the places where that trust breaks. Here are all ten at a glance:

IDRiskPlain meaningCheapest first fix
MCP01Token Mismanagement and Secret ExposureCredentials leak through code, logs, or contextShort-lived tokens and secret scanning
MCP02Privilege Escalation via Scope CreepPermissions grow past what the task needsLeast privilege with expiry
MCP03Tool PoisoningA tool's description or output carries hidden instructionsPin and hash tool definitions
MCP04Software Supply Chain Attacks and Dependency TamperingA malicious or hijacked package becomes your serverInventory and pin every dependency
MCP05Command Injection and ExecutionUntrusted text reaches a shellNo shell, argument lists, validation
MCP06Intent Flow SubversionRetrieved content redirects the agent's goalTreat retrieved text as data, approve writes
MCP07Insufficient Authentication and AuthorizationServers do not check who is callingOAuth 2.1 and per-tool checks
MCP08Lack of Audit and TelemetryNobody can see what the agent didLog every tool call
MCP09Shadow MCP ServersUnapproved servers run outside governanceInventory and allowlist
MCP10Context Injection and Over-SharingContext leaks across users or tasksIsolate context per user

💡 Naming note: the project's overview page labels the sixth entry "Prompt Injection via Contextual Payloads", while its detail page for MCP06 is titled "Intent Flow Subversion". Both point to the same slot, and this article uses the detail page title.

Secrets, Permissions and Poisoned Tools

MCP01: Token Mismanagement and Secret Exposure

A hand pulling a handwritten sticky note off the edge of a monitor in a cluttered home office

This is the oldest problem in security wearing a new coat. Hard-coded API secrets, long-lived tokens, and credentials pasted into prompts or config files end up in logs, chat history, and the model's memory. Once a secret sits inside the context window, a prompt injection only has to ask the model to repeat it.

OWASP's scenario: a developer commits a secret during testing, the MCP server reads it at startup, and the assistant later prints it in a reply to someone else.

What to do:

  • Issue short-lived, narrowly scoped tokens instead of permanent ones.
  • Run secret scanning on repositories and CI pipelines.
  • Keep secrets out of tool descriptions, system prompts, and example payloads.
  • Rotate immediately after any suspected exposure.

💡 Tip: secrets with a fixed prefix are easy to hunt. PicassoIA API secrets start with pia_sk_, so a one-line scanner rule can flag them in any repository. Add the same kind of rule for every provider you use.

MCP02: Privilege Escalation via Scope Creep

Overloaded steel ring holding dozens of mismatched metal tags on a rusted hook in a concrete corridor

Permissions start tight and loosen over time. A token made for one repository gets widened "just for this sprint", an agent gains write access because read access was annoying, and nobody revokes anything. The model ends up holding far more power than any single task needs, so one bad instruction does far more damage.

OWASP's scenario: a prompt injection hidden in a public GitHub issue redirects an agent with broad repository access, and the agent copies private code into a public pull request.

What to do:

  • Design for least privilege: one scope per task, not one scope per team.
  • Put an automatic expiry on every grant.
  • Split read tools from write tools so approvals can differ.
  • Review agent permissions on a fixed schedule, the same way you review human access.

MCP03: Tool Poisoning

A gloved hand hesitating before a rusted counterfeit wrench hanging among clean tools on a workshop pegboard

Models pick tools by reading their names and descriptions, which makes those descriptions an attack surface. A poisoned tool hides instructions in its metadata, schema, or output. In April 2025, Invariant Labs demonstrated the attack with an innocent addition tool whose hidden description told the agent to read a local MCP config file and an SSH private file, then pass the contents along in a spare parameter while the reply talked about arithmetic.

A nastier variant is the rug pull: a tool behaves well when you approve it, then changes its description after installation.

What to do:

  • Pin tool versions and store a hash of each description at approval time.
  • Alert on any change to a description or schema.
  • Show users the full tool description, not a shortened summary.
  • Prefer signed tools from publishers you can name.

MCP04: Supply Chain Attacks and Dependency Tampering

Aerial view of a conveyor belt of identical parcels with one resealed box being inspected by a worker with a flashlight

An MCP server is code someone else wrote, pulled from a registry. A compromised or impostor package gets the same access you grant the real one. In September 2025 an npm package called postmark-mcp copied a genuine Postmark integration and added a single line that sent a blind copy of every outgoing email to an address the attacker controlled. Researchers at Koi Security reported it as the first malicious MCP server seen in the wild, and Snyk's write-up walks through the details. It was pulling roughly 1,500 downloads a week before it was removed.

What to do:

  • Keep an AI bill of materials: every server, its version, and where it came from.
  • Pin exact versions and read the diff before each upgrade.
  • Install only from publishers you can verify, and prefer signed releases.
  • Run dependency scanning before a server is approved, and run unfamiliar ones in a container with no network access until reviewed.

MCP05: Command Injection and Execution

Agents build commands from text. When that text is attacker-controlled (an issue comment, a filename, a web page), the shell does the rest. According to Cycode's breakdown of the list, CVE-2025-6514 in mcp-remote carried a CVSS score of 9.6, affected a package with more than 437,000 downloads, and allowed OS command injection. It sits on the border between this entry and MCP04.

The difference between risky and safe is often one line:

import re
import subprocess

# Risky: untrusted text is spliced into a shell string
subprocess.run(f"git log --author={author}", shell=True)

# Safer: fixed command, argument list, validated input, no shell
if not re.fullmatch(r"[A-Za-z0-9._@][A-Za-z0-9 ._@-]{0,63}", author):
    raise ValueError("invalid author")
subprocess.run(["git", "log", "--author", author], shell=False, check=True)

What to do:

  • Prefer parameterized APIs over shell commands.
  • When a command is unavoidable, use argument lists and strict input validation.
  • Apply a deny-by-default policy for which commands a server may run.
  • Sandbox local servers so a successful injection stays inside a small box.

Hijacked Intent and Open Doors

MCP06: Intent Flow Subversion

A foggy rural crossroads with a twisted signpost pointing in contradictory directions and a lone car waiting

The agent reads a web page, an issue, or a PDF, and that content contains instructions. A model cannot reliably tell data from commands, so it may follow them. The result is goal hijacking: the agent still looks like it is doing your task while it serves someone else's.

The clearest real case came from Invariant Labs in May 2025, against the official GitHub MCP server. An attacker opens a malicious issue in a public repository. When the owner asks their agent to look at the open issues, the agent reads the issue, gets injected, pulls data from private repositories into its context, and publishes it in a pull request on the public one. The researchers called it a toxic agent flow, said it was an architectural issue rather than a bug in the server code, and suspected that many people choose an "always allow" approval policy, which removes the human check.

What to do:

  • Anchor the original goal and check each planned action against it.
  • Add an independent guardrail model that sees only the user's request and the proposed tool call.
  • Tag retrieved content as untrusted data and tell the model to treat it as passive text.
  • Require human approval for anything that writes, sends, or deletes, and never default to "always allow".

💡 Tip: a classifier is one layer, not the whole defense. Llama Guard 4 12B on PicassoIA is a content moderation model that can screen text before it reaches your agent, but it is a safety classifier and not a dedicated injection detector, so keep approvals and least privilege in place.

MCP07: Insufficient Authentication and Authorization

A steel server room door propped open with a red rubber wedge beside a dark badge reader

Some MCP servers never ask who is calling. An exposed endpoint with no authentication lets anyone invoke its tools, and a server that checks identity once but never checks permissions per call lets a low-privilege user trigger high-privilege actions.

A concrete case is CVE-2025-49596 in Anthropic's MCP Inspector, rated CVSS 9.4. Versions below 0.14.1 had no authentication between the Inspector client and its proxy, so unauthenticated requests could launch commands over stdio. Chained with a browser flaw and cross-site request forgery, simply visiting a malicious website could run code on a developer machine.

What to do:

  • Use OAuth 2.1 with multi-factor authentication for people.
  • Validate the token audience per server, so a token minted for one server fails on another.
  • Give services managed identities instead of shared accounts.
  • Bind local servers to localhost and require a token even there.
  • Check permissions per tool call, not once per session.

Blind Spots and Shadow Servers

MCP08: Lack of Audit and Telemetry

An empty night-shift security desk with a blank logbook and switched-off monitors

Without logs, every other risk on this list becomes invisible. Token theft, command injection, and prompt injection can all happen with nothing recorded, and incident response turns into guesswork. This entry amplifies the other nine.

A useful tool-call log is small. For each call, record:

FieldWhy it matters
Who or what made the callTies the action to a user, agent, or service
Which server and toolShows which capability was used
Arguments (hashed or redacted)Lets you replay intent without storing secrets
Result size and statusExposes bulk reads and silent failures
Timestamp and session IDRebuilds the order of events

What to do:

  • Write logs to immutable storage the agent cannot edit.
  • Alert on patterns, such as a burst of private reads followed by a write to a public place.
  • Watch whole sequences of actions, not just single calls.

MCP09: Shadow MCP Servers

A forgotten server tower and router hidden under a desk in a cluttered supply closet

A developer spins up an experimental server on a Friday, it keeps running with default credentials and open settings, and by Monday it holds real data. Nobody approved it, nobody monitors it, and it never appears in an inventory. That is a shadow MCP server.

Where to look first:

  • MCP config files on developer laptops and in shared repositories.
  • CI/CD pipelines and container registries.
  • Cloud accounts, for listeners on unusual ports.
  • Desktop apps and editor extensions that can add their own server entries.

What to do:

  • Run continuous scanning of those places, not a yearly audit.
  • Enforce an allowlist so a client refuses unknown servers.
  • Ban default credentials at the platform level.

MCP10: Context Injection and Over-Sharing

A glass-walled meeting room with a crowded whiteboard visible from the corridor as colleagues walk past

Shared or persistent context windows leak. When one agent serves several users or tenants and the context is not isolated, one person's data can appear in another person's session. The OWASP scenario is a single agent serving many users that leaks one user's personal data into a different session.

It has happened to a real product. BleepingComputer reported that Asana warned users in June 2025 that a logic flaw in its new MCP feature exposed data from some organizations to others. Roughly 1,000 customers were affected, and Asana switched the feature off from June 5 to June 17 while it fixed the bug. It was a logic error, not a hack, and the flaw had been live for about a month before Asana found it.

What to do:

  • Give every user and tenant its own scoped context window.
  • Make memory ephemeral by default and expire it fast.
  • Enforce tenant isolation in the protocol layer, not only in the prompt.
  • Redact personal data before anything is stored for later reuse.

Which Risks to Fix First

You cannot close all ten in a week, so start where the damage is largest and the work is smallest.

Highest Impact, Lowest Effort

  • MCP01: turn on secret scanning and shorten token lifetimes.
  • MCP07: put authentication in front of every server, including the ones on localhost.
  • MCP09: list every server your team runs today. You cannot protect what you have not counted.

Slower but Necessary

  • MCP03 and MCP04: pinning and hashing take real setup, but they stop silent changes.
  • MCP06: approvals and guardrails need design work and constant tuning.
  • MCP08 and MCP10: logging and isolation touch architecture, so plan them as projects.
  • MCP02 and MCP05: these sit in between; tighten scopes while you review each server.

A One-Week Hardening Plan

DayTaskRisks closed
MondayInventory every MCP server and client configMCP09
TuesdayScan repos for secrets, rotate anything old, shorten token lifetimesMCP01
WednesdayAdd authentication and per-tool permission checksMCP07, MCP02
ThursdayPin versions, hash tool descriptions, set change alertsMCP03, MCP04
FridayTurn on tool-call logging and require approval for writesMCP08, MCP06

💡 Common mistakes: approving "always allow" to cut clicks, trusting a server because it has many downloads, and logging everything except the tool arguments that matter.

Make Your Own Security Visuals

A security checklist lands harder when people can picture it. Every image in this article uses a plain, physical stand-in for an abstract flaw: a crowded ring of passes for scope creep, a propped-open door for weak authentication, a blank logbook for missing audit trails. You can build the same kind of visuals for your own threat models, training decks, and internal wikis.

Try it on PicassoIA. Open a text-to-image model such as Seedream 5 Pro, Qwen Image 3, or GPT Image 2, describe one real object that stands in for your risk, and add the lighting and lens you want. Generate a few variations, pick the sharpest, and drop it into your next review. If you write the documentation too, the large language models on PicassoIA can help you draft the first version before you edit it by hand.

Share this article