Back to skill

Security audit

business-review-trust-research

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent, but its authenticated API helper can call broader Crawlora routes and methods than the documented endpoint catalog describes.

Review before installing if you rely on strict endpoint limits or have a sensitive Crawlora account. The skill should only be used with inputs you are comfortable sending to Crawlora, and the helper would be safer if it rejected POST for this catalog and enforced exact documented route shapes for dynamic path segments.

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:44
Finding
Overbroad Authenticated API Route and HTTP Method Authorization<![CDATA[ ## Vulnerability Details **File Location**: `scripts/crawlora.sh`, lines 44–100 **Vulnerability Type**: Overly permissive route allowlisting and HTTP method authorization **Risk Level**: Medium ### Vulnerable Code ```bash case "$method" in GET|POST) ;; *) echo "only GET and POST are supported by the business-review-trust-research skill" >&2 exit 2 ;; esac # Reject path syntax that could smuggle a route through a shell glob check. case "$path" in ""|*[?#%]*|*..*|*//* ) echo "invalid path for the business-review-trust-research skill" >&2 exit 2 ;; esac case "$path" in /bbb/business) ;; /bbb/business/complaints) ;; /bbb/business/more-info) ;; /bbb/business/reviews) ;; /bbb/category) ;; /bbb/scamtracker/*) ;; /bbb/scamtracker/search) ;; /bbb/scamtracker/state-stats) ;; /bbb/search) ;; /capterra/product) ;; /capterra/product/reviews) ;; /capterra/search) ;; /kickstarter/comments) ;; /kickstarter/discover) ;; /kickstarter/project) ;; /kickstarter/updates) ;; /producthunt/category/*) ;; /producthunt/category/*/products) ;; /producthunt/leaderboard) ;; /producthunt/product/*) ;; /producthunt/product/*/about) ;; /producthunt/product/*/alternatives) ;; /producthunt/product/*/customers) ;; /producthunt/product/*/launches) ;; /producthunt/product/*/makers) ;; /producthunt/product/*/reviews) ;; /producthunt/search) ;; /trustmrr/acquire) ;; /trustmrr/categories) ;; /trustmrr/category/*) ;; /trustmrr/leaderboard) ;; /trustmrr/marketplace) ;; /trustmrr/startup/*) ;; /trustmrr/startups) ;; /trustpilot/business-units/search) ;; /trustpilot/business/*) ;; /trustpilot/business/*/related) ;; /trustpilot/business/*/reviews) ;; /trustpilot/categories) ;; /trustpilot/categories/search) ;; /trustpilot/category/*) ;; *) echo "path is not in the business-review-trust-research skill catalog" >&2 exit 2 ;; esac ``` ### Technical Analysis The endpoint ...[truncated 3463 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Bind each route to its documented HTTP method.** Since the audited endpoint reference lists `GET` endpoints, reject `POST` unless a specific endpoint is explicitly documented to require it. 2. **Validate path structure rather than using unrestricted glob prefixes.** Require every dynamic identifier to be exactly one path segment and reject additional descendants. For example: ```bash case "$method:$path" in GET:/producthunt/search) ;; GET:/producthunt/leaderboard) ;; GET:/producthunt/product/*) ;; *) echo "unsupported method or path" >&2 exit 2 ;; esac ``` A plain `*` remains insufficient for single-segment enforcement. Before matching, split the path into segments or apply an anchored regular expression that excludes `/` from identifiers. 3. **Use anchored regular expressions for dynamic routes.** For example: ```bash if [[ "$method" == "GET" && "$path" =~ ^/producthunt/product/[A-Za-z0-9._-]+(/(about|alternatives|customers|launches|makers|reviews))?$ ]]; then : else echo "unsupported method or path" >&2 exit 2 fi ``` Define similarly constrained expressions for every dynamic route family. 4. **Reject empty and malformed dynamic segments.** Apply endpoint-specific character and length restrictions to Product Hunt IDs, Trustpilot slugs, TrustMRR slugs, category slugs, and BBB Scam Tracker IDs. 5. **Generate the client allowlist from the endpoint catalog.** This reduces drift between `reference/endpoints.md` and the executable authorization logic. 6. **Add negative security tests.** Verify that the helper rejects: - Undocumented descendant paths. - Extra path segments. - Unsupported methods, especially `POST`. - Encoded or malformed separators. - Empty identifiers. - Routes that are similar to, but not exactly part of, the documented catalog. 7. **Retain existing protections.** Preserve the fixed HTTP ...[truncated 131 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
Findings (10)

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill invokes shell commands via `scripts/crawlora.sh` but does not declare any tool scope, permissions, or allowed-tools boundaries. That omission weakens defense-in-depth because an agent may execute shell access more broadly than intended, increasing the chance of unintended command execution or misuse if user-controlled parameters are later interpolated unsafely by the helper script.

External Transmission

Medium
Category
Data Exfiltration
Content
Endpoints this skill uses, grouped by platform. Call them via `scripts/crawlora.sh` (see SKILL.md).

All paths are relative to the API base `https://api.crawlora.net/api/v1` and require the header `x-api-key: $CRAWLORA_API_KEY`. Path params like `{id}` are substituted into the URL; `GET` params go in the query string; `POST` params go in a JSON body.

**41 endpoints across 6 platform group(s).**
Confidence
92% confidence
Finding
The skill is explicitly designed to send data to an external service at api.crawlora.net using authenticated requests. External transmission is expected for this skill's function, but it remains security-relevant because user queries, URLs, company names, or campaign identifiers may leave the local trust boundary and be processed by a third party.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The file documents use of an authenticated third-party API and an API key header but provides no user-facing warning that user-supplied queries and identifiers may be transmitted off-platform. In an agent skill context, this can cause unannounced external data sharing and opaque credentialed network access, which undermines informed consent and safe deployment.

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.

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.

Vague Triggers

Low
Confidence
82% confidence
Finding
This markdown file describes what the skill uses and points readers to invoke it via another script, but it provides no explicit activation conditions, allowed trigger phrases, or exclusion cases. In markdown files, missing specificity around invocation scope can create ambiguity about when the skill should be used versus not used.

Static analysis

No suspicious patterns detected.