Back to skill

Security audit

Cartogopher

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its CartoGopher setup purpose, but it asks users to run unverified downloaded code, persist an API key in plaintext, and modify a system identity file.

Review before installing. Only run this in a workspace and account where you are comfortable installing vendor-provided code, avoid running the setup as root, do not let it create /etc/machine-id unless you intentionally control that container, and prefer storing the CartoGopher API key in a dedicated secret mechanism instead of shell profiles or multiple plaintext MCP configs.

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 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
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:77
Finding
Unverified Remote Payload Retrieval and Execution<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 77-92 and 96-123 **Vulnerability Type**: Remote executable retrieval without integrity verification **Risk Level**: High ### Vulnerable Code ```bash # Detect platform and set download URL PLATFORM=$(uname -s)-$(uname -m) case "$PLATFORM" in Darwin-arm64) DOWNLOAD_URL="https://cartogopher.com/downloads/cartogopher/v4/mac/arm64" ;; Darwin-x86_64) DOWNLOAD_URL="https://cartogopher.com/downloads/cartogopher/v4/mac/intel" ;; Linux-x86_64) DOWNLOAD_URL="https://cartogopher.com/downloads/cartogopher/v4/linux/amd64" ;; Linux-aarch64) DOWNLOAD_URL="https://cartogopher.com/downloads/cartogopher/v4/linux/arm64" ;; *) echo "Unsupported platform: $PLATFORM"; exit 1 ;; esac # Download, extract, and clean up curl -sL "$DOWNLOAD_URL" -o cg.zip && unzip cg.zip -d ~/.cartogopher/mcp-server && rm cg.zip ``` ```bash cd ~/.cartogopher/mcp-server npm install ``` The platform-specific alternatives perform the same unverified retrieval: ```bash curl -sL https://cartogopher.com/downloads/cartogopher/v4/mac/arm64 -o cg.zip && unzip cg.zip -d ~/.cartogopher/mcp-server && rm cg.zip curl -sL https://cartogopher.com/downloads/cartogopher/v4/mac/intel -o cg.zip && unzip cg.zip -d ~/.cartogopher/mcp-server && rm cg.zip curl -sL https://cartogopher.com/downloads/cartogopher/v4/linux/amd64 -o cg.zip && unzip cg.zip -d ~/.cartogopher/mcp-server && rm cg.zip curl -sL https://cartogopher.com/downloads/cartogopher/v4/linux/arm64 -o cg.zip && unzip cg.zip -d ~/.cartogopher/mcp-server && rm cg.zip ``` ### Technical Analysis The Skill downloads a ZIP archive from an external, mutable URL and installs its contents without validating a cryptographic checksum or digital signature. The downloaded package later supplies `cartogopher-mcp.js`, which is executed by Node.js as the configured MCP server. The URL includes a nominal `v4` path but does not identify an immutable release artifact or verify that the received ...[truncated 2113 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Publish each supported archive as an immutable, versioned release artifact rather than serving mutable platform endpoints. 2. Publish SHA-256 or stronger digests through a separately protected release channel and verify the selected archive before extraction. 3. Digitally sign release manifests or artifacts and verify signatures against a pinned vendor public key. 4. Configure downloads to reject unexpected redirects or verify that the final redirect destination uses HTTPS and belongs to an explicit allowlist. 5. Download into a newly created, permission-restricted temporary directory and inspect archive paths before extraction to prevent path traversal or unexpected overwrites. 6. Ship and require a reviewed lockfile. Use `npm ci` rather than `npm install` to ensure deterministic dependency resolution. 7. Use `npm ci --ignore-scripts` where lifecycle scripts are unnecessary. If scripts are required, document and audit each one before execution. 8. Perform installation and MCP execution as an unprivileged user and restrict the MCP server's filesystem and network access to the minimum required workspace and endpoints. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:125
Finding
API Key Persisted in Multiple Plaintext Configuration Files<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 125-181 **Vulnerability Type**: Plaintext credential storage and unnecessary credential duplication **Risk Level**: Medium ### Vulnerable Code ```bash # Detect shell profile SHELL_PROFILE="$HOME/.zshrc" [ -f "$HOME/.bashrc" ] && [ ! -f "$HOME/.zshrc" ] && SHELL_PROFILE="$HOME/.bashrc" # Add API key to shell profile (only if not already present) if ! grep -q "CARTOGOPHER_API_KEY" "$SHELL_PROFILE" 2>/dev/null; then echo "export CARTOGOPHER_API_KEY=API_KEY_HERE" >> "$SHELL_PROFILE" fi source "$SHELL_PROFILE" ``` The OpenClaw configuration duplicates the key: ```json { "mcpServers": { "cartogopher": { "command": "node", "args": ["~/.cartogopher/mcp-server/cartogopher-mcp.js"], "env": { "CURSOR_WORKSPACE": ".", "CARTOGOPHER_API_KEY": "API_KEY_HERE" } } } } ``` The Cursor configuration also duplicates the key: ```json { "mcpServers": { "cartogopher": { "command": "node", "args": ["~/.cartogopher/mcp-server/cartogopher-mcp.js"], "env": { "CURSOR_WORKSPACE": "${workspaceFolder}", "CARTOGOPHER_API_KEY": "API_KEY_HERE" } } } } ``` The Claude Code command places the key directly in command arguments: ```bash claude mcp add cartogopher node ~/.cartogopher/mcp-server/cartogopher-mcp.js \ -e CURSOR_WORKSPACE=. \ -e CARTOGOPHER_API_KEY=API_KEY_HERE ``` ### Technical Analysis The setup instructs users to write the API key into a shell startup file and then duplicate it in an MCP configuration. These are persistent plaintext files that may be readable by local processes operating as the user and may be copied into backups, diagnostic bundles, synchronized profiles, or shared configuration. The Claude command additionally exposes the literal secret to shell history and may expose it transiently through process argument inspection, depending on how the CLI handles the supplied arguments. ...[truncated 1440 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store the API key in an operating-system keychain, credential manager, or another secret-management facility rather than in shell profiles. 2. Configure the MCP launcher to resolve the secret at runtime so the literal value does not need to appear in `openclaw.json`, `~/.cursor/mcp.json`, or equivalent configuration. 3. Avoid storing the same key in multiple locations. Use one protected source of truth and pass the value only to the MCP child process that requires it. 4. Do not place literal secrets in command-line arguments. Use protected standard input, a secret reference, or a permission-restricted environment-loading mechanism supported by the client. 5. If file-based storage is unavoidable, create a dedicated secret file with owner-only permissions, verify its ownership, and keep it outside project repositories and synchronized configuration directories. 6. Warn users not to commit, paste, log, or include MCP configuration and shell profiles in support bundles without redaction. 7. Provide documented key rotation and revocation procedures and automatically remove expired trial keys where feasible. 8. Ensure setup output and verification responses redact the key rather than echoing it. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:66
Finding
Setup Modifies the System-Wide Machine Identity File<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 66-73 **Vulnerability Type**: System-level modification beyond normal per-user MCP setup scope **Risk Level**: Medium ### Vulnerable Code ```bash # Ensure machine-id exists (required in containers) [ -f /etc/machine-id ] || (cat /proc/sys/kernel/random/uuid | tr -d '-' > /etc/machine-id) ``` ### Technical Analysis The installation procedure writes directly to `/etc/machine-id` when that file is absent. This is a system-level identity file consumed by operating-system components and unrelated applications. Creating or maintaining it is normally the responsibility of the operating system or container initialization process, not a per-user code-intelligence plugin. The command succeeds only when the invoking context already has permission to write under `/etc`, such as a root shell or a sufficiently privileged container. It does not independently bypass operating-system access controls. Nevertheless, instructing users or agents to perform this global modification encourages execution with permissions beyond those required to install an MCP server in the user's home directory. Generating the identifier through an ad hoc shell pipeline also bypasses platform-supported machine-ID initialization and lifecycle behavior. ### Attack Path 1. CartoGopher is installed in a container or environment where `/etc/machine-id` is absent. 2. The user or agent runs the setup under root or another context with write access to `/etc`. 3. The command generates a value and writes it to the global `/etc/machine-id` path. 4. Other applications and services in the same environment begin consuming the newly created identifier. 5. The changed identity semantics may persist for the lifetime of the container or writable image and affect software unrelated to CartoGopher. ### Impact Assessment The immediate privilege exercised is write access to a system configuration file. The action may alter machine identity be ...[truncated 471 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove direct creation of `/etc/machine-id` from the automated Skill instructions. 2. Detect the missing prerequisite and stop with a clear explanation instead of modifying system state. 3. Where initialization is genuinely required, instruct an administrator to use the operating system or container platform's supported machine-ID initialization process after explicit informed consent. 4. Document why the identifier is required, how it is used, whether it is transmitted externally, and the consequences of generating it in cloned container images. 5. Prefer a CartoGopher-specific identifier stored under the user's application data directory if the product controls the identifier requirement. 6. Keep the MCP installation and runtime under an unprivileged account and avoid requiring root access for ordinary setup. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Missing User Warnings

