Back to skill

Security audit

Amr

Security checks for vulnerabilities and agentic risk

Overview

This skill should go to Review because it is advertised as an autonomous mobile robot fleet manager but actually behaves like a local notes/config shell utility with unsafe file handling.

Do not rely on this skill for real robot or fleet operations. Treat it only as a local entry logger, and install only if you are comfortable with it writing ~/.amr plus amr-export.json or amr-export.csv in the current directory. Avoid passing untrusted text to add, search, or config, and avoid running export in shared or sensitive directories.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/script.sh:138
Finding

OS Command Injection Through Dynamically Constructed GNU sed Program

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh:138-151
Vulnerability Type: OS command injection
Risk Level: High

Vulnerable Code

bash
cmd_config() {
    local key="${1:-}" val="${2:-}"
    local cfg="$DATA_DIR/config.txt"
    if [ -z "$key" ]; then
        echo "=== Config ==="
        if [ -f "$cfg" ]; then
            while IFS="=" read -r k v; do echo "  $k=$v"; done < "$cfg"
        else echo "  (empty — use config <key> <value>)"; fi
    elif [ -z "$val" ]; then
        grep "^${key}=" "$cfg" 2>/dev/null | cut -d= -f2- || echo "(not set)"
    else
        if [ -f "$cfg" ] && grep -q "^${key}=" "$cfg" 2>/dev/null; then
            sed -i "s|^${key}=.*|${key}=${val}|" "$cfg"
        else
            echo "${key}=${val}" >> "$cfg"
        fi
        echo "Set: $key=$val"
    fi
}

Technical Analysis

The configuration key and value are attacker-controlled command-line arguments. When an existing key is updated, both arguments are interpolated directly into a GNU sed program:

bash
sed -i "s|^${key}=.*|${key}=${val}|" "$cfg"

Shell quoting prevents immediate shell expansion of the arguments, but it does not make them safe as sed syntax. A value can contain the | delimiter and literal newline characters, terminate the intended substitution, and introduce additional sed commands. GNU sed supports the e command, which executes an external command through a shell.

The key is also interpreted as a regular expression by both grep and sed. Consequently, regex metacharacters can alter which configuration records are selected or replaced, even when command execution is not achieved.

Attack Path

  1. The attacker causes a normal configuration entry to exist, for example by invoking:
    bash
    scripts/script.sh config mode safe
    
  2. The attacker supplies a replacement value containing a sed de ...[truncated 1039 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not construct sed programs by interpolating untrusted strings.
  • Restrict configuration keys to an explicit syntax, such as:
    bash
    [[ "$key" =~ ^[A-Za-z0-9_.-]+$ ]] || {
        echo "Invalid configuration key" >&2
        return 1
    }
    
  • Rewrite the configuration through a securely created temporary file using a parser that passes values as data rather than executable syntax.
  • If awk is used, pass values with -v and compare keys as strings; do not concatenate them into source code.
  • Atomically replace the original configuration only after successful generation and validation.
  • Reject embedded carriage returns, newlines, and NUL-like data from keys and values unless multiline values are explicitly supported through a safe serialization format.
  • Store configuration in a structured format and use a dedicated serializer or parser instead of regular-expression substitution.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:10
Finding

Unescaped JSON and CSV Serialization Enables Data Corruption and Spreadsheet Formula Injection

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh:10-14, 99-116
Vulnerability Type: Improper output encoding and CSV formula injection
Risk Level: Medium

Vulnerable Code

bash
_save_entry() {
    _ensure_dirs
    local cmd="$1" val="$2"
    local ts=$(date '+%Y-%m-%d %H:%M:%S')
    printf '{"ts":"%s","cmd":"%s","val":"%s"}\n' "$ts" "$cmd" "$val" >> "$DATA_DIR/data.jsonl"
}
bash
cmd_export() {
    local fmt="${1:-json}"
    local out="amr-export.$fmt"
    if [ ! -f "$DATA_DIR/data.jsonl" ]; then echo "No data."; return 0; fi
    case "$fmt" in
        json) cp "$DATA_DIR/data.jsonl" "$out" ;;
        csv)
            echo "timestamp,command,value" > "$out"
            while IFS= read -r line; do
                ts=$(echo "$line" | grep -o '"ts":"[^"]*' | cut -d'"' -f4)
                c2=$(echo "$line" | grep -o '"cmd":"[^"]*' | cut -d'"' -f4)
                vl=$(echo "$line" | grep -o '"val":"[^"]*' | cut -d'"' -f4)
                echo "$ts,$c2,$vl" >> "$out"
            done < "$DATA_DIR/data.jsonl"
            ;;
        *) echo "Formats: json, csv"; return 1 ;;
    esac
    echo "Exported: $out ($(wc -c < "$out") bytes)"
}

Technical Analysis

_save_entry places arbitrary entry text directly between JSON quotation marks. It does not escape quotation marks, backslashes, control characters, or newlines. A crafted entry can therefore terminate the intended JSON string, add fields or records, or make the JSONL store syntactically invalid.

The listing and export logic does not use a JSON parser. It extracts fields with grep and cut, so embedded quotation marks and malformed records can cause incorrect values to be displayed or exported.

CSV export concatenates values with commas without applying RFC 4180 quoting. Commas, quotation marks, and newlines can create additional cells or rows. Values beginning with spreads ...[truncated 1437 chars]

