Back to skill

Security audit

Slv Grpc Geyser

Security checks for vulnerabilities and agentic risk

Overview

This skill is for legitimate Solana node operations, but it relies on high-impact remote administration and unverified external runtime playbooks that users should review carefully before installing.

Install only if you trust the SLV template source and will review the resolved ~/.slv/template playbook path before execution. Use this on intended hosts only, run dry-run/check mode first, avoid production restarts without change approval, and prefer manually installing pinned prerequisites instead of running automatic setup paths.

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:88
Finding
Mutable Remote Installation Script Recommended for Direct Shell Execution<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:88` **Vulnerability Type**: Remote code retrieval and execution through a `curl`-to-shell command **Risk Level**: High ### Vulnerable Code ```bash echo " → Install: sh -c \"\$(curl -sSfL https://release.anza.xyz/stable/install)\"" ``` ### Technical Analysis The setup script recommends downloading a shell script from an external URL and passing its contents directly to `sh`. Although `setup.sh` only prints this command rather than executing it automatically, it presents the command as the supported installation procedure. The effective code executed by the user is not included in the audited package. It is also not pinned to a specific immutable release, checksum, or cryptographic signature. The remote payload can therefore change after the Skill has been reviewed. HTTPS protects data in transit but does not establish that the response is the same artifact that was reviewed. A compromise of the release infrastructure, domain, DNS resolution, TLS trust chain, or upstream publishing credentials could replace the response with arbitrary shell code. ### Attack Path 1. The user runs `scripts/setup.sh`. 2. The script reports that `solana-cli` is unavailable and displays the installation command. 3. The user copies and executes the recommended command. 4. The command retrieves the current response from `https://release.anza.xyz/stable/install`. 5. If the response or delivery infrastructure has been compromised, attacker-controlled shell code is passed directly to `sh`. 6. The payload executes with the privileges and environment of the invoking user and can modify user-owned files, steal accessible credentials, or establish persistence. ### Impact Assessment Successful exploitation provides arbitrary code execution under the account that runs the recommended command. The payload could access the user's SSH configuration and other user-readable credentials, modify shell startup files, tampe ...[truncated 227 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not recommend piping network responses directly into a shell. - Pin the installation to a specific, reviewed release rather than a mutable `stable` endpoint. - Download the artifact to a local file before execution. - Verify a cryptographic signature or a checksum obtained through an independently authenticated channel. - Display the resolved version, source URL, and expected digest to the user. - Require explicit confirmation before executing any downloaded installer. - Prefer installation through a trusted, signed package repository when available. - Document a manual inspection procedure, for example: ```bash curl --fail --location --output solana-install.sh \ "https://example.invalid/releases/<fixed-version>/install.sh" printf '%s %s\n' "<expected-sha256>" "solana-install.sh" | sha256sum --check less solana-install.sh sh solana-install.sh ``` ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/setup.sh:35
Finding
Automatic Installation of Unpinned Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:35-46` **Vulnerability Type**: Unpinned package installation from mutable dependency sources **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 elif [[ "$OS" == "macos" ]] && command -v brew &>/dev/null; then 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 ``` ### Technical Analysis The setup script automatically installs whichever version of Ansible is current in the selected package source. It does not enforce the documented minimum version, pin a reviewed release, verify an expected artifact digest, or use a lock file. The installed dependency directly controls later Ansible execution and parsing of inventories, plugins, and playbooks. Consequently, a compromised package index, repository mirror, publisher account, or unexpectedly incompatible future release can change deployment behavior after the Skill itself has been audited. The `pip` branches install with the invoking user's privileges. The `apt-get` and `dnf` branches invoke `sudo`, causing package installation and associated maintainer scripts to run with root privileges. Although signed operating-system repositories reduce this risk, the script does not verify repository configuration or provenance before using them. ### Attack Path 1. The user runs `scripts/setup.sh` on a system without `ansible-playbook`. 2. The script selects the first available package manager. 3. It requests the current, unpinned `ansible-core` or `ansible` package. 4. A compromised dependency source, mirror, publishing account, or repository configuration supplies a malicious package or dependency. 5. Installation code r ...[truncated 688 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin Ansible to a specific tested release compatible with the Skill. - For Python installation, use a dedicated virtual environment and a hash-locked requirements file, such as: ```text ansible-core==<reviewed-version> \ --hash=sha256:<verified-package-hash> ``` - Install with `pip --require-hashes` and include hashes for all transitive dependencies. - For operating-system packages, verify that configured repositories are trusted, signed, and expected before invoking `sudo`. - Avoid silently selecting whichever package source is available. - Show the exact package, version, repository, and command, then request explicit user confirmation. - Validate the installed version after installation and fail if it does not match the supported range. - Consider separating prerequisite checks from installation so users can provision dependencies through their established administrative controls. ]]>

T07 · Tool Hijacking and Spoofing

