Back to skill

Security audit

Pilot Matchmaker

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for finding and ranking peer agents, but its example trust scoring can misclassify an untrusted peer as trusted if a peer ID is crafted maliciously.

Review the trust-ranking example before installing or using it for real delegation. It should compare node IDs as exact literals and preserve JSON values safely; otherwise a crafted peer identifier could be ranked as trusted and selected for later work.

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

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:58
Finding

Regex Injection in Peer Trust Evaluation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 58-66
Vulnerability Type: Improper validation of attacker-influenced peer identifiers
Risk Level: Medium

Vulnerable Code

bash
candidates=$(pilotctl --json peers --search "$requirements" | jq -r '.peers[].node_id')
trusted=$(pilotctl --json trust | jq -r '.trusted[].node_id')

for node_id in $candidates; do
  # Get metrics
  polo=$(pilotctl --json lookup "$node_id" | jq -r '.polo_score // 0')
  latency=$(pilotctl --json ping "$node_id" 2>/dev/null | jq -r '.avg_rtt_ms // 999')
  is_trusted=$(echo "$trusted" | grep -q "$node_id" && echo 1 || echo 0)

Technical Analysis

Candidate node IDs originate from peer-discovery output and may therefore be influenced by remote peers. The workflow passes each node ID directly to grep as a regular-expression pattern:

bash
grep -q "$node_id"

Shell quoting prevents word expansion at this call site, but it does not make the pattern literal. Metacharacters such as .*, ^, $, or character classes retain their regular-expression meaning. A node ID beginning with - can also be interpreted as a grep option because the command does not use --.

Consequently, a crafted candidate ID can match an unrelated entry in the trusted-node list. The workflow would then assign the candidate a 30-point trust bonus even though its exact identifier is absent from that list.

The loop also uses for node_id in $candidates, which applies shell whitespace splitting to values extracted from JSON rather than preserving each identifier as an exact array element.

Attack Path

  1. An attacker advertises a peer whose node ID is a matching regular expression, such as .*, assuming the protocol permits such characters or fails to validate identifiers upstream.
  2. pilotctl --json peers --search returns the attacker-controlled identifier as a candidate.
  3. The unquoted array-style loop processes the extracted text using shell word splittin ...[truncated 1043 chars]
Remediation
View remediation

Remediation Suggestions

Use exact, literal, whole-line matching, terminate command options explicitly, and preserve JSON values as shell array elements:

bash
mapfile -t candidates < <(
  pilotctl --json peers --search "$requirements" |
    jq -r '.peers[].node_id'
)

mapfile -t trusted < <(
  pilotctl --json trust |
    jq -r '.trusted[].node_id'
)

for node_id in "${candidates[@]}"; do
  if printf '%s\n' "${trusted[@]}" | grep -Fqx -- "$node_id"; then
    is_trusted=1
  else
    is_trusted=0
  fi

  # Continue scoring with the validated identifier.
done

For stronger hardening:

  1. Compare candidate and trusted identifiers directly in jq rather than converting structured JSON into shell-delimited text.
  2. Validate every node ID against the protocol's canonical identifier format before using it in commands.
  3. Reject empty, malformed, option-like, or noncanonical identifiers.
  4. Treat trust as an exact identity assertion rather than a substring or pattern match.
  5. Fail closed when trust output is malformed or unavailable.
  6. Add regression tests covering regex metacharacters, leading hyphens, whitespace, empty identifiers, and identifiers that are prefixes of trusted IDs.
Vulnerability Patterns
  • 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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep

Static analysis

No suspicious patterns detected.