Back to skill

Security audit

wayfair-research

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but its helper includes under-documented POST request-body support that can send arbitrary caller-supplied text to Crawlora even though the documented Wayfair endpoints are GET-only.

Review before installing. Use this only for public Wayfair category and product lookups, and do not place secrets, private prompts, environment values, or personal data in query parameters or POST bodies. Prefer a version of the helper that rejects POST, rejects -d, and enforces the documented GET-only parameter schemas.

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/crawlora.sh:36
Finding
Undocumented POST Capability Allows Arbitrary Data Transmission<![CDATA[ ## Vulnerability Details **File Location**: `scripts/crawlora.sh`, lines 36–100 **Vulnerability Type**: Excessive network capability and unrestricted request-body transmission **Risk Level**: Medium ### Vulnerable Code ```bash method="GET" body="" args=() while [ $# -gt 0 ]; do case "$1" in -X) method="$2"; shift 2 ;; -d) body="$2"; shift 2 ;; *) args+=("$1"); shift ;; esac done ``` ```bash case "$method" in GET|POST) ;; *) echo "only GET and POST are supported by the wayfair-research skill" >&2 exit 2 ;; esac ``` ```bash if [ "$method" = "GET" ]; then # -G + --data-urlencode URL-encodes each value (so spaces etc. are safe). qs=() for kv in ${rest[@]+"${rest[@]}"}; do [ -n "$kv" ] || continue # curl treats both @file and name@file forms as local-file input for # --data-urlencode. Reject @ outright so query arguments cannot disclose # local files to the Crawlora API. case "$kv" in *@*) echo "@ is not allowed in query arguments" >&2; exit 2 ;; esac qs+=(--data-urlencode "$kv") done curl -fsS -G "${auth[@]}" ${qs[@]+"${qs[@]}"} "${base}${path}" else [ -n "$body" ] || body="${rest[0]:-}" [ -n "$body" ] || body='{}' # Stream the body on stdin so curl never interprets a user value as its # @file shorthand (and cannot read local files supplied in a request body). printf '%s' "$body" | curl -fsS -X "$method" "${auth[@]}" \ -H "Content-Type: application/json" --data-binary @- "${base}${path}" fi ``` ### Technical Analysis The Skill declares only three Wayfair endpoints, and `reference/endpoints.md` documents all three as GET-only: - `GET /wayfair/categories` - `GET /wayfair/category` - `GET /wayfair/product/{id}` Despite this, the helper accepts `-X POST`, accepts arbitrary caller-controlled content through `-d` or a positional argument, and transmits that content to `https://api.crawlora.net/api/v1`. POST support is therefore unnecessary for the declared Wayfair ...[truncated 2618 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove POST and request-body support because every documented endpoint is GET-only: ```bash method="GET" args=("$@") ``` Reject `-X`, `-d`, and any other option-like arguments. 2. Enforce GET explicitly: ```bash case "${1:-}" in -*) echo "options and alternate HTTP methods are not supported" >&2; exit 2 ;; esac ``` 3. Validate parameters separately for each endpoint: - `/wayfair/categories`: allow only `page`, `page_size`, and `q`. - `/wayfair/category`: allow only `category` and `page`. - `/wayfair/product/{id}`: reject query parameters. 4. Validate product paths strictly, such as requiring a `W`-prefixed identifier with an expected character format rather than allowing every value matched by `/wayfair/product/*`. 5. Reject duplicate, malformed, or unexpected query parameters and apply reasonable length limits to parameter names and values. 6. Add regression tests confirming that: - POST is rejected for every route. - `-d` and arbitrary curl-style options are rejected. - Only documented query parameters are accepted. - The API base cannot be overridden. - The API key remains absent from process arguments and logs. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (9)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill invokes shell-based helper commands but does not declare any explicit tool scope or allowed-tools restrictions. That creates unnecessary execution latitude: in an agent environment, the skill could be run with broader shell capabilities than required, increasing the blast radius if the skill is modified, misused, or combined with adversarial input.

External Transmission

Medium
Category
Data Exfiltration
Content
#!/usr/bin/env bash
# Crawlora REST helper — minimal, dependency-free (curl only).
# Calls https://api.crawlora.net/api/v1 with your Crawlora API key.
# Get a free key (2,000 credits/mo, no card) at https://crawlora.net?utm_source=github&utm_medium=referral&utm_campaign=crawlora-skills.
#
Confidence
70% 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
#!/usr/bin/env bash
# Crawlora REST helper — minimal, dependency-free (curl only).
# Calls https://api.crawlora.net/api/v1 with your Crawlora API key.
# Get a free key (2,000 credits/mo, no card) at https://crawlora.net?utm_source=github&utm_medium=referral&utm_campaign=crawlora-skills.
#
# Usage:
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
#!/usr/bin/env bash
# Crawlora REST helper — minimal, dependency-free (curl only).
# Calls https://api.crawlora.net/api/v1 with your Crawlora API key.
# Get a free key (2,000 credits/mo, no card) at https://crawlora.net?utm_source=github&utm_medium=referral&utm_campaign=crawlora-skills.
#
# Usage:
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
#!/usr/bin/env bash
# Crawlora REST helper — minimal, dependency-free (curl only).
# Calls https://api.crawlora.net/api/v1 with your Crawlora API key.
# Get a free key (2,000 credits/mo, no card) at https://crawlora.net?utm_source=github&utm_medium=referral&utm_campaign=crawlora-skills.
#
# Usage:
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
#!/usr/bin/env bash
# Crawlora REST helper — minimal, dependency-free (curl only).
# Calls https://api.crawlora.net/api/v1 with your Crawlora API key.
# Get a free key (2,000 credits/mo, no card) at https://crawlora.net?utm_source=github&utm_medium=referral&utm_campaign=crawlora-skills.
#
# Usage:
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# Keep the API key out of the curl process command line. A private temporary
# config supplies the header and is removed automatically on exit.
curl_config="$(mktemp "${TMPDIR:-/tmp}/crawlora-curl.XXXXXX")"
chmod 600 "$curl_config"
trap 'rm -f "$curl_config"' EXIT
printf 'header = "x-api-key: %s"\n' "$CRAWLORA_API_KEY" >"$curl_config"
auth=(--config "$curl_config")
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

External Transmission

Medium
Category
Data Exfiltration
Content
[ -n "$body" ] || body='{}'
  # Stream the body on stdin so curl never interprets a user value as its
  # @file shorthand (and cannot read local files supplied in a request body).
  printf '%s' "$body" | curl -fsS -X "$method" "${auth[@]}" \
    -H "Content-Type: application/json" --data-binary @- "${base}${path}"
fi
Confidence
70% 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

Low
Confidence
83% confidence
Finding
The script sends query parameters or JSON request bodies to the external Crawlora API via curl, which can transmit user-supplied data off the local system. While comments describe the API and usage, there is no explicit user-facing warning in runtime output or usage text that request contents are sent to a remote service.

Static analysis

No suspicious patterns detected.