Back to skill

Security audit

Slv Validator

Security checks for vulnerabilities and agentic risk

Overview

This validator automation skill is coherent in purpose, but it asks agents to run high-impact Ansible automation from an unaudited mutable template directory and uses risky setup/install patterns.

Review this skill before installing. Use it only on intended validator hosts, inspect the resolved ~/.slv/template playbooks before any run, avoid curl-to-shell installers, prefer pinned and verified dependencies, and require explicit confirmation for user creation, firewall/systemd changes, identity changes, restarts, and ledger cleanup.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
scripts/setup.sh:87
Finding
Unverified Remote Installer Recommended for Direct Shell Execution<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:87` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```bash else warn "solana-cli not found (optional — only needed for local key generation)" echo " → Install: sh -c \"\$(curl -sSfL https://release.anza.xyz/stable/install)\"" fi ``` ### Technical Analysis The setup script recommends a command that retrieves content from an external URL and immediately supplies the response to `sh`. The retrieved payload is not pinned to a specific version and is not validated using a cryptographic checksum or publisher signature. The command is printed rather than automatically executed, so exploitation requires the user or agent to follow the displayed instruction. Nevertheless, it creates a remote code-execution channel whose effective payload can change after the Skill has been reviewed. HTTPS protects the connection in transit but does not ensure that the remote server, release infrastructure, or delivered script remains trustworthy and immutable. ### Attack Path 1. A user runs `scripts/setup.sh` on a system without `solana-keygen`. 2. The script recommends the `sh -c "$(curl ...)"` installation command. 3. The user or AI agent follows the recommendation. 4. The remote endpoint, its DNS path, hosting infrastructure, or release account has been compromised, or the hosted script has otherwise changed. 5. The returned content is executed directly by the local shell without integrity validation. 6. The payload performs arbitrary actions with the privileges of the invoking account. ### Impact Assessment Successful exploitation permits arbitrary command execution under the account that runs the recommended installer. The payload could read user-accessible SSH credentials and validator configuration, modify shell initialization files, replace command-line tools, or establish persistence within the user account. If the recommendation is ex ...[truncated 189 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not recommend piping or substituting remotely retrieved content directly into a shell. - Pin the Solana CLI installer or package to an explicitly tested version. - Download the artifact to a local file before execution. - Verify a publisher-provided cryptographic signature and a pinned SHA-256 or stronger checksum. - Abort installation if verification fails. - Display the resolved version, source URL, checksum, and installation actions before requesting user approval. - Prefer a trusted package repository or signed release archive over a mutable bootstrap script. - If a bootstrap script is unavoidable, allow the user to inspect it before invoking it in a restricted environment. ]]>

T07 · Tool Hijacking and Spoofing

Error
Location
AGENT.md:155
Finding
Execution of Unverified Playbooks Selected from a User-Writable Template Directory<![CDATA[ ## Vulnerability Details **File Location**: `AGENT.md:155-171` **Vulnerability Type**: Local tool and playbook substitution **Risk Level**: High ### Vulnerable Code ```bash ### Playbook Execution Directory All playbooks are stored in `~/.slv/template/{version}/ansible/`. To find the latest version directory: ```bash TEMPLATE_DIR=$(ls -d ~/.slv/template/*/ | sort -V | tail -1) ``` Example (testnet validator): ```bash TEMPLATE_DIR=$(ls -d ~/.slv/template/*/ | sort -V | tail -1) ansible-playbook -i ~/.slv/inventory.testnet.validators.yml \ ${TEMPLATE_DIR}ansible/testnet-validator/init.yml --limit <identity_pubkey> ``` Do NOT use the skill's own `ansible/` directory for execution. Those files are reference copies. The runtime playbooks live in `~/.slv/template/`. ``` ### Technical Analysis The Skill instructs the agent to discover the highest version-like directory under `~/.slv/template/` and execute an Ansible playbook from it. No checksum, signature, trusted manifest, ownership check, or permission validation is performed before execution. The template directory is located under the user's home directory and is ordinarily writable by that user. Any process operating as that user can therefore create a directory with a version name that sorts after legitimate versions and populate it with substituted playbooks. The legitimate-looking `ansible-playbook` invocation would then execute the substituted tasks. This risk is amplified by the artifact's omission of the advertised `ansible/` playbooks. The audited package only contains documentation, an example inventory, and the setup script. Consequently, the actual deployment logic that the agent is instructed to execute was outside the audit scope and cannot be assumed to match the documented behavior. ### Attack Path 1. An attacker obtains the ability to write files as the local user, such as through another compromised application or package. 2. The attacker creates a directory such as `~/.slv ...[truncated 1368 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Bundle the reviewed Ansible playbooks with the Skill rather than directing execution to unaudited mutable copies. - Pin an explicit template version instead of automatically selecting the highest directory name. - Publish a signed manifest containing the expected paths and cryptographic hashes of every runtime playbook and template. - Verify signatures and hashes immediately before execution. - Validate that the template directory and its parents have expected ownership and are not group- or world-writable. - Resolve the selected path to a canonical path and reject symbolic links or paths outside the trusted template root. - Show the exact resolved playbook path, version, digest, target inventory, and requested privilege escalation before asking for user confirmation. - Fail closed when the pinned version is absent or verification cannot be completed. - Include the runtime playbooks in future security reviews so their privileged and destructive behavior can be assessed directly. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/setup.sh:35
Finding
Unpinned Installation of Ansible from the Active Python Package Index<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:35-38` **Vulnerability Type**: Insecure dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash if command -v pip3 &>/dev/null; then pip3 install --user ansible-core elif command -v pip &>/dev/null; then pip install --user ansible-core ``` ### Technical Analysis The setup script installs `ansible-core` without pinning an exact tested version or verifying package hashes. Package resolution is delegated to the invoking environment's active Python package index and pip configuration. This permits installation of any release considered current by that index, including a future incompatible or compromised release. A malicious or compromised configured mirror could also supply unauthorized package content. No lock file, hash requirement, trusted-index policy, or post-installation integrity check is used. Although `ansible-core` is a legitimate dependency and the package name is not a visible typosquat, the installation mechanism unnecessarily expands supply-chain risk for a tool that will subsequently execute administrative deployment tasks. ### Attack Path 1. A user runs `scripts/setup.sh` without `ansible-playbook` already installed. 2. The script invokes `pip3` or `pip` using the user's existing index and configuration. 3. The configured index, mirror, account, or selected upstream release supplies compromised package content. 4. Pip installs that content into the user's environment. 5. Package installation behavior or the resulting Ansible executable runs attacker-controlled code. 6. Later validator deployment commands may further expose inventories and remote server access to the compromised tool. ### Impact Assessment Installation occurs with `--user`, so the direct privilege level is normally the invoking user's account rather than root. A compromised dependency could access files available to that user, including Ansible inventories, SSH-agent access, SSH ...[truncated 348 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin `ansible-core` to an exact version that has been tested with the Skill. - Maintain a requirements or lock file with hashes and install using hash enforcement, such as pip's `--require-hashes`. - Document and enforce the expected package index rather than silently inheriting arbitrary mirror configuration. - Verify the installed version and abort when it differs from the supported version. - Prefer an isolated virtual environment to avoid modifying the user's general Python environment. - Review and deliberately update the pinned dependency through a controlled release process. - Where operating-system packages are used, document the trusted repository and supported package version. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (17)

