Back to skill

Security audit

VM Health Check

Security checks for vulnerabilities and agentic risk

Overview

This VM-check skill is mostly coherent, but it should be reviewed before install because it uses unsafe SSH handling, persists connection metadata, and can run remote Docker cleanup.

Install only if you are comfortable with this skill accessing a remote Docker host over SSH and storing the VM host, username, and SSH key path in TOOLS.md. Before use, the publisher should fix SSH argument construction, restore host-key verification, validate config values, and require explicit confirmation for cleanup actions.

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
scripts/vm-check.sh:16
Finding

SSH Option Injection Through Unquoted Command Construction

Content
View full analysis

Vulnerability Details

File Location: scripts/vm-check.sh:16-28
Vulnerability Type: SSH option injection and potential local command execution
Risk Level: High

bash
SSH_KEY="${SSH_KEY:-~/.ssh/id_rsa}"
VM_HOST="${VM_HOST:?VM_HOST is required. Set it via: VM_HOST=<host> bash vm-check.sh}"
VM_USER="${VM_USER:-ubuntu}"
SECTION="${1:-all}"

SSH_CMD="ssh -i $SSH_KEY -o StrictHostKeyChecking=no $VM_USER@$VM_HOST"

run_section() {
  local name="$1"
  local cmd="$2"
  echo "=== $name ==="
  $SSH_CMD "$cmd" 2>/dev/null
  echo ""
}

The same unsafe expansion pattern is also used for direct SSH calls at lines 69, 82, 96, 99, and 100.

Technical Analysis

The script constructs an SSH invocation as a scalar string and subsequently expands $SSH_CMD without quotes. Bash performs word splitting and pathname expansion on this value. Consequently, whitespace and option-like content supplied through SSH_KEY, VM_USER, or VM_HOST can become additional arguments to the local ssh process.

This is particularly dangerous because OpenSSH supports options such as ProxyCommand, which can cause a local process to be launched. An attacker who can influence the saved VM configuration or the environment passed to the script could place additional SSH options in one of these values. The script performs no validation to ensure that the key is a single path, that the username and hostname have valid syntax, or that injected options are rejected.

Although the Skill requires SSH access for its declared VM-checking functionality, accepting arbitrary SSH arguments is not necessary and exceeds the minimum safe behavior.

Attack Path

  1. An attacker influences a VM configuration value stored in TOOLS.md, or otherwise controls an environment variable such as SSH_KEY.
  2. The Agent extracts that value and passes it to vm-check.sh.
  3. The value includes whitespace followed by an additional SSH op ...[truncated 1043 chars]
Remediation
View remediation

Remediation Suggestions

Construct the SSH command as a Bash array so that every value remains exactly one argument:

bash
SSH_KEY="${SSH_KEY:-$HOME/.ssh/id_rsa}"

SSH_CMD=(
  ssh
  -i "$SSH_KEY"
  -o StrictHostKeyChecking=yes
  --
  "$VM_USER@$VM_HOST"
)

run_section() {
  local name="$1"
  local cmd="$2"
  echo "=== $name ==="
  "${SSH_CMD[@]}" "$cmd"
  echo
}

Apply the array form to every SSH invocation rather than expanding a command string. In addition:

  • Validate VM_USER against the syntax allowed for expected remote usernames.
  • Validate VM_HOST as a hostname, IPv4 address, or IPv6 address and reject whitespace, control characters, and leading hyphens.
  • Require SSH_KEY to resolve to an expected regular file and reject newline or control characters.
  • Use $HOME/.ssh/id_rsa rather than a literal tilde inside parameter expansion.
  • Treat values recovered from TOOLS.md as untrusted configuration rather than shell-safe text.
  • Preserve SSH errors or report them safely instead of suppressing all diagnostics with 2>/dev/null.

T09 ยท Insecure Skill Coding Practices

Warning
Location
scripts/vm-check.sh:21
Finding

SSH Host Authentication Disabled

Content
View full analysis

Vulnerability Details

File Location: scripts/vm-check.sh:21
Vulnerability Type: Missing SSH server identity verification
Risk Level: Medium

bash
SSH_CMD="ssh -i $SSH_KEY -o StrictHostKeyChecking=no $VM_USER@$VM_HOST"

Technical Analysis

StrictHostKeyChecking=no instructs SSH to accept previously unknown host keys automatically and weakens protection when identifying the remote endpoint. This prevents the Skill from reliably establishing that it is communicating with the intended VM.

SSH authentication is required by the declared functionality, but disabling server identity validation is not. Secure host-key verification can be retained without granting the Skill additional privileges.

Attack Path

  1. The Agent initiates an SSH connection to the configured VM.
  2. An attacker with control over DNS, routing, the local network, or the target address redirects the connection to an impersonating SSH server.
  3. The attacker presents an untrusted host key.
  4. Because strict host-key checking is disabled, the connection may proceed without meaningful identity confirmation.
  5. The Skill sends its remote health-check or Docker command to the impersonating endpoint.
  6. The attacker observes operational requests and returns fabricated output that the Agent may present as genuine VM status.