High
Confidence
98% confidence
Finding
The skill instructs appending an API key directly into a shell startup file, which stores credentials in plaintext in a broadly reused location. This increases the chance of accidental disclosure through backups, dotfile syncing, shell history mistakes, local multi-user access, or later exfiltration by unrelated tools.

External Transmission

Medium
Category
Data Exfiltration
Content
openclaw:
    requires:
      bins:
        - curl
        - unzip
        - node
        - npm
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill tells the agent to send the user's email address to an external service to obtain a trial key, but provides no explicit privacy notice or consent checkpoint. This creates unnecessary risk of sharing personal data with a third party without informed user approval.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill directs downloading a remote bundle and running npm install, which executes third-party code and dependency lifecycle scripts, without warning the user about supply-chain risk or verifying authenticity. This expands the trust boundary substantially and could lead to arbitrary code execution if the server or package contents are compromised.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The skill instructs creating or modifying /etc/machine-id, a system-wide host identifier, to satisfy a container prerequisite. This changes operating-system state beyond the scoped task of configuring an MCP server and can affect identity, telemetry, licensing, or host-level assumptions inside containers.

External Transmission

Medium
Category
Data Exfiltration
Content
esac

# Download, extract, and clean up
curl -sL "$DOWNLOAD_URL" -o cg.zip && unzip cg.zip -d ~/.cartogopher/mcp-server && rm cg.zip
```

**Platform-specific one-liners (if you already know the platform):**
Confidence
93% confidence
Finding
This step downloads a remote archive from an external domain and installs it locally without integrity verification or trust warnings. Because the archive is then extracted and followed by dependency installation, compromise of the distribution channel could lead to execution of malicious code.

Intent-Code Divergence

Low
Confidence
76% confidence
Finding
Lines L135-L145 state the API key must be added to the shell profile so the MCP server process can access it, implying shell-profile inheritance matters. But L201 says the MCP server must have `CARTOGOPHER_API_KEY` explicitly in its env config and does not inherit from the shell, which contradicts the rationale for permanently exporting the key in the profile.