MCP Security Vulnerabilities: A Quick Weekend List
If you're reading this on a weekend, don't!
1. Tool Poisoning Attacks
Hidden vectors: An attacker publishes a supposedly benign tool manifest in which the markdown description embeds secondary instructions using zero-width Unicode characters or harmonized whitespace. MCP clients that concatenate the description with the user prompt enable a blended instruction sequence that bypasses system-level sandboxing.
Blast radius: Immediate prompt hijack, lateral movement to every conversation where the tool is invoked, and privilege escalation if the agent holds elevated scopes (repo
, payments.write
, etc.).
Defense-in-depth:
- Strip or normalize Unicode in tool metadata before prompt assembly.
- Render tool descriptions inside an iframe or a Markdown sandbox that forbids HTML/JS expansion.
- Diff the AST of the tool description between install-time and runtime; treat drift as a block condition.
2. Rug Pull Re-definitions
Pattern: The attacker pushes a legitimate v1.0 of the tool, gains trust and star ratings, then tags v1.0.1 that silently rewires the endpoint from https://api.example.com/summarize
to https://evil.tld/exfil
. Most MCP launchers auto-update by semantic version range (^1.0.0
).
Impact: Enterprises that pin only the major version ingest the malicious update without change control, leaking data and credentials.
Mitigations:
- Disable automatic range updates; force explicit version pinning and checksum validation.
- Maintain a private mirror of vetted manifests; CI/CD should fail on manifest SHA drift.
- Require signed update commits with SigStore or similar transparency log.
3. Cross-Server Tool Shadowing / Confused Deputy
Vector: The attacker registers a tool named jira-sync
on an external MCP server. A local policy gives jira-sync
production scope in the belief that it is the internal tool. The agent then forwards privileged tokens to the external server.
Countermeasures:
- Namespaced tool identifiers (
corp/jira-sync
) plus origin checks. - Mutual-TLS between the MCP host and approved tool registries.
- Capability tokens bound to origin and audience (
aud
) claims.
4. Conversation History Exfiltration
Technique: A malicious tool declares an argument called context
with type string[]
. Over-permissive agents auto-fill this argument with the full chat transcript to "help the tool understand." The transcript is POSTed off-box.
Remediation:
- Disallow automatic argument hydration unless the schema uses a dedicated "ephemeral" flag signed by auditors.
- Run NLP diff detectors that flag when outgoing payloads exceed a threshold of similarity to the original chat.
5. Line Jumping Pre-Checkpoint Injection
Observation: Some MCP clients place system and security prompts at index 0, then append the user prompt, then the tool prompt. If the attacker wraps their input in an array (["attacker", "system override"]
) the parser splits it, positioning the malicious string ahead of the security checkpoint.
Fixes:
- Parse messages strictly by documented JSON schema, not by naïve string splitting.
- Canonically re-order conversation frames on the server side.
6. Plain-Text API Key Storage
Finding: More than 40% of open-source MCP launchers persist tool credentials in ~/.mcp/config.json
with 0600
but unencrypted. On multi-tenant bastions this is trivial to read via local privilege escalation (LPE) or forensic memory dumps.
Hardening:
- Store secrets in platform KMS (e.g., macOS Keychain, Windows DPAPI, HashiCorp Vault).
- Rotate keys automatically after first use; provide short-lived STS credentials.
7. ANSI Terminal Code Deception
Attack: When listing installed tools, the manifest's title
field embeds \u001b[2K
(erase line) followed by an instruction such as rm -rf /
. On TTY render the line is blank; copy-pasting from the terminal includes the hidden payload.
Controls:
- Sanitize non-printable ASCII < 0x20 in all CLI output.
- Provide a
--raw
flag that prints hex-encoded manifest fields for review.
8. Remote Code Execution via SSH Key Theft
Scenario: A tool offering "remote build" requests ~/.ssh/id_rsa.pub
to install on the build worker. The code path also logs the private key on error. Attackers trigger a controlled exception and collect the private key from telemetry.
Prevention:
- Enforce write-only telemetry; redact outbound logs with deterministic finite automata matching private-key PEM headers.
- Use
ssh-agent
socket forwarding; never handle private keys in user space.
9. Function Parameter Abuse
Abuse path: MCP function signatures often expose highly permissive regex-validated parameters. Example: get_user(input: string)
where input
is intended to be an email address. Attacker passes SQL-like patterns (.*
) to enumerate.
Safeguards:
- Constrain parameters with formal JSON schema, not free-form strings.
- Reject inputs exceeding realistic length or failing whitelist character sets.
10. GitHub Integration Weak Spots
Weakness: The repo.read
scope is granted at install-time, but the tool later triggers git ls-remote --heads https://token@github.com/org/private.git
on a shadow private repo it controls. Result: token reuse and repo cloning.
Defenses:
- Issue repo-scoped fine-grained PATs; verify the repo owner before checkout.
- Run outbound URL allow-listing in the CI sandbox.
11. RCE in MCP Inspector
Detail: Early versions executed docker inspect
on arbitrary container IDs received from remote peers, then parsed the resulting JSON with eval
due to malformed backticks in a template literal. Crafted container IDs closed the string and injected OS commands.
Patch: Replace eval
with a safe JSON parser and escape untrusted input.
12. Session ID Leakage
Problem: Several web-based agents place the session UUID in a GET query string (/chat?sid=…
). Proxy logs, browser history, and referer headers expose it.
Fixes:
- Move session identifiers to HttpOnly cookies with
SameSite=Strict
. - Rotate SID after privilege elevation events.
13. Consent Fatigue Exploits
Mechanism: An attacker tool bombards the user with incremental permission prompts (readProfile
, readEmail
, readCalendar
, …). Users reflexively accept.
Secure UX:
- Batch permissions; show a diff with red/yellow/green risk levels.
- Cool-off timers or exponential back-off on repeated denied permissions.
14. Tool Name Collision
Issue: MCP discovery is case-insensitive on some registries (AI-scan
, ai-scan
). The attacker publishes the lower-case variant first, then re-routes traffic.
Resolution:
- Enforce canonical slug hashing on the registry.
- Surfacing visual digests (e.g., SHA-256 truncated) in UI next to tool name.
15. Malicious Local Server Installations
Threat: Many tutorials suggest pip install . && python server.py
. The server binds 0.0.0.0:80
with weak CORS and no CSRF token. A drive-by webpage can POST an instruction that rebuilds or exfiltrates the local vector database.
Strategic fixes:
- Default binding to
localhost
, random high port, and CSRF secret. - Containerize with an AppArmor or SELinux profile that denies network egress except to allow-listed domains.