Back to skill

Security audit

samsclub-research

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent, but its helper can send broader authenticated requests to Crawlora than the documented read-only Sam's Club use requires.

Review before installing if you are sensitive about third-party API use or quota consumption. Use it only with a Crawlora key you are comfortable using for Sam's Club catalog lookups, avoid sending sensitive text in request bodies, and prefer a revised version that restricts the helper to exact documented GET endpoints.

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:37
Finding
Overbroad HTTP Method and Route Authorization Enables Authenticated Data Transmission<![CDATA[ ## Vulnerability Details **File Location**: `scripts/crawlora.sh`, lines 37–100 **Vulnerability Type**: Overbroad API authorization and unintended data transmission **Risk Level**: Medium ### Vulnerable Code The helper accepts both `GET` and `POST`, even though all five documented endpoints are GET-only: ```sh case "$method" in GET|POST) ;; *) echo "only GET and POST are supported by the samsclub-research skill" >&2 exit 2 ;; esac ``` Route validation uses broad wildcards rather than enforcing the exact five documented endpoint structures: ```sh case "$path" in /samsclub/category) ;; /samsclub/content/*) ;; /samsclub/departments) ;; /samsclub/product/*) ;; /samsclub/product/*/related) ;; *) echo "path is not in the samsclub-research skill catalog" >&2 exit 2 ;; esac ``` For any accepted non-GET request, arbitrary caller-provided content is transmitted to the fixed third-party API with the user's API key: ```sh 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 endpoint reference defines five Sam's Club operations, all of which use `GET`. No documented functionality requires `POST` requests or arbitrary JSON request bodies. Allowing `POST` therefore exceeds the minimum network privileges necessary for the declared catalog-research functionality. The route allowlist is also broader than the documented interface. Patterns such as `/samsclub/product/*` and `/samsclub/content/*` accept arbitrary suffixes, including undocumented nested paths, provided they avoid the separately prohibited characters. Consequently, the helper does not enforce the exact endpoint shapes or ...[truncated 2439 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Restrict the helper to `GET`, because every documented endpoint is read-only: ```sh [ "$method" = "GET" ] || { echo "only GET is supported by the samsclub-research skill" >&2 exit 2 } ``` 2. Remove request-body processing and reject `-d` entirely. 3. Replace broad wildcard authorization with exact route-shape validation. Validate identifiers before constructing paths, for example: - `/samsclub/departments` - `/samsclub/category` - `/samsclub/content/<numeric-id>` - `/samsclub/product/<documented-product-id>` - `/samsclub/product/<documented-product-id>/related` 4. Enforce endpoint-specific query parameters: - `/samsclub/departments`: no query parameters. - `/samsclub/category`: require `id`; permit only optional integer `page`. - Product and content routes: reject all query parameters unless explicitly documented. 5. Reject duplicate, unknown, or malformed parameters and enforce reasonable identifier and page-length limits. 6. Retain the existing fixed HTTPS API base, API-key character validation, private temporary file, cleanup trap, and rejection of curl `@file` query syntax, as these controls appropriately reduce credential-redirection and local-file disclosure risks. ]]>
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 (8)

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill invokes shell commands via `scripts/crawlora.sh` but does not declare any tool restrictions such as `allowed-tools` or permissions. That creates an unnecessary execution surface: an agent may permit broader shell usage than intended, increasing the chance of command misuse or expansion beyond the documented API-calling purpose.

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.

Static analysis

No suspicious patterns detected.