Back to skill

Security audit

Mcp Marketplace

Security checks for vulnerabilities and agentic risk

Overview

This MCP marketplace skill is mostly purpose-aligned, but it gives agents high-impact install and runtime authority without enough containment or verification.

Review every generated install, update, health-check, Docker, and shell-profile command before allowing the agent to run it. Prefer pinned package versions and verified images, avoid sudo/global installs where possible, do not enable the Docker socket entry unless you accept host-level risk, and run health checks only for servers you trust with your environment variables.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/install_server.py:52
Finding

Remote installer is downloaded and executed without integrity verification

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
scripts/install_server.py:89
Finding

Unpinned third-party packages are downloaded and executed during installation verification

Content
View full analysis
dict: """Return the command the agent should run to install/verify the package.""" method = server["installMethod"] package = server["package"] if method == "npx": return { "command": f"npx -y {package} --help", "description": f"Verify {package} is available via npx (downloads on first use)", "note": "npx packages don't need global install — they download on demand", } elif method == "npm": return { "command": f"npm install -g {package}", "description": f"Install {package} globally via npm", "note": "Requires npm write permissions. Use sudo if needed.", } elif method == "uvx": return { "command": f"uvx {package} --help", "description": f"Verify {package} is available via uvx (downloads on first use)", "fallbackCommand": f"uv tool install {package}", "note": "uvx packages resolve on demand. If verification fails, try the fallback command.", } elif method == "pip": pip_cmd = "pip3" if check_command_exists("pip3") else "pip" return { "command": f"{pip_cmd} install {package}", "description": f"Install {package} via {pip_cmd}", "note": "Consider using a virtual environment for isolation.", } elif method == "http": return { "command": None, "description": f"No installation needed for HTTP server '{server['displayName']}'", "note": "Just configure the URL in .mcp.json", } elif method == "docker": return { ...[truncated 3359 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/health_check.py:206
Finding

Health checks expose the complete parent environment to spawned MCP servers

Content
View full analysis
dict: """Spawn a stdio MCP server, send initialize + tools/list, return health status.""" proc = None try: # Merge with os.environ so PATH and other essentials are inherited merged_env = dict(os.environ) merged_env.update(env) proc = subprocess.Popen( [command] + args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=merged_env, ) ``` ### Technical Analysis The health checker copies every variable from `os.environ` and provides the resulting environment to the MCP server process. Only a small subset, such as a controlled `PATH`, locale variables, and the server's explicitly declared `requiredEnv`, is needed for the health check. Agent and development environments frequently contain unrelated secrets such as cloud credentials, CI tokens, package registry credentials, SSH agent configuration, database URLs, and API keys. Any executed MCP package can enumerate these values directly. This creates a particularly dangerous chain with the unpinned `npx` and `uvx` execution behavior: a newly downloaded package receives secrets unrelated to its declared function before it has been established as trustworthy. ### Attack Path 1. The user requests a health check for an MCP server. 2. The Skill resolves or downloads the server executable. 3. `check_stdio_server` copies the complete parent environment. 4. The server process starts with all inherited variables. 5. A malicious or compromised package enumerates its environment. 6. The package extracts unrelated credentials. 7. Because no network sandbox is applied, the package can transmit those credentia ...[truncated 461 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
assets/known_servers.json:1083
Finding

Unverified mutable Docker image is granted control of the host Docker daemon

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/secrets_helper.py:52
Finding

Secrets-manager shell commands are generated through unsafe string interpolation

Content
View full analysis
dict: """Generate the command to store a secret.""" if manager == "1password": return { "manager": "1password", "storeCommand": f'op item create --category=api-credential --title "MCP: {service_name}" --vault=Private "credential="', "retrieveCommand": f'op read "op://Private/MCP: {service_name}/credential"', "shellIntegration": f'export {env_var}=$(op read "op://Private/MCP: {service_name}/credential")', "note": "Add the export line to ~/.zshrc for automatic retrieval on shell start", } elif manager == "keychain": return { "manager": "keychain", "storeCommand": f'security add-generic-password -a mcp -s "{service_name}" -w ""', "retrieveCommand": f'security find-generic-password -a mcp -s "{service_name}" -w', "shellIntegration": f'export {env_var}=$(security find-generic-password -a mcp -s "{service_name}" -w)', "note": "Add the export line to ~/.zshrc for automatic retrieval on shell start", } else: return {"error": f"Unknown manager: {manager}"} ``` `SKILL.md:276-285`: ```markdown 7. **Offer secrets manager (if available)**: Before telling the user to add `export` to `.zshrc`, check for a secrets manager: ``` python3 {baseDir}/scripts/secrets_helper.py --action detect ``` If managers are found, offer the option: "I detected **[manager name]** on your system. Want to store this token there instead of in your shell profile? It's more secure." If yes, generate the store command: ``` python3 {baseDir}/scri ...[truncated 1861 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (92)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description promises a full-featured MCP server lifecycle and discovery tool, including installation, configuration, registry search, config generation, management operations, and health testing. The actual code does not perform any of those broader tasks. Instead, it only reads two local JSON files and evaluates compatibility between a known server and a specific client using metadata rules. This is related to MCP troubleshooting, but it is a much narrower function than the declared primary purpose. There are no undeclared dangerous behaviors, but the declared description materially overstates what this code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code’s primary purpose is contribution tooling for catalog maintenance: it validates server metadata fields, checks for duplicate IDs against a local known_servers.json file, constructs a catalog entry object, and generates a pull request template. While the PR template text mentions install testing and health checks, the script does not actually perform those actions. This is materially different from the declared purpose of end-user MCP server installation, configuration, discovery, and operational management.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a full-featured MCP server management tool. The supplied code chunk is much narrower: it scans the local system for globally installed npm packages, pip packages, and uv tools; loads a local known-server catalog; reads common MCP configuration files; and reports which known MCP servers are installed and whether they are already configured. That is related to MCP server discovery/listing, but it does not implement installation, configuration generation, registry search, health checks, testing, troubleshooting, removal, or updates. Additionally, the code performs local environment/package/config inspection, which is a concrete capability not explicitly declared in the permissions or description. Because the actual behavior is only a subset and includes undeclared system/package scanning, the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description promises a full-featured MCP server management capability, including discovery across multiple registries, installation, configuration generation for several clients, lifecycle management, and health checks/troubleshooting. The supplied code does only a small subset: it reads a local known_servers.json file, checks whether local commands like npm/npx/uvx/pip/docker are present, and constructs install-related command strings. It does not search external registries, does not install anything, does not generate config files, does not list/remove/update servers, and does not perform actual health checks of MCP servers. Although prerequisite checking and generating install commands are related to installation, the code's actual behavior is materially narrower than the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description promises a broad MCP server installation, discovery, configuration, and health-check tool. This code chunk only manages bookkeeping for already-installed servers in a JSON state file and reports whether a server appears in certain config files. Its primary purpose is narrower than declared. While list/remove/status/info overlap partially with the description, major advertised capabilities—installing servers, searching registries, generating configs, and actual health checking/troubleshooting—are absent from the supplied code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a broad MCP server management tool covering installation, configuration generation, registry search, listing, removal, update, and health checking. The supplied code chunk does none of those primary management actions. It loads static template and known-server metadata, scans a project directory for files/patterns, reads existing MCP configuration files only to determine which servers are already configured, and emits recommendation JSON. Reading local Claude/Cursor/.mcp config files is consistent with recommendation context, but the core behavior is materially narrower and different from the declared purpose. Therefore this chunk does not accurately represent the declared functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description focuses on MCP server lifecycle management: searching registries, installing/removing servers, generating client configs, listing servers, and testing server health. The actual code does none of that. Instead, it inspects the local environment for secrets-management tools and outputs JSON containing suggested commands for saving and loading tokens. While secrets handling could be a supporting feature in a broader MCP setup workflow, this code chunk’s primary purpose is materially different from the declared skill purpose and lacks the core server-management behaviors described. Therefore this is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

This code chunk’s primary function is 'smart recommendation' of MCP servers. It loads affinity data and known server metadata from local assets, inspects local installed/configured server state from OpenClaw and Claude/Cursor config files, scores candidate servers, and prints recommendation JSON. The declared description instead emphasizes MCP server lifecycle management and registry search/discovery, including install, configuration generation, removal, status, health checks, and troubleshooting. While recommendation/discovery is loosely adjacent to 'what MCP servers are available,' this script is materially narrower and different in purpose: it recommends complements based on current setup rather than managing servers or searching registries. Therefore the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

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 · assets/known_servers.json (reported line 17)May include surrounding context.

json
"GITHUB_TOKEN": "https://github.com/settings/tokens/new?scopes=repo"
      },
      "requiredEnvDescriptions": {
        "GITHUB_TOKEN": "Personal access token with 'repo' scope"
      },
      "optionalEnv": [],
      "verified": true,

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 · assets/known_servers.json (reported line 251)May include surrounding context.

json
"GITHUB_TOKEN": "https://github.com/settings/tokens/new?scopes=repo"
      },
      "requiredEnvDescriptions": {
        "GITHUB_TOKEN": "Personal access token with 'repo' scope"
      },
      "optionalEnv": [],
      "verified": true,

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 · assets/known_servers.json (reported line 418)May include surrounding context.

json
"GITHUB_TOKEN": "https://github.com/settings/tokens/new?scopes=repo"
      },
      "requiredEnvDescriptions": {
        "GITHUB_TOKEN": "Personal access token with 'repo' scope"
      },
      "optionalEnv": [],
      "verified": true,

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 · assets/known_servers.json (reported line 615)May include surrounding context.

json
"GITHUB_TOKEN": "https://github.com/settings/tokens/new?scopes=repo"
      },
      "requiredEnvDescriptions": {
        "GITHUB_TOKEN": "Personal access token with 'repo' scope"
      },
      "optionalEnv": [],
      "verified": true,

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 · assets/known_servers.json (reported line 710)May include surrounding context.

json
"GITHUB_TOKEN": "https://github.com/settings/tokens/new?scopes=repo"
      },
      "requiredEnvDescriptions": {
        "GITHUB_TOKEN": "Personal access token with 'repo' scope"
      },
      "optionalEnv": [],
      "verified": true,

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · assets/known_servers.json (reported line 651)May include surrounding context.

json
"requiredEnv": [],
      "requiredEnvLinks": {},
      "requiredEnvDescriptions": {},
      "optionalEnv": ["KUBECONFIG"],
      "verified": true,
      "popularity": 2000,
      "tags": ["kubernetes", "k8s", "kubectl", "pods", "deployments", "cluster", "devops"]

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 · assets/known_servers.json (reported line 774)May include surrounding context.

json
"AIRTABLE_API_KEY": "https://airtable.com/create/tokens"
      },
      "requiredEnvDescriptions": {
        "AIRTABLE_API_KEY": "Airtable Personal Access Token"
      },
      "optionalEnv": [],
      "verified": true,

Docker Socket Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

Mounting /var/run/docker.sock into a container gives that container effectively root-equivalent control over the host Docker daemon, enabling container breakout, arbitrary container creation, filesystem mounting, and broad host compromise. In a marketplace/catalog context, shipping this as an installable server definition without a strong warning materially increases the chance users enable a highly privileged integration without understanding the risk.

Content

Scanner excerpt · assets/known_servers.json (reported line 1092)May include surrounding context.

json
"package": "mcp/docker",
      "dockerImage": "mcp/docker:latest",
      "dockerPorts": [],
      "dockerVolumes": ["/var/run/docker.sock:/var/run/docker.sock"],
      "args": [],
      "requiredEnv": [],
      "requiredEnvLinks": {},

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 · references/oauth-patterns.md (reported line 26)May include surrounding context.

md
1. Go to [Google Cloud Console → APIs & Services → Credentials](https://console.cloud.google.com/apis/credentials)
2. Create **OAuth 2.0 Client ID** (type: Desktop App)
3. Download the `credentials.json` file
4. Run the server's auth flow (usually `python3 -m <module> --auth`) — this opens a browser for consent
5. The server stores refresh tokens locally (typically in `~/.config/<server>/token.json`)

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 · references/oauth-patterns.md (reported line 41)May include surrounding context.

md
5. Copy the **Bot User OAuth Token** (starts with `xoxb-`)
6. Set: `export SLACK_BOT_TOKEN=xoxb-your-token-here`

## GitHub Apps (vs Personal Access Tokens)

Some servers support GitHub App authentication for organization-level access.

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 · references/oauth-patterns.md (reported line 47)May include surrounding context.

md
5. Copy the **Bot User OAuth Token** (starts with `xoxb-`)
6. Set: `export SLACK_BOT_TOKEN=xoxb-your-token-here`

## GitHub Apps (vs Personal Access Tokens)

Some servers support GitHub App authentication for organization-level access.

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 · references/oauth-patterns.md (reported line 45)May include surrounding context.

md
Some servers support GitHub App authentication for organization-level access.

### Personal Access Token (Simple)

1. Go to [GitHub Settings → Developer → Personal Access Tokens](https://github.com/settings/tokens/new)
2. Select required scopes (typically `repo`, `read:org`)

MCP Config Access

High
Category
Agent Snooping
Confidence
95% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

Scanner excerpt · references/troubleshooting.md (reported line 84)May include surrounding context.

md
OpenClaw doesn't see the new MCP server after adding it to `.mcp.json`.

**Fix:**
1. Verify `.mcp.json` is valid JSON: `python3 -c "import json; json.load(open('.mcp.json')); print('OK')"`
2. Verify the file is in the project root directory
3. Restart OpenClaw to reload the configuration
4. Check that the server entry is inside the `"mcpServers"` key

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/health_check.py (reported line 211)May include surrounding context.

python
proc = None
    try:
        # Merge with os.environ so PATH and other essentials are inherited
        merged_env = dict(os.environ)
        merged_env.update(env)

        proc = subprocess.Popen(

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 · scripts/secrets_helper.py (reported line 39)May include surrounding context.

python
"note": "Signed in" if available else "CLI found but not signed in — run 'op signin' first",
        })

    # Check macOS Keychain
    if shutil.which("security"):
        managers.append({
            "name": "keychain",

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 · scripts/secrets_helper.py (reported line 43)May include surrounding context.

python
"note": "Signed in" if available else "CLI found but not signed in — run 'op signin' first",
        })

    # Check macOS Keychain
    if shutil.which("security"):
        managers.append({
            "name": "keychain",

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 · scripts/secrets_helper.py (reported line 42)May include surrounding context.

python
# Check macOS Keychain
    if shutil.which("security"):
        managers.append({
            "name": "keychain",
            "displayName": "macOS Keychain",
            "command": "security",
            "available": True,

Static analysis

No suspicious patterns detected.