Back to skill

Security audit

AB-Agents-Meter-Reader

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it executes an unpinned third-party MCP package at runtime while handling private meter photos and local household data.

Install only if you are comfortable sending meter photos to MiniMax and storing your name, address, and readings locally. For safer use, pin and review the MCP package version, avoid unusual image filenames, run it under a low-privilege account, and treat `~/.meter-readings` and the MiniMax API key as sensitive.

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 (2)

T08 · Insecure Dependencies

Error
Location
meter-reader.sh:79
Finding

Unpinned Third-Party Package Is Downloaded and Executed at Runtime

Content
View full analysis

Vulnerability Details

File Location: meter-reader.sh:79-84
Vulnerability Type: Unpinned runtime dependency execution
Risk Level: High

Vulnerable Code

bash
{
    echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"meter-reader","version":"1.0"}}}'
    sleep 1
    echo "{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"understand_image\",\"arguments\":{\"prompt\":\"$PROMPT\",\"image_source\":\"$IMAGE_PATH\"}}}"
} | uvx minimax-coding-plan-mcp 2>/dev/null | python3 -c "

Technical Analysis

The script invokes uvx minimax-coding-plan-mcp without specifying an exact package version or verifying an artifact hash. Depending on the local uvx cache and package resolution behavior, this can cause package code to be retrieved from an external package source and executed at runtime.

The effective code executed by the skill can therefore change after the skill itself has been audited. A compromised upstream release, package repository, maintainer account, or dependency could introduce arbitrary code into subsequent runs.

The package runs with the permissions of the user invoking the script. It also inherits the process environment after the script sources /root/.openclaw/.minimax-env, meaning the MiniMax API credential can be available to the package process.

Attack Path

  1. An attacker compromises the upstream package, its publishing credentials, its dependency chain, or the package source used by uvx.
  2. A malicious package version is published under the resolved package name.
  3. A user invokes the skill to analyze a meter photograph.
  4. uvx resolves and executes the unpinned package.
  5. The malicious package executes with the invoking user's privileges and inherited environment.
  6. It can read accessible local files, capture the MiniMax API key, inspect image data, ma ...[truncated 795 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin minimax-coding-plan-mcp to a specific, reviewed version rather than resolving the latest available version:
    bash
    uvx 'minimax-coding-plan-mcp==<reviewed-version>'
    
  2. Use a lockfile or package installation mechanism that records and verifies hashes for the package and all transitive dependencies.
  3. Install reviewed dependencies during a controlled deployment phase instead of downloading executable code during normal image analysis.
  4. Verify package provenance and signatures where supported.
  5. Run the MCP server in a restricted sandbox or container with:
    • Read-only access to only the selected image.
    • No access to unrelated home-directory content.
    • A minimal environment containing only required variables.
    • Restricted outbound network access.
    • A dedicated, unprivileged operating-system account.
  6. Avoid sourcing credentials from a root-owned global path into a process that launches third-party code. Pass narrowly scoped, short-lived credentials only to the component that requires them.
  7. Document the exact dependency version in SKILL.md and establish a review process before updating it.

T09 · Insecure Skill Coding Practices

Warning
Location
meter-reader.sh:79
Finding

Unescaped Image Path and Prompt Permit JSON-RPC Request Injection

Content
View full analysis

Vulnerability Details

File Location: meter-reader.sh:79-83
Vulnerability Type: Improper construction of JSON from untrusted strings
Risk Level: Medium

Vulnerable Code

bash
{
    echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"meter-reader","version":"1.0"}}}'
    sleep 1
    echo "{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"understand_image\",\"arguments\":{\"prompt\":\"$PROMPT\",\"image_source\":\"$IMAGE_PATH\"}}}"
} | uvx minimax-coding-plan-mcp 2>/dev/null | python3 -c "

Technical Analysis

The script interpolates $PROMPT and $IMAGE_PATH directly into a JSON string. Shell quoting prevents ordinary shell command substitution from the expanded values, but it does not perform JSON escaping.

Linux and macOS filenames can contain quotation marks, backslashes, and most control characters. A specially constructed existing filename can therefore terminate the intended image_source JSON string and inject additional JSON properties. At minimum, malformed characters can invalidate the request and cause a denial of service. Depending on duplicate-key handling by the MCP implementation, an injected property can replace an intended argument such as image_source.

