Back to skill

Security audit

Find RSS

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent RSS-discovery purpose, but its helper script can make unrestricted network requests to user-supplied URLs and followed redirects, including internal or local services.

Install only if you are comfortable allowing the skill to fetch URLs from the agent's network environment. Prefer using it only with explicit public http/https website URLs, and avoid running it where the agent has access to private networks, localhost admin services, or cloud metadata endpoints unless the runtime blocks those destinations.

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/find-rss.sh:18
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/find-rss.sh, lines 5, 18, 48, and 72–76
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: High

Vulnerable Code

bash
URL="$1"
bash
# Fetch the page and extract RSS/Atom links
echo "📄 Checking HTML for RSS link tags..."
RSS_LINKS=$(curl -s -L "$URL" | grep -iE 'type="application/(rss|atom)"|rel="alternate"' | grep -iE 'href="[^"]*"' | sed 's/.*href="\([^"]*\)".*/\1/' | sort -u)
bash
# Extract domain
DOMAIN=$(echo "$URL" | sed -E 's|(https?://[^/]+).*|\1|')
bash
for path in "${COMMON_PATHS[@]}"; do
    TEST_URL="${DOMAIN}${path}"
    STATUS=$(curl -s -o /dev/null -w "%{http_code}" -L "$TEST_URL" 2>/dev/null)
    if [ "$STATUS" = "200" ]; then
        # Check if it's actually an RSS/Atom feed
        CONTENT_TYPE=$(curl -s -I -L "$TEST_URL" 2>/dev/null | grep -i "content-type" | head -1)

Technical Analysis

The script accepts a caller-controlled value as URL and passes it directly to curl without validating its scheme, hostname, resolved address, or destination port. It also enables automatic redirect following through -L without validating each redirect target.

Consequently, the script can be induced to request resources that should not be reachable through normal external website discovery, including:

  • Loopback services such as 127.0.0.1 or localhost
  • Private network addresses
  • Link-local and cloud metadata addresses
  • Local resources accessible through non-HTTP protocols supported by the installed curl
  • Internal destinations reached through redirects from an initially public URL

After the initial request, the script derives a domain and probes multiple predictable RSS paths. This expands the issue from a single arbitrary request into limited service and endpoint reconnaissance against the selected host. HTTP status codes, content types, and extracted feed-like ...[truncated 1819 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse the supplied URL with a dedicated URL parser rather than regular expressions.
  2. Permit only explicitly supported schemes, preferably https and, if required, http. Reject file, ftp, gopher, and every other scheme.
  3. Reject URLs containing embedded credentials, malformed hosts, ambiguous numeric IP formats, or unsupported ports.
  4. Resolve the hostname before each request and reject all loopback, private, link-local, multicast, reserved, and unspecified IPv4 and IPv6 ranges.
  5. Explicitly block cloud metadata destinations, including link-local metadata addresses and deployment-specific metadata hostnames.
  6. Disable automatic redirects or validate the scheme, hostname, port, and resolved IP address of every redirect destination before following it.
  7. Account for DNS rebinding by validating resolved addresses at connection time and avoiding untrusted re-resolution between validation and connection.
  8. Pass a validated URL to curl after an option terminator and restrict protocols explicitly, for example with --proto '=http,https'.
  9. Add connection and total request timeouts, response-size limits, and a maximum redirect count to reduce denial-of-service exposure.
  10. Run the skill in an egress-restricted sandbox that cannot access localhost, private networks, metadata services, or other sensitive destinations.
  11. Apply the same validation to the initial page request, every generated common-path URL, and every redirect target.
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
82% confidence
Finding

The skill invokes a shell script directly, but the manifest does not declare any explicit tool scope or permissions. That creates ambiguity about what execution capabilities the skill requires and can lead to over-broad runtime access or unsafe approval of shell-capable skills without clear review boundaries.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest description says the skill triggers on phrases like "subscribe to updates" and when working with "content monitoring," which are broad phrases that can arise in many contexts unrelated to RSS discovery. It also mixes a few specific examples with an open-ended activation condition, without clear exclusion boundaries or negative examples.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.