Back to skill

Security audit

web-snippet-extractor

Security checks for vulnerabilities and agentic risk

Overview

The skill has a legitimate snippet-extraction purpose, but its included script can fetch arbitrary URLs without enforcing the stated public-page boundary.

Review this skill before installing if your agent runs in an environment with access to internal services, local files, or cloud metadata. Use it only with trusted public HTTP/HTTPS pages, and prefer the documented web_fetch workflow over the included shell script unless URL validation is added.

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
scripts/extract.sh:7
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery and Local Resource Access

Content
View full analysis

Vulnerability Details

File Location: scripts/extract.sh, lines 7–18
Vulnerability Type: Unrestricted user-controlled URL fetching
Risk Level: Medium

Vulnerable Code

bash
URL="${1:?Usage: extract.sh <url> [max-chars]}"
MAX_CHARS="${2:-20000}"

if ! command -v curl &>/dev/null; then
  echo "Error: curl is required" >&2
  exit 1
fi

echo "# Snippets from: $URL"
echo ""

# Fetch and extract code blocks using grep if no pandoc
html=$(curl -sL --max-time 30 "$URL")

Technical Analysis

The script accepts a URL directly from the user and passes it to curl without validating its scheme, hostname, resolved IP address, or destination network. Although SKILL.md states that the target URL must be publicly accessible, the executable script does not enforce that requirement.

The use of curl -L follows redirects without checking each redirect destination. An apparently public URL can therefore redirect to a loopback, private, link-local, or cloud metadata address. Curl may also support non-HTTP schemes such as file://, depending on the installed build and protocol configuration. This can permit the script to read resources accessible to the local process.

The command also lacks an explicit -- option terminator before the user-controlled URL. A value beginning with - may consequently be interpreted by curl as an option rather than as a destination. This broadens the possible misuse of the curl invocation, although no direct shell command injection is present because the variable is quoted.

Attack Path

  1. An attacker or untrusted user supplies a crafted URL to scripts/extract.sh.
  2. The URL references a local file, an internal service, a loopback endpoint, a private network host, or a public endpoint that redirects to such a destination.
  3. The script passes the value directly to curl and follows redirects.
  4. Curl retrieves the resource using the network ...[truncated 1381 chars]
Remediation
View remediation

Remediation Suggestions

  1. Restrict accepted schemes to https:// and, only if operationally necessary, http://. Reject file://, ftp://, gopher://, and all other protocols.
  2. Parse URLs with a dedicated URL parser rather than regular expressions. Reject embedded credentials, malformed hosts, ambiguous numeric IP representations, and unexpected ports.
  3. Resolve the hostname before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges.
  4. Revalidate the destination after every redirect. Alternatively, disable redirects or implement bounded redirect handling in application logic.
  5. Add an option terminator before the URL:
    bash
    html=$(curl -sS --max-time 30 --proto '=http,https' --proto-redir '=http,https' -- "$URL")
    
    Protocol restrictions alone do not prevent access to private HTTP services, so network-range validation is still required.
  6. Prefer an explicit hostname allowlist when the expected documentation sources are known.
  7. Run the script in a sandbox with restricted filesystem access, blocked cloud metadata endpoints, and egress controls that deny internal network ranges.
  8. Apply equivalent destination validation to the documented web_fetch workflow so that the script and agent instructions enforce the same public-resource policy.
  9. Add tests covering file:// URLs, localhost, private IPv4 and IPv6 addresses, link-local metadata endpoints, DNS results resolving to private addresses, public-to-private redirects, and values beginning with -.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The description says to use the skill whenever you find a documentation page, blog post, or tutorial and need actionable code blocks, which is a wide class of everyday browsing and coding-assistance scenarios. It does not define clear boundaries or exclusions for when this skill should be invoked instead of more general summarization or extraction skills.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.