For example, a filename containing content structurally similar to the following can introduce a second image_source property:

text
photo.jpg","image_source":"/path/to/another/file

The precise result depends on the JSON parser and MCP server behavior. Parsers commonly retain the final value for duplicate keys, which could cause the vision tool to process a path other than the image that passed the script's -f check.

The hardcoded prompts currently contain no JSON metacharacters that trigger this flaw, but the unsafe construction remains present for both variables.

Attack Path

  1. An attac ...[truncated 1672 chars]
Remediation
View remediation

Remediation Suggestions

Construct JSON with a serializer rather than string interpolation. For example, use jq:

bash
init_request=$(jq -nc '{
  jsonrpc: "2.0",
  id: 1,
  method: "initialize",
  params: {
    protocolVersion: "2024-11-05",
    capabilities: {},
    clientInfo: {name: "meter-reader", version: "1.0"}
  }
}')

tool_request=$(jq -nc \
  --arg prompt "$PROMPT" \
  --arg image_source "$IMAGE_PATH" \
  '{
    jsonrpc: "2.0",
    id: 2,
    method: "tools/call",
    params: {
      name: "understand_image",
      arguments: {
        prompt: $prompt,
        image_source: $image_source
      }
    }
  }')

{
    printf '%s\n' "$init_request"
    sleep 1
    printf '%s\n' "$tool_request"
} | uvx 'minimax-coding-plan-mcp==<reviewed-version>'

Additional hardening should include:

  1. Resolve the image with a canonical path and verify that it points to a regular file.
  2. Restrict accepted inputs to approved image formats and validate file content rather than relying only on extensions.
  3. Reject filenames containing control characters if operationally unnecessary.
  4. Restrict file selection to an approved directory where possible.
  5. Configure the MCP server to expose only the required understand_image tool.
  6. Reject duplicate JSON keys at the receiving boundary where supported.
  7. Avoid suppressing all MCP error output, because doing so obstructs detection and diagnosis of malformed or manipulated requests.
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 Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose understates important behaviors: meter photos are sent to an external vision service, and personal data such as tenant name and apartment address are stored locally. Users may provide sensitive household information without informed consent, creating privacy and trust risks that are more serious because the skill processes real-world residence and utility data.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill documentation indicates file read/write behavior and persistent local storage, but it does not declare any tool scope such as permissions or allowed-tools. This weakens user and platform visibility into what the skill can access, increasing the chance of over-privileged execution or unexpected data handling.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The setup text requires a third-party vision API but does not warn that meter photos and potentially associated contextual data will leave the local environment. Even if the transfer is functionally necessary, lack of a privacy warning can mislead users about exposure of household imagery and related metadata.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes reading meter values from photos, saving history, and generating landlord messages. In addition to image analysis, the code loads /root/.openclaw/.minimax-env and depends on MINIMAX_API_KEY, which introduces credential and environment access not disclosed by the stated purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill sends user-supplied local meter photos to an external AI/MCP service, which expands the trust boundary beyond a local utility script. Even if the purpose is functional, undisclosed remote transmission of images and associated prompts can expose sensitive household information, metadata, or embedded personal details to third parties.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script transmits local image data to an external vision endpoint without a clear runtime warning or opt-in, which can surprise users and violate privacy expectations. Meter photos may include address context, timestamps, or other visual details that users did not intend to share outside their machine.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The script invokes uvx minimax-coding-plan-mcp without pinning an exact version or verifying package integrity. That creates a supply-chain risk: a compromised or newly published upstream version could execute arbitrary code in the user's environment when the meter-reading workflow runs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The history section shows storage of tenant name, apartment address, and utility readings in a local JSON file, but it is presented as a feature rather than a privacy-sensitive behavior. This can expose personal household data to other local users, backups, or misconfigured file permissions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

Most of the document is in English, but the support section switches to Russian text and Russian-language promotional copy without user opt-in or explanation. This is a locale/language policy concern because the skill does not offer a language choice or document that it is intended for Russian-speaking users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The message template emitted by generate_message is entirely in Russian, and the script does not offer any language selection or opt-in. This creates a natural-language policy issue because the skill imposes a locale/language preference on all users regardless of their needs.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.