Error
Location
AGENT.md:113
Finding
Execution of Automatically Selected Playbooks Outside the Audited Skill Package<![CDATA[ ## Vulnerability Details **File Location**: `AGENT.md:113-127` **Vulnerability Type**: Untrusted tool and playbook selection from mutable local storage **Risk Level**: High ### Vulnerable Code ```bash 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 (mainnet RPC): ```bash TEMPLATE_DIR=$(ls -d ~/.slv/template/*/ | sort -V | tail -1) ansible-playbook -i ~/.slv/inventory.mainnet.rpcs.yml \ ${TEMPLATE_DIR}ansible/mainnet-rpc/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 Agent is instructed to disregard package-local reference files and execute a playbook from the highest version-like directory under `~/.slv/template/`. The selected files are outside the audited artifact, and the procedure performs no checksum, signature, ownership, permission, provenance, or expected-version verification. Selection through `sort -V | tail -1` means that merely creating a directory with a higher version name can redirect execution to different playbooks. The command also does not safely handle unexpected path names, absent directories, or symbolic links. Ansible playbooks can execute commands on managed hosts, copy files, install packages, invoke privileged tasks through `become`, and load controller-side extensions such as plugins. User confirmation of a normal node deployment does not establish informed consent to execute substituted playbook content that was never displayed or verified. The supplied project contains no `ansible/` tree despite documentation describing one, so the actual runtime deployment implementation could not be reviewed as part of this audit. ### Attack Path 1. An attacker or compromised updater gains the ability to create or replace co ...[truncated 1237 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Bundle the reviewed runtime playbooks with the Skill, or pin an exact trusted template release rather than automatically selecting the highest directory. - Verify a cryptographic signature or manifest of checksums before executing any external template. - Validate that the template directory and every parent directory have expected ownership and are not writable by untrusted users. - Reject symbolic links and resolve the canonical path before execution. - Display the exact resolved playbook path, version, signer, and checksum before requesting user confirmation. - Show the playbook diff or task summary when the template differs from the previously approved version. - Run `ansible-playbook --syntax-check` and an appropriate check-mode review before deployment. - Restrict inventory scope and privilege escalation explicitly. - Avoid loading Ansible plugins, roles, or collections from unverified writable locations. - Treat confirmation as valid only for the exact verified digest shown to the user. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Credential Access

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

  vars:
    # --- RPC 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
grpc-1:
      ansible_host: "<server-ip>"
      ansible_user: "solv"
      ansible_ssh_private_key_file: "~/.ssh/id_rsa"

  vars:
    # --- RPC 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
grpc-1:
      ansible_host: "<server-ip>"
      ansible_user: "solv"
      ansible_ssh_private_key_file: "~/.ssh/id_rsa"

  vars:
    # --- RPC 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
```bash
   # Check if gRPC port is listening (default: 10000)
   ss -tlnp | grep ':10000'
   # Or use grpcurl if available:
   grpcurl -plaintext localhost:10000 list
   ```
   - Port not listening → Geyser plugin still loading, 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
-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
90% confidence
Finding
The README explicitly frames the skill as able to deploy, build, and manage Solana gRPC Geyser nodes, including lifecycle actions like stop, restart, and update, but it does not warn that these operations modify remote infrastructure and can interrupt service availability. In an AI-agent skill context, omitting that warning increases the chance a user or agent invokes disruptive actions on production hosts without understanding the operational risk.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The markdown describes commands for full node initialization, start/stop/restart, updates, and Firedancer setup, all of which can change system state, services, and configuration on remote hosts. The file presents these operations as routine usage without an explicit warning that they will modify target servers and may impact running services.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script automatically installs software and may invoke privileged package-manager commands that modify the host system, but it does not provide a clear upfront warning or require explicit confirmation before doing so. In an agent-skill context, this is risky because users may run the setup helper expecting a passive check, while it can perform system-wide changes and pull packages from external sources.

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
95% confidence
Finding
This line invokes sudo to run apt-get update and install ansible-core, which causes privileged system changes. Even though the goal appears legitimate, embedding sudo execution in a setup script can surprise users, expand blast radius if the script is altered, and normalize running agent-provided code with elevated privileges.

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
94% confidence
Finding
This line similarly uses sudo with dnf to install ansible-core, performing privileged package installation on Linux systems. In a setup helper distributed as part of an agent skill, unattended elevation is dangerous because users may trust and run it without closely reviewing all system-impacting operations.

Missing User Warnings

Low
Confidence
79% confidence
Finding
The skill instructs users to clone and build privileged infrastructure components from external GitHub repositories based on user-supplied version tags, but it provides no integrity verification, commit pinning, provenance validation, or warning about supply-chain risk. In the context of validator/gRPC node deployment, building unverified third-party code can lead to execution of malicious or compromised source during build or runtime on production servers.

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:149