Back to skill

Security audit

MCP Business Integration

Security checks for vulnerabilities and agentic risk

Overview

This MCP integration guide is purpose-aligned, but it needs review because it teaches broad business-data and write-capable integrations using insecure examples and limited safety scoping.

Review before installing or using this skill. It is not malicious, but users should treat its code blocks as illustrative only: add path containment, least-privilege credentials, explicit authorization checks, confirmation gates for writes or budget changes, destination allowlists, redacted logging, and clear cache/retention controls before implementing any MCP server based on it.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:94
Finding
Path Traversal in MCP Filesystem Integration Example<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:94-103` **Vulnerability Type**: Path traversal enabling unauthorized file access and modification **Risk Level**: High ### Vulnerable Code ```python # MCP Server for file access @server.resource("file://documents/{path}") async def read_document(path: str): with open(f"documents/{path}") as f: return f.read() @server.tool("write_document") async def write_document(path: str, content: str): with open(f"documents/{path}", "w") as f: f.write(content) return {"status": "written"} ``` ### Technical Analysis The filesystem integration directly interpolates an externally supplied `path` into a local filesystem path. It does not reject absolute paths, normalize path components, resolve symbolic links, or verify that the resulting path remains under the intended `documents` directory. An attacker able to invoke these MCP endpoints could supply traversal sequences such as `../.env`, `../../etc/passwd`, or paths targeting application configuration. The operating system resolves the `..` components before opening the file, allowing the request to escape the expected directory. The write operation creates an additional integrity risk because an attacker can overwrite any file writable by the MCP server process. The exact scope depends on the operating-system privileges and working directory of that process. ### Attack Path 1. An operator implements or deploys the documented filesystem MCP server. 2. The attacker gains permission to call the `file://documents/{path}` resource or `write_document` tool. 3. The attacker supplies a crafted path containing traversal components, such as `../.env`. 4. Python passes `documents/../.env` to the operating system without a containment check. 5. The operating system resolves the path outside the intended `documents` directory. 6. The read endpoint returns the targeted file, or the write endpoint modifies it. 7. Information obtained from ...[truncated 796 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Define a fixed, minimally privileged root directory for all document operations. - Reject absolute paths and path components such as `..`. - Resolve both the configured root and requested path to canonical paths, then verify that the requested path remains beneath the root. - Account for symbolic-link traversal by validating the resolved path rather than only checking the original string. - Separate read and write authorization, and expose write access only when required. - Run the MCP server under a dedicated operating-system account with access only to the intended document directory. - Use an allowlist of document identifiers instead of accepting arbitrary filesystem paths where possible. - Add tests covering traversal sequences, absolute paths, alternate separators, URL-encoded traversal, and symbolic links. A hardened implementation should follow this pattern: ```python from pathlib import Path DOCUMENT_ROOT = Path("documents").resolve() def resolve_document_path(path: str) -> Path: requested = Path(path) if requested.is_absolute(): raise ValueError("Absolute paths are not permitted") resolved = (DOCUMENT_ROOT / requested).resolve() if resolved != DOCUMENT_ROOT and DOCUMENT_ROOT not in resolved.parents: raise ValueError("Path escapes the document directory") return resolved @server.resource("file://documents/{path}") async def read_document(path: str): safe_path = resolve_document_path(path) return safe_path.read_text() @server.tool("write_document") async def write_document(path: str, content: str): safe_path = resolve_document_path(path) safe_path.write_text(content) return {"status": "written"} ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:290
Finding
Sensitive MCP Inputs and Outputs Logged Without Redaction<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:290-299` **Vulnerability Type**: Sensitive information exposure through debug logging **Risk Level**: Medium ### Vulnerable Code ```python import logging logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger("mcp_server") @server.tool("debug_operation") async def debug_operation(data: dict): logger.debug(f"Input: {data}") result = await process(data) logger.debug(f"Output: {result}") return result ``` ### Technical Analysis The example globally enables DEBUG logging and records complete tool inputs and outputs. The Skill is designed to process business data from CRM, analytics, advertising, databases, and external APIs. Consequently, `data` and `result` may contain personal information, customer records, authentication tokens, API keys, internal identifiers, financial metrics, or confidential business information. String interpolation serializes the complete objects without field filtering or redaction. Logs commonly persist beyond the original request and may be copied into centralized logging platforms, monitoring systems, backups, support bundles, or development consoles. Access controls and retention policies for these destinations may be weaker than those protecting the source systems. ### Attack Path 1. An operator deploys the documented MCP server with DEBUG logging enabled. 2. A legitimate user or attacker submits sensitive values to `debug_operation`, or the operation produces sensitive output. 3. The server writes the complete input and output objects to its configured log handlers. 4. Log collectors, local files, container logs, monitoring agents, or support tooling retain and potentially replicate the records. 5. A user with log access, but without authorization to access the original business system, retrieves the sensitive values. 6. If credentials or tokens were logged, they may be reused to access connected services until they expire or are re ...[truncated 681 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not enable DEBUG logging by default in production deployments. - Avoid logging complete request and response objects; log only operational metadata required for diagnostics. - Apply allowlist-based structured logging so only explicitly approved fields are recorded. - Redact or omit passwords, authorization headers, API keys, tokens, cookies, personal information, customer content, and database results. - Configure access controls, encryption, retention limits, and deletion procedures for all log destinations. - Prevent logs from being included in publicly accessible support bundles or telemetry. - Add automated tests that verify sensitive fields are never emitted. - Document incident procedures for rotating any credential discovered in logs. A safer logging pattern is: ```python import logging logger = logging.getLogger("mcp_server") @server.tool("debug_operation") async def debug_operation(data: dict): logger.debug( "Processing debug operation", extra={"field_count": len(data)} ) result = await process(data) logger.debug("Debug operation completed") return result ``` If selected values are operationally necessary, they should be sanitized through a centralized redaction function before being logged. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Vague Triggers

Medium
Confidence
94% confidence
Finding
The skill description includes broad trigger phrases like 'business data' and 'agent integration', which can cause the skill to activate in overly broad contexts and expose users to data-accessing capabilities unexpectedly. In a skill focused on MCP connections to databases, files, CRM, and ads systems, overbroad invocation increases the chance of unintended sensitive operations being suggested or used.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The document demonstrates access to databases, files, external APIs, CRM records, and write-capable operations without explicit warnings about authorization, privacy, destructive effects, or data handling boundaries. Because this skill is about connecting agents directly to business systems, omission of safety guidance materially increases the risk of accidental exfiltration, unauthorized writes, and privacy violations.

Session Persistence

Medium
Category
Rogue Agent
Content
- Query databases and APIs
- Access files and resources
- Execute tools and functions
- Maintain context across sessions

## Why MCP Matters
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

External Transmission

Medium
Category
Data Exfiltration
Content
# MCP Server for REST API
@server.resource("api://customers")
async def get_customers():
    response = await httpx.get("https://api.example.com/customers")
    return response.json()

@server.tool("create_customer")
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# MCP Server for REST API
@server.resource("api://customers")
async def get_customers():
    response = await httpx.get("https://api.example.com/customers")
    return response.json()

@server.tool("create_customer")
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
@server.tool("create_customer")
async def create_customer(data: dict):
    response = await httpx.post(
        "https://api.example.com/customers",
        json=data
    )
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Ssd 3

Medium
Confidence
98% confidence
Finding
The debug example logs full input and output payloads, which may include customer data, CRM records, analytics, API tokens, or other business-sensitive content. In MCP integrations, logs often become centralized and long-lived, so plain-language payload logging can turn routine debugging into a secondary data exposure channel.

Static analysis

No suspicious patterns detected.