Impact Assessment

An attacker may learn the configured username, connection timing, and the administrative commands requested by the Skill. They may also falsify system-health, database-size, container, disk-usage, or cleanup results.

Public-key authentication ordinarily does not transmit the private key itself, so this setting alone does not disclose the key file. The principal impacts are loss of endpoint authenticity, exposure of operational metadata, and compromised integrity of audit results.

Remediation
View remediation

Remediation Suggestions

  • Remove StrictHostKeyChecking=no and use standard SSH host-key verification.
  • Provision the expected VM key in a dedicated known_hosts file before running checks.
  • For first-time enrollment, display and require confirmation of the host-key fingerprint through a trusted channel.
  • If automatic first connection is required, use StrictHostKeyChecking=accept-new; this is weaker than pre-provisioning but safer than unconditional acceptance.
  • Consider specifying a dedicated file with UserKnownHostsFile to isolate Skill-managed hosts without weakening the user's global SSH configuration.
  • Treat host-key changes as security errors and stop rather than silently continuing.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill is presented as a health-check/reporting tool, but its documented behavior includes cleanup actions and references behavior not disclosed in the user-facing description, including SSH-related handling. That mismatch is dangerous because users may invoke it expecting read-only diagnostics while the underlying workflow can modify remote Docker state or weaken trust assumptions around remote access.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

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

Content

Scanner excerpt ยท SKILL.md (reported line 36)May include surrounding context.

md
# Configure via environment variables:
#   VM_HOST   - VM IP or hostname (required)
#   VM_USER   - SSH username (default: ubuntu)
#   SSH_KEY   - Path to SSH private key (default: ~/.ssh/id_rsa)
#
# Example:
#   VM_HOST=10.0.0.1 VM_USER=ubuntu SSH_KEY=~/.ssh/mykey bash vm-check.sh

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

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

Content

Scanner excerpt ยท scripts/vm-check.sh (reported line 9)May include surrounding context.

sh
# Configure via environment variables:
#   VM_HOST   - VM IP or hostname (required)
#   VM_USER   - SSH username (default: ubuntu)
#   SSH_KEY   - Path to SSH private key (default: ~/.ssh/id_rsa)
#
# Example:
#   VM_HOST=10.0.0.1 VM_USER=ubuntu SSH_KEY=~/.ssh/mykey bash vm-check.sh

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

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

Content

Scanner excerpt ยท scripts/vm-check.sh (reported line 16)May include surrounding context.

sh
# Configure via environment variables:
#   VM_HOST   - VM IP or hostname (required)
#   VM_USER   - SSH username (default: ubuntu)
#   SSH_KEY   - Path to SSH private key (default: ~/.ssh/id_rsa)
#
# Example:
#   VM_HOST=10.0.0.1 VM_USER=ubuntu SSH_KEY=~/.ssh/mykey bash vm-check.sh

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

A skill advertised for health checks should not silently bundle destructive cleanup operations, because operators may trigger it during routine inspection and unintentionally delete images or caches needed for rollback or debugging. Even if some prune operations are commonly considered low risk, they still change system state and can disrupt operations when unexpectedly executed.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases are broad enough to match common administrative language, increasing the chance that the skill runs in contexts where the user only wanted general advice, not remote access or potentially mutating actions. In an environment with automatic tool selection, ambiguous triggers can cause unintended execution against production systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs the agent to persist SSH connection details, including the private key path, in TOOLS.md without warning about sensitivity, access scope, or retention. Persisting infrastructure access metadata in a general project file can expose internal hosts and credential locations to other tools, collaborators, or future prompts that read that file.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest says the first run asks for VM details once, saves them, and never asks again. This script instead requires configuration through environment variables, hard-fails if VM_HOST is unset, and contains no prompting or persistence logic, so the implemented behavior does not match the advertised workflow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The SSH command disables host key verification with -o StrictHostKeyChecking=no, which makes man-in-the-middle attacks materially easier. Because this skill connects to remote infrastructure and can run privileged Docker and database inspection commands, trusting any presented host key can expose credentials, infrastructure metadata, and enable command interception or redirection.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script includes destructive cleanup actions (docker image prune -af and docker builder prune -f) in a skill primarily presented as a VM health-check tool. In this context, users may reasonably expect read-only diagnostics, so bundling state-changing operations increases the chance of accidental disruption, removal of cached artifacts, and operational impact on the remote host.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation says 'Never run docker system prune -af without explicit user approval (destroys volumes)'. However, docker system prune -af does not remove volumes unless --volumes is also specified, so the comment misstates what the command actually does. This is an intent/documentation divergence that could mislead operators about the command's real impact.

Content

No source excerpt is available for this finding.