Back to skill

Security audit

apple-jobs-research

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Apple jobs lookup helper that sends user-directed requests to Crawlora and does not show hidden, persistent, destructive, or deceptive behavior.

Install only if you are comfortable using Crawlora as a third-party service for Apple jobs research. Keep CRAWLORA_API_KEY private, avoid sending sensitive text as query or body content, and prefer normal GET calls shown in the skill documentation.

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

Note
Location
scripts/crawlora.sh:42
Finding
Helper permits authenticated POST requests outside the documented endpoint contract<![CDATA[ ## Vulnerability Details **File Location**: `scripts/crawlora.sh`, lines 42–48 and 92–98 **Vulnerability Type**: Excessive HTTP method capability and insufficient request-contract enforcement **Risk Level**: Low ### Technical Analysis The Skill documentation defines both permitted Apple Jobs endpoints as GET-only operations: - `GET /apple-jobs/job` - `GET /apple-jobs/search` However, the helper accepts both GET and POST, allows callers to provide arbitrary request bodies, and sends POST requests using the user's Crawlora API key. Relevant code: ```sh while [ $# -gt 0 ]; do case "$1" in -X) method="$2"; shift 2 ;; -d) body="$2"; shift 2 ;; *) args+=("$1"); shift ;; esac done ``` ```sh case "$method" in GET|POST) ;; *) echo "only GET and POST are supported by the apple-jobs-research skill" >&2 exit 2 ;; esac ``` ```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 ``` This capability exceeds the minimum privileges required by the declared functionality. The hostname and paths remain fixed and allowlisted, which significantly limits exposure, but the HTTP method and body are not constrained to the documented API contract. The implementation also does not validate endpoint-specific parameter names or required parameters. Consequently, authenticated content can be transmitted to the two allowlisted routes even though the Skill only requires query-based GET requests. ### Attack Path 1. An attacker influences the arguments used to invoke `scripts/crawlora.sh`, such as through an untrusted prompt or an unsafe wrapper. 2. The attacker supplies `-X POST` and an arbitrary JSON body through `-d` or a positi ...[truncated 1415 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Restrict the helper to GET requests and remove the `-X` and `-d` interfaces. 2. Reject all methods other than GET rather than maintaining unnecessary POST support. 3. Validate parameters separately for each route: - `/apple-jobs/job`: permit only the required `id` parameter. - `/apple-jobs/search`: permit only `q`, `location`, and `page`; require `q`. 4. Reject duplicate, malformed, and unknown parameters. 5. Validate `page` as a positive integer and apply reasonable length limits to all string values. 6. Retain the existing fixed HTTPS base URL, route allowlist, API-key character validation, URL encoding, mode-600 temporary file, and cleanup trap. 7. Add automated negative tests confirming that POST, unknown methods, unknown parameters, missing required parameters, and non-allowlisted routes are rejected before any network request occurs. ]]>
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
93% confidence
Finding
The skill invokes shell-based helper commands (`scripts/crawlora.sh`) but does not declare any `permissions` or `allowed-tools` scope. That omission weakens least-privilege controls and can allow broader-than-necessary tool use when the skill is executed, increasing the blast radius if the skill is modified, misused, or combined with prompt injection elsewhere.

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
79% confidence
Finding
This markdown file documents use of an external API endpoint and requires the `x-api-key: $CRAWLORA_API_KEY` header, which implies use of a sensitive credential and network transmission. Under the markdown-specific warning criterion, the file does not include any caution about exposing the key, sending data to a third-party service, or handling credentials safely.

Static analysis

No suspicious patterns detected.