Remediation
View remediation

Remediation Suggestions

  • Use a real JSON serializer, such as jq, rather than constructing JSON with printf.
  • Parse stored records using a JSON parser instead of grep and cut.
  • Reject or correctly encode control characters and newlines according to the JSON specification.
  • Generate CSV with an established CSV library or implement RFC 4180 encoding:
    • Enclose every field in double quotes.
    • Replace each embedded double quote with two double quotes.
    • Preserve commas and newlines only inside properly quoted fields.
  • Neutralize spreadsheet formulas in untrusted fields, for example by prefixing values beginning with =, +, -, or @ with a single quote, while documenting that transformation.
  • Validate existing JSONL records before export and fail safely when malformed data is detected.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:99
Finding

Predictable Export Destinations Permit Symbolic-Link File Overwrite

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh:99-116
Vulnerability Type: Unsafe file creation and symbolic-link following
Risk Level: Medium

Vulnerable Code

bash
cmd_export() {
    local fmt="${1:-json}"
    local out="amr-export.$fmt"
    if [ ! -f "$DATA_DIR/data.jsonl" ]; then echo "No data."; return 0; fi
    case "$fmt" in
        json) cp "$DATA_DIR/data.jsonl" "$out" ;;
        csv)
            echo "timestamp,command,value" > "$out"
            while IFS= read -r line; do
                ts=$(echo "$line" | grep -o '"ts":"[^"]*' | cut -d'"' -f4)
                c2=$(echo "$line" | grep -o '"cmd":"[^"]*' | cut -d'"' -f4)
                vl=$(echo "$line" | grep -o '"val":"[^"]*' | cut -d'"' -f4)
                echo "$ts,$c2,$vl" >> "$out"
            done < "$DATA_DIR/data.jsonl"
            ;;
        *) echo "Formats: json, csv"; return 1 ;;
    esac
    echo "Exported: $out ($(wc -c < "$out") bytes)"
}

Technical Analysis

Export filenames are fixed relative paths:

bash
amr-export.json
amr-export.csv

The script neither checks whether the destination already exists nor rejects symbolic links. The JSON path uses cp, while the CSV path uses shell redirection. These operations can follow a pre-existing destination symbolic link and overwrite its target.

This is a predictable-file vulnerability. It is exploitable when an attacker can create files in the directory from which a more privileged or otherwise higher-value user runs the export command.

Attack Path

  1. The attacker obtains write access to the intended working directory.
  2. The attacker creates amr-export.json or amr-export.csv as a symbolic link to a file writable by the victim account.
  3. The victim or Agent runs the corresponding export command from that directory.
  4. cp or shell redirection follows the symbolic link.
  5. The target file i ...[truncated 679 chars]
Remediation
View remediation

Remediation Suggestions

  • Accept an explicit export path and validate it against an approved destination directory.
  • Refuse to overwrite existing files unless the user explicitly requests replacement.
  • Check for symbolic links with test -L, while recognizing that a check alone does not eliminate time-of-check/time-of-use races.
  • Create output files atomically with exclusive-create semantics and restrictive permissions.
  • Write to a securely created temporary file in the destination directory, then perform an atomic rename only after verifying the destination policy.
  • Set a restrictive umask, such as 077, if exported data may be sensitive.
  • Avoid running exports from shared or untrusted writable directories.
Vulnerability Patterns
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill presents itself as an autonomous mobile robot fleet manager, but the documented behavior is only generic local entry management. This kind of description-behavior mismatch is dangerous because an agent or user may grant the skill elevated trust, invoke it in operational robotics contexts, or rely on it for safety-relevant AMR actions that it does not actually perform.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The banner, help text, and command descriptions present this script as an AMR fleet manager even though the code only stores and searches local entries. Misrepresenting safety- and operations-related functionality increases the risk of operator deception, incorrect automation decisions, and concealment of the tool's true persistence behavior, especially in environments where robotics tools are trusted more than generic local scripts.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill advertises autonomous mobile robot fleet management, but the implementation is a generic local log/notes utility with add/list/search/remove/export/config features and no AMR control or status logic. This kind of capability mismatch is dangerous because it can mislead operators and downstream agents into trusting or invoking a tool for safety-relevant robotics tasks when it actually performs unrelated local data manipulation, indicating possible deceptive packaging or trojanized repurposing.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest advertises AMR fleet management, while the commands describe a generic local CRUD-style entry manager. In an industrial or operational context, this can mislead orchestration systems and users into selecting the wrong skill for robot control or status monitoring, causing incorrect automation decisions and loss of operational visibility.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The top-level documentation claims AMR task and status functionality, but each command is described only in generic terms like add, list, search, and remove entry. This contradiction increases the chance that a human or agent will misunderstand what operational effect a command has, especially in a high-trust industrial setting.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation includes file-modifying and destructive commands such as add, remove, export, and config changes without warning about side effects, data loss, or path risks. In practice, this can lead users or agents to run state-changing operations without confirmation, backups, or understanding where data is stored.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This shell script updates or appends to a persistent config file under the user's data directory, which is a file write operation covered by the missing-warning rule for code files. While it prints a success message after the change, there is no advance disclosure in comments, help text, or a confirmation prompt warning that running the command will modify on-disk configuration.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.