Back to skill

Security audit

Perftest

Security checks for vulnerabilities and agentic risk

Overview

This HTTP benchmarking skill is mostly purpose-aligned, but unsafe argument handling can let crafted inputs make curl read and send local files, and report commands can read arbitrary local files.

Review before installing. Only run this skill with trusted, simple HTTP or HTTPS targets and avoid using report or compare on sensitive paths. The package should be fixed to quote arguments, use curl --, validate URLs and counts, and restrict report files to its own data directory.

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

Error
Location
scripts/script.sh:84
Finding

Unquoted User Input Enables curl Option Injection and Local File Exfiltration

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh, lines 84-100
Vulnerability Type: curl argument and option injection
Risk Level: High

Vulnerable Code

bash
cmd_http() {
    local url="${2:-}"
    local count="${3:-}"
    [ -z "$url" ] && die "Usage: $SCRIPT_NAME http <url count>"
    echo 'Testing $2 ($((${3:-5})) requests)'; for i in $(seq 1 ${3:-5}); do curl -so /dev/null -w '%{time_total}' $2 2>/dev/null; echo; done | awk '{s+=$1;n++} END{printf "Avg: %.3fs\n",s/n}'
}

cmd_latency() {
    local host="${2:-}"
    [ -z "$host" ] && die "Usage: $SCRIPT_NAME latency <host>"
    curl -so /dev/null -w 'DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n' $2 2>/dev/null
}

cmd_throughput() {
    local url="${2:-}"
    [ -z "$url" ] && die "Usage: $SCRIPT_NAME throughput <url>"
    curl -so /dev/null -w '%{speed_download}' $2 2>/dev/null | awk '{printf "Speed: %.0f bytes/sec\n",$1}'
}

Technical Analysis

The http, latency, and throughput handlers pass the user-controlled $2 positional parameter to curl without quoting it and without using the -- end-of-options delimiter. Bash consequently performs word splitting and pathname expansion before invoking curl.

An attacker can supply a single argument containing spaces and curl options. After shell expansion, curl receives those words as independent command-line arguments rather than as one URL. Options such as --data-binary @FILE, --upload-file FILE, or --config FILE can cause curl to read local resources and transmit their contents to an attacker-controlled server.

The handlers also use incorrect positional parameters. main removes the command name with shift before invoking each handler, but the handlers read the primary value from $2 rather than $1. This breaks documented invocations, but does ...[truncated 1445 chars]

Remediation
View remediation

Remediation Suggestions

  1. Correct positional-argument handling after main performs shift. Read the primary argument from $1 and the optional count from $2.
  2. Store arguments in local variables and quote every expansion.
  3. Insert -- before the URL so curl cannot interpret it as an option.
  4. Reject values beginning with -.
  5. Parse and validate URLs, allowing only explicitly supported schemes such as http:// and https://.
  6. Validate request counts as bounded positive integers before passing them to seq.
  7. Consider restricting access to loopback, link-local, private, and cloud metadata addresses if untrusted users can select targets.

Example hardened implementation:

bash
cmd_throughput() {
    local url="${1:-}"
    [ -z "$url" ] && die "Usage: $SCRIPT_NAME throughput <url>"

    case "$url" in
        http://*|https://*) ;;
        *) die "Only HTTP and HTTPS URLs are supported" ;;
    esac

    curl -so /dev/null -w '%{speed_download}' -- "$url" 2>/dev/null |
        awk '{printf "Speed: %.0f bytes/sec\n", $1}'
}

Apply the same quoting, validation, corrected indexing, and -- delimiter pattern to every affected curl invocation.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (6)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill invokes shell scripts that perform network activity, but the manifest does not declare any tool scope or permission boundaries. This creates an under-specified trust model: users or orchestration systems cannot clearly determine that the skill needs shell and network capabilities before execution, increasing the chance of unintended outbound requests or command execution.

Content

No source excerpt is available for this finding.

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
80% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · scripts/script.sh (reported line 9)May include surrounding context.

sh
DATA_DIR="$HOME/.local/share/perftest"
mkdir -p "$DATA_DIR"

#
#
#
#

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script issues HTTP requests via curl in the http, latency, and throughput commands, which transmit user-supplied targets over the network. Although usage strings exist, there is no clear disclosure, confirmation, or descriptive comment warning that these commands will contact remote hosts and generate network traffic.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill exposes local file-reading/reporting behavior via the report and compare commands, which use user-supplied paths with cat and head. That capability exceeds the stated purpose of HTTP performance benchmarking and can disclose arbitrary local file contents if the agent or user is induced to run those commands on sensitive files.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Arbitrary local file access is unjustified for a web-service benchmarking skill and creates an unnecessary data-exposure surface. Because file paths are taken directly from arguments and passed unquoted to commands, the skill can read any readable local file rather than only benchmark artifacts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This markdown file states that data is stored under ~/.local/share/perftest/, but it does not warn users that running performance and stress tests may create persistent local artifacts. Because markdown files should disclose behaviors that could affect user data or system state, this storage behavior should be surfaced more explicitly as a user warning.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.