Credential Access

High
Category
Privilege Escalation
Content
validator-1:
      ansible_host: "<server-ip>"
      ansible_user: "solv"
      ansible_ssh_private_key_file: "~/.ssh/id_rsa"

  vars:
    # --- Validator Type ---
Confidence
90% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
validator-1:
      ansible_host: "<server-ip>"
      ansible_user: "solv"
      ansible_ssh_private_key_file: "~/.ssh/id_rsa"

  vars:
    # --- Validator Type ---
Confidence
90% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
validator-1:
      ansible_host: "<server-ip>"
      ansible_user: "solv"
      ansible_ssh_private_key_file: "~/.ssh/id_rsa"

  vars:
    # --- Validator Type ---
Confidence
90% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Chaining Abuse

High
Category
Tool Misuse
Content
brew install ansible
  elif [[ "$OS" == "linux" ]]; then
    if command -v apt-get &>/dev/null; then
      sudo apt-get update && sudo apt-get install -y ansible-core
    elif command -v dnf &>/dev/null; then
      sudo dnf install -y ansible-core
    else
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Credential Access

High
Category
Privilege Escalation
Content
warn "SSH agent running but no keys loaded"
    echo "  → Run: ssh-add ~/.ssh/id_rsa (or your key path)"
  fi
elif [[ -f "$HOME/.ssh/id_rsa" ]] || [[ -f "$HOME/.ssh/id_ed25519" ]]; then
  info "SSH keys found (agent not running — Ansible will use key files directly)"
else
  warn "No SSH keys found"
Confidence
90% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
warn "SSH agent running but no keys loaded"
    echo "  → Run: ssh-add ~/.ssh/id_rsa (or your key path)"
  fi
elif [[ -f "$HOME/.ssh/id_rsa" ]] || [[ -f "$HOME/.ssh/id_ed25519" ]]; then
  info "SSH keys found (agent not running — Ansible will use key files directly)"
else
  warn "No SSH keys found"
Confidence
90% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

External Transmission

Medium
Category
Data Exfiltration
Content
1. **Local RPC Response Check** (every 30 seconds):
   ```bash
   curl -s http://localhost:8899 -X POST -H "Content-Type: application/json" \
     -d '{"jsonrpc":"2.0","id":1,"method":"getSlot"}'
   ```
   - No response → still loading ledger, retry
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
3. **Slot Sync Check** (every 60 seconds, after RPC responds):
   ```bash
   # Network latest slot (requires ERPC API key or other reference RPC)
   NETWORK_SLOT=$(curl -s "${REFERENCE_RPC_URL}" \
     -H 'Content-Type: application/json' \
     -d '{"jsonrpc":"2.0","id":1,"method":"getSlot"}' | jq -r '.result')
Confidence
84% confidence
Finding
The skill instructs use of a user-configurable external RPC endpoint (`REFERENCE_RPC_URL`) for monitoring, which causes outbound network communication to a third party. While the payload is only `getSlot`, the endpoint could expose infrastructure metadata, encourage use of API-keyed services, and create a path for sending data to arbitrary external hosts if the variable is not constrained.

External Transmission

Medium
Category
Data Exfiltration
Content
-d '{"jsonrpc":"2.0","id":1,"method":"getSlot"}' | jq -r '.result')

   # Local slot
   LOCAL_SLOT=$(curl -s http://localhost:8899 -X POST -H 'Content-Type: application/json' \
     -d '{"jsonrpc":"2.0","id":1,"method":"getSlot"}' | jq -r '.result')

   DIFF=$((NETWORK_SLOT - LOCAL_SLOT))
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
89% confidence
Finding
This markdown file advertises deploying validators, managing lifecycle, configuring firewall, systemd services, and log rotation, all of which can affect system integrity and availability. The description does not include any cautionary warning about modifying target servers, service disruption risk, or the need to verify environment and credentials before use.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill documents a cleanup playbook that removes ledger and snapshot files but does not explicitly warn that these operations are destructive and may cause irreversible data loss, longer recovery times, or service interruption. In an automation skill for validator operators, omission of a warning increases the chance of accidental execution by users who may interpret the command as routine maintenance.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
Several testnet playbooks explicitly remove ledger data or combine restart actions with ledger deletion, yet the documentation provides no clear safety notice about destructive side effects. Because these are operational runbooks intended for direct execution, the lack of warnings materially increases the risk of accidental data deletion and validator downtime.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script automatically installs packages using pip, Homebrew, apt, or dnf, including privileged package-manager paths and a later curl-based installer recommendation, without any confirmation or integrity verification step. In an agent-skill context, this is risky because running setup as instructed can cause unintended system changes and trust network/package sources implicitly.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
brew install ansible
  elif [[ "$OS" == "linux" ]]; then
    if command -v apt-get &>/dev/null; then
      sudo apt-get update && sudo apt-get install -y ansible-core
    elif command -v dnf &>/dev/null; then
      sudo dnf install -y ansible-core
    else
Confidence
96% confidence
Finding
The script invokes sudo apt-get update && sudo apt-get install -y ansible-core, which performs privileged system modification non-interactively. In a skill setup script, automatic elevation increases risk because a user may run it without realizing it will change system packages as root.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
if command -v apt-get &>/dev/null; then
      sudo apt-get update && sudo apt-get install -y ansible-core
    elif command -v dnf &>/dev/null; then
      sudo dnf install -y ansible-core
    else
      error "Cannot auto-install ansible-core. Please install manually: pip3 install ansible-core"
      exit 1
Confidence
95% confidence
Finding
The script invokes sudo dnf install -y ansible-core, which is a privileged package installation with automatic approval. This can unexpectedly alter the host system and is especially concerning in an AI-agent workflow where users may execute helper scripts with limited review.

Missing User Warnings

Low
Confidence
82% confidence
Finding
The pre-flight command creates a user on the target system with elevated privileges via `--become`, which affects system accounts and access configuration. The markdown does not explicitly warn the user that this step performs administrative changes on the remote host.

Missing User Warnings

Low
Confidence
76% confidence
Finding
The script checks SSH_AUTH_SOCK and runs ssh-add -l to inspect the user's loaded SSH keys. While it does not expose private key material, this is access to sensitive authentication state and there is no prior comment or user-facing notice explaining that the script will query the SSH agent.

Static analysis

Detected: suspicious.generated_source_template_injection

User-controlled placeholder is embedded directly into generated source code.

Critical
Code
suspicious.generated_source_template_injection
Location
AGENT.md:197