Back to skill

Security audit

Mcp Builder Anthropic

Security checks for vulnerabilities and agentic risk

Overview

This MCP-building guide is coherent, but its evaluator and copied examples can expose private tool data or lead to insecure MCP servers without extra safeguards.

Install only if you are comfortable reviewing the examples before copying them and running evaluations only against test or low-sensitivity MCP servers. Avoid production credentials and private data unless you add read-only tool allowlists, redaction for tool results and errors, authenticated/loopback HTTP configuration, safe path handling, and pinned dependencies.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
reference/node_mcp_server.md:719
Finding

Unauthenticated MCP HTTP Endpoint Exposed on All Network Interfaces

Content
View full analysis
{ const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, enableJsonResponse: true }); res.on('close', () => transport.close()); await server.connect(transport); await transport.handleRequest(req, res, req.body); }); const port = parseInt(process.env.PORT || '3000'); app.listen(port, () => { console.error(`MCP server running on http://localhost:${port}/mcp`); }); } ``` ### Technical Analysis The documented HTTP server accepts MCP requests without authenticating or authorizing the requesting client. Checking that `EXAMPLE_API_KEY` exists only confirms that the server possesses an upstream credential; it does not restrict who can invoke the MCP endpoint. The endpoint also lacks: - OAuth or bearer-token validation. - Per-tool authorization. - `Origin` and Host-header validation. - DNS-rebinding protection. - Request-size and rate limits. - Explicit loopback binding. Calling `app.listen(port)` without a host generally listens on all available interfaces. The log message stating that the server is running on `localhost` does not enforce loopback-only accessibility. This example conflicts with the security recommendations in `reference/mcp_best_practices.md:154-177`, which require token validation, Origin validation, DNS-rebinding protection, and binding local servers to `127.0.0.1`. ### Attack Path 1. A developer copies the documented ...[truncated 1206 chars]
Remediation
View remediation
{ console.error(`MCP server running on http://127.0.0.1:${port}/mcp`); }); ``` 2. Require authenticated inbound requests before invoking the MCP transport. For remote deployments, implement OAuth 2.1 and validate: - Token signature and expiration. - Issuer and audience. - Scopes required for the requested operation. 3. Enforce per-tool authorization rather than relying only on endpoint-level authentication. 4. Validate the `Origin` and Host headers and enable the MCP SDK's DNS-rebinding protections where supported. 5. Add request-body size limits, rate limiting, TLS, secure reverse-proxy configuration, and security logging. 6. Use separate credentials with narrowly scoped read-only permissions when destructive access is unnecessary. 7. Correct the guide's log message and deployment documentation so that claimed network exposure matches the actual bind configuration. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
reference/python_mcp_server.md:536
Finding

Path Traversal in Document Resource Example

Content
View full analysis
str: '''Expose documents as MCP resources. Resources are useful for static or semi-static data that doesn't require complex parameters. They use URI templates for flexible access. ''' document_path = f"./docs/{name}" with open(document_path, "r") as f: return f.read() ``` ### Technical Analysis The resource parameter `name` is inserted directly into a filesystem path. The implementation does not: - Reject `..` path components. - Reject absolute paths. - Canonicalize the resulting path. - Confirm that the resolved path remains below the intended `docs` directory. - Restrict file extensions or symbolic links. Consequently, a crafted name can cause `open()` to resolve a file outside `./docs`. This violates the path-sanitization requirement stated in `reference/mcp_best_practices.md`. ### Attack Path 1. An attacker obtains access to the MCP resource endpoint. 2. The attacker supplies a traversal value such as `../.env`, `../../config.json`, or another path reachable by the process. 3. The server constructs a path such as `./docs/../.env`. 4. The operating system resolves the traversal components outside the document directory. 5. `open()` reads the targeted file using the MCP process's filesystem permissions. 6. The file contents are returned to the attacker through the MCP resource response. If symbolic links exist below `docs`, they can provide another path outside the intended resource root unless link handling is explicitly controlled. ### Impact Assessment An attacker may read any file accessible to the MCP process. Potentially exposed information includes: - Environment and configuration files. - API tokens and application crede ...[truncated 275 chars]
Remediation
View remediation
str: requested = Path(name) if requested.is_absolute(): raise ValueError("Absolute paths are not allowed") candidate = (DOCS_ROOT / requested).resolve() if candidate == DOCS_ROOT or DOCS_ROOT not in candidate.parents: raise ValueError("Invalid document path") if candidate.suffix.lower() not in ALLOWED_SUFFIXES: raise ValueError("Unsupported document type") if not candidate.is_file(): raise FileNotFoundError("Document not found") return candidate.read_text(encoding="utf-8") ``` Additional hardening should include: - Prefer opaque document identifiers mapped to server-controlled paths. - Reject symbolic links or verify their resolved targets remain under `DOCS_ROOT`. - Run the MCP process with minimal filesystem permissions. - Avoid placing credentials or configuration within directories readable by the service account. - Add tests covering `../`, absolute paths, encoded traversal, nested traversal, and symlink escape attempts. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/evaluation.py:94
Finding

Sensitive Evaluation and Tool Data Sent to an External Model Without Privacy Controls

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding

Unpinned Dependencies and Mutable Package Execution

Content
View full analysis
=0.39.0 mcp>=1.1.0 ``` The documentation also recommends unversioned installation and execution: ```bash pip install anthropic mcp ``` ```bash npx @modelcontextprotocol/inspector ``` ### Technical Analysis The Python requirements specify only minimum versions. As a result, a future installation can resolve to any later release accepted by the package resolver. The manual installation command is entirely unpinned. The `npx` command similarly resolves and executes a package version at invocation time. This allows the effective code executed by users to change after the Skill itself has been reviewed. The package names appear consistent with the declared official ecosystem, and the audit found no evidence of current typosquatting or intentionally malicious dependencies. The risk arises from mutable supply-chain resolution, lack of hashes, and lack of a reviewed lockfile. ### Attack Path 1. A user follows the installation or Inspector testing instructions. 2. `pip` or `npx` resolves the package versions available at that later time. 3. A compromised, malicious, or unexpectedly incompatible future release is selected. 4. Package installation hooks or runtime code execute with the user's privileges. 5. That code may access files, environment variables, API keys, source code, or network resources available to the development environment. A non-malicious breaking release can also change evaluation semantics or introduce vulnerabilities without any change to the audited Skill package. ### Impact Assessment Dependency code runs with the privileges of the user performing installation or evaluation. A compromised dependency could potentially access: - `ANTHROPIC ...[truncated 377 chars]
Remediation
View remediation
mcp== ``` 2. Generate and commit a lockfile for reproducible installations. 3. Use package hashes where practical, such as a requirements file compatible with: ```bash pip install --require-hashes -r requirements.txt ``` 4. Pin the Inspector invocation to a reviewed version: ```bash npx @modelcontextprotocol/inspector@ ``` 5. Prefer installing from configured trusted registries and verify package provenance. 6. Use isolated virtual environments or containers with minimal filesystem and network privileges. 7. Add automated dependency vulnerability scanning and a documented review process for version upgrades. 8. Consider suppressing lifecycle scripts where compatible with the package and workflow, and avoid exposing production credentials during dependency installation. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description says this skill is a guide for building MCP servers, implying instructional or reference content for development. The supplied code is not a guide or server-building utility; it is an operational evaluation script. Its primary purpose is to test existing MCP servers by connecting to them, enumerating tools, asking benchmark questions through Claude, executing tool calls, collecting metrics, and generating a markdown report. This is a materially different function from authoring guidance. The code also interacts with external resources and services not reflected in the description, including Anthropic's API and live MCP endpoints/processes via stdio, SSE, or HTTP. Therefore the description does not accurately represent the code's actual behavior.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 62)May include surrounding context.

md
- [⚡ TypeScript Guide](./reference/node_mcp_server.md) - TypeScript patterns and examples

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 83)May include surrounding context.

md
- [⚡ TypeScript Guide](./reference/node_mcp_server.md) - TypeScript patterns and examples

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 223)May include surrounding context.

md
- [⚡ TypeScript Guide](./reference/node_mcp_server.md) - TypeScript patterns and examples

External Model or Provider Selection

High
Category
Excessive Agency
Confidence
90% confidence
Finding

Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Content

Scanner excerpt · reference/evaluation.md (reported line 488)May include surrounding context.

md
optional arguments:
  -h, --help            Show help message
  -t, --transport       Transport type: stdio, sse, or http (default: stdio)
  -m, --model           Claude model to use (default: claude-3-7-sonnet-20250219)
  -o, --output          Output file for report (default: print to stdout)

stdio options:

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · reference/mcp_best_practices.md (reported line 158)May include surrounding context.

md
**OAuth 2.1**:
- Use secure OAuth 2.1 with certificates from recognized authorities
- Validate access tokens before processing requests
- Only accept tokens specifically intended for your server

**API Keys**:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill instructs the agent to create MCP servers, use WebFetch, and generate evaluation XML files, but it declares no explicit tool scope such as allowed-tools or permissions. That omission can let the runtime expose broader file-writing or MCP capabilities than the skill actually needs, increasing the chance of unintended tool use or privilege creep.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

Using npx @modelcontextprotocol/inspector without a pinned version causes execution of whatever package version is current at runtime. This creates a supply-chain risk: a compromised upstream release or breaking update could execute unexpected code during testing.

Content

No source excerpt is available for this finding.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.

Content

Scanner excerpt · reference/evaluation.md (reported line 205)May include surrounding context.

md
After understanding the API and tools, USE the MCP server tools:
- Inspect content using READ-ONLY and NON-DESTRUCTIVE operations ONLY
- Goal: identify specific content (e.g., users, channels, messages, projects, tasks) for creating realistic questions
- Should NOT call any tools that modify state
- Will NOT read the code of the MCP server implementation itself
- Parallelize this step with individual sub-agents pursuing independent explorations
- Ensure each subagent is only performing READ-ONLY, NON-DESTRUCTIVE, and IDEMPOTENT operations

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · reference/node_mcp_server.md (reported line 601)May include surrounding context.

md
mcp = FastMCP("example_mcp")

# Constants
API_BASE_URL = "https://api.example.com/v1"

# Enums
class ResponseFormat(str, Enum):

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · reference/python_mcp_server.md (reported line 353)May include surrounding context.

md
mcp = FastMCP("example_mcp")

# Constants
API_BASE_URL = "https://api.example.com/v1"

# Enums
class ResponseFormat(str, Enum):

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The guide demonstrates prompting for API keys in-band through user interaction without a user-facing warning about credential handling, retention, or safer auth patterns. In documentation meant to shape implementations, that omission can encourage secret collection practices that are hard to audit and easy to misuse.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The guide explicitly demonstrates using ctx.elicit(..., input_type="password") to request an API key and immediately use it in an API call. In a documentation skill about MCP server design, this normalizes collecting secrets through conversational prompts without discussing safer alternatives, storage boundaries, consent, or least-privilege handling, which can lead downstream implementers to build credential-harvesting patterns into tools.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The example encourages a tool to request an API key from the user and then use it for an API call, which is a sensitive-data collection pattern. In the context of an MCP server-building guide, this is more dangerous because it can propagate into many derived tools and normalize collecting high-value credentials over conversational interfaces.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The markdown guide shows direct file reads from a templated resource path but does not include any warning about filesystem access risks or input sanitization. Because this is prescriptive implementation guidance, omission of security caveats increases the chance that developers will adopt an unsafe file access pattern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The stdio transport creates a client context from a caller-supplied command and arguments, which results in subprocess execution. While the docstring notes 'Command to run,' there is no confirmation prompt, logging, or explicit warning to the user that a local process will be started.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The SSE and streamable HTTP transports establish remote network connections using a URL and caller-provided headers, and tool calls later send arguments through the session. This file contains no visible warning, prompt, or logging indicating that user-provided data and headers may be transmitted to an external MCP server.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The evaluation system prompt explicitly requires the model to disclose the inputs provided to each tool and the outputs received from each tool in its

. In an MCP evaluation harness, tool arguments and tool results can contain API responses, secrets, personal data, internal identifiers, or other sensitive material, so this design causes unnecessary data exposure into model output and the final report.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

This prompt-level behavior intentionally asks the model to reveal full tool inputs and outputs, creating a straightforward path for sensitive data leakage through generated summaries and evaluation artifacts. Because this harness is specifically designed to exercise external MCP tools, the likelihood of handling confidential or regulated data is higher than in a generic prompt, making the disclosure requirement especially risky in this skill context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

When a tool call fails, the code sends the exception message and full traceback back to the model as tool output, and that content can later be incorporated into summaries, feedback, or reports. Tracebacks often contain filesystem paths, environment details, request data, credentials in error messages, or internal implementation details that should not be disclosed to the model or end users.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This is a markdown file, so SQP-2 applies to missing warnings in documentation. The guide instructs users to export ANTHROPIC_API_KEY and later pass authorization headers and tokens, but it does not include any warning about protecting secrets, avoiding shell history exposure, or not committing credentials to files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The documentation demonstrates use of Authorization: Bearer token123 headers and token-bearing environment variables when running evaluations. Because the file later describes generated reports with per-task details and agent feedback, a user warning about possible credential exposure in logs or reports would help address privacy and system-integrity risks.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The module comment states that the server includes user search, project management, and data export capabilities. In the actual example code, only example_search_users is registered, and no project-management or export tools are implemented in the shown example. This is an active documentation/code mismatch rather than a mere omission because the comment explicitly describes capabilities not present.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The resource example reads ./docs/{name} directly from a user-controlled path segment and presents it as a normal MCP resource pattern without warning about path traversal or filesystem exposure. Even though it is illustrative documentation, readers may copy it verbatim and expose arbitrary local files if name is not constrained and canonicalized.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency specifier uses a lower-bound only constraint (anthropic>=0.39.0), which makes builds non-reproducible and allows future releases to be installed without review. That increases supply-chain risk and makes it impossible to determine whether a deployment is affected by later vulnerable or breaking versions.

Content

Scanner excerpt · scripts/requirements.txt (reported line 1)May include surrounding context.

text
anthropic>=0.39.0
mcp>=1.1.0

Static analysis

No suspicious patterns detected.