Back to skill

Security audit

cf-crawl

Security checks for vulnerabilities and agentic risk

Overview

This Cloudflare crawler is mostly purpose-aligned, but it unsafely executes its local credential file as shell code and handles a powerful API token in a way users should review before installing.

Install only if you are comfortable giving the skill a Cloudflare token with Browser Rendering read and edit access and sending crawl targets, page contents, prompts, schemas, and results to Cloudflare services. Store the token in a tightly protected file, do not generate that file from untrusted input, prefer a dedicated least-privilege token, and avoid crawling sensitive or regulated content unless Cloudflare's data handling is acceptable for that data.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/crawl.sh:23
Finding
Credential Environment File Is Executed as Arbitrary Shell Code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/crawl.sh:23-27`; `scripts/poll.sh:6-10` **Vulnerability Type**: Unsafe execution of a credential configuration file **Risk Level**: Medium ### Vulnerable Code In `scripts/crawl.sh:23-27`: ```bash # Load credentials if [[ -f ~/.clawdbot/secrets/cloudflare-crawl.env ]]; then source ~/.clawdbot/secrets/cloudflare-crawl.env fi : "${CF_ACCOUNT_ID:?Set CF_ACCOUNT_ID}" : "${CF_CRAWL_API_TOKEN:?Set CF_CRAWL_API_TOKEN}" ``` In `scripts/poll.sh:6-10`: ```bash if [[ -f ~/.clawdbot/secrets/cloudflare-crawl.env ]]; then source ~/.clawdbot/secrets/cloudflare-crawl.env fi : "${CF_ACCOUNT_ID:?Set CF_ACCOUNT_ID}" : "${CF_CRAWL_API_TOKEN:?Set CF_CRAWL_API_TOKEN}" ``` ### Technical Analysis The Bash `source` command does not treat the referenced file as a passive environment-variable file. It parses and executes its entire contents as shell code in the context of the current script. The scripts expect the file to contain only `CF_ACCOUNT_ID` and `CF_CRAWL_API_TOKEN` assignments, but they do not validate its ownership, permissions, syntax, or allowed variable names. Consequently, command substitutions, function definitions, redirections, and arbitrary shell commands placed in the file will execute whenever either script starts. For example, a compromised file could contain an assignment with command substitution: ```bash CF_ACCOUNT_ID="$(attacker_controlled_command)" CF_CRAWL_API_TOKEN="..." ``` Exploitation requires the attacker or another compromised component to obtain the ability to create or modify `~/.clawdbot/secrets/cloudflare-crawl.env`. The use of `source` then turns control over what should be data-only configuration into code execution. ### Attack Path 1. An attacker compromises a provisioning process, backup restoration process, account-level utility, or other component capable of writing the credential file. 2. The attacker adds arbitrary Bash commands or command substitutions to `~/.clawd ...[truncated 933 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not load the credential file with `source`, `.`, or `eval`. - Prefer passing credentials through an established secret manager or a controlled process environment. - If a file must be supported, implement a data-only parser that: - Accepts only `CF_ACCOUNT_ID` and `CF_CRAWL_API_TOKEN`. - Rejects duplicate keys, unknown keys, malformed lines, command substitutions, and shell metacharacters. - Does not evaluate the parsed values as shell syntax. - Verify that the file is owned by the current user and is not a symbolic link. - Require restrictive permissions, such as mode `0600`, before reading it. - Reject values containing unexpected control characters or newlines. - Document that the credential file must never be generated from untrusted input. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/crawl.sh:126
Finding
Cloudflare API Token Is Exposed in Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/crawl.sh:126-130`, `scripts/crawl.sh:151-153`, `scripts/crawl.sh:176-178`; `scripts/poll.sh:29-30` **Vulnerability Type**: Sensitive credential exposure through process arguments **Risk Level**: Low ### Vulnerable Code In `scripts/crawl.sh:126-130`: ```bash # Start crawl RESPONSE=$(curl -s -X POST "$BASE" \ -H "Authorization: Bearer $CF_CRAWL_API_TOKEN" \ -H "Content-Type: application/json" \ -d "$BODY") ``` In `scripts/crawl.sh:151-153`: ```bash RESULT=$(curl -s "$BASE/$JOB_ID" \ -H "Authorization: Bearer $CF_CRAWL_API_TOKEN") ``` In `scripts/crawl.sh:176-178`: ```bash PAGE=$(curl -s "$BASE/$JOB_ID$QUERY" \ -H "Authorization: Bearer $CF_CRAWL_API_TOKEN") ``` In `scripts/poll.sh:29-30`: ```bash RESULT=$(curl -s "$BASE/$JOB_ID$QUERY" \ -H "Authorization: Bearer $CF_CRAWL_API_TOKEN") ``` ### Technical Analysis The shell expands `CF_CRAWL_API_TOKEN` before starting `curl`. The complete authorization header can therefore become part of the `curl` process argument vector. Depending on the operating system's process-inspection policy, the expanded token may be observable through process-listing utilities, process-monitoring software, audit facilities, or `/proc` while the request is active. The polling and pagination loops repeatedly create processes containing the token, increasing the observation window. The network destination itself is the documented HTTPS endpoint at `api.cloudflare.com`, and transmitting a bearer token to that endpoint is necessary for the declared functionality. The weakness is specifically the local delivery mechanism used to provide the header to `curl`, not the use of Cloudflare's authenticated API. ### Attack Path 1. The victim invokes the crawler or polling script with a valid Cloudflare API token. 2. The shell expands the token into the `curl` authorization-header argument. 3. During execution, a local user, monitoring agent, or compromised p ...[truncated 1077 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Avoid placing the bearer token directly in the `curl` argument vector. - Pass the authorization header through a protected temporary curl configuration or header file: - Create it with restrictive permissions under a trusted directory. - Use secure temporary-file creation. - Remove it with a reliable cleanup trap. - Ensure neither the filename nor file contents can be influenced by untrusted input. - Where supported, use a credential helper, secret manager integration, or protected file descriptor that does not expose the token in process arguments. - Issue a dedicated Cloudflare token restricted to the minimum account and Browser Rendering permissions required. - Do not reuse a broad Cloudflare administrative token for this Skill. - Rotate the token if local process inspection or logging may have captured it. - Review process-accounting, audit, telemetry, and debugging systems to ensure authorization headers are not retained. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (12)

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill invokes shell scripts but does not declare any tool scope or allowed-tools boundary, so an agent may use shell capabilities without an explicit permission contract. In an agent environment, this increases the chance of overbroad command execution and makes it harder for reviewers or policy engines to constrain what the skill can do.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill encourages crawling and AI extraction through Cloudflare services but does not clearly warn that crawled page content, prompts, and extracted results may be transmitted to third-party infrastructure. Users may unknowingly send proprietary, regulated, or otherwise sensitive data off-platform, creating confidentiality and compliance risk.

Session Persistence

Medium
Category
Rogue Agent
Content
#   --json-schema F  Path to JSON schema file (requires --format json)
#   --poll-interval  Seconds between polls (default 5)
#   --timeout SEC    Max seconds to wait (default 300)
#   --output FILE    Write results to file (default stdout)
#   --raw            Output raw API response (no formatting)
#   --start-only     Start job, print ID, don't poll
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

External Transmission

Medium
Category
Data Exfiltration
Content
fi

# Start crawl
RESPONSE=$(curl -s -X POST "$BASE" \
  -H "Authorization: Bearer $CF_CRAWL_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$BODY")
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

Medium
Confidence
79% confidence
Finding
This shell script performs a file write when `--output` is provided, using `echo "$FINAL" > "$OUTPUT"`. Although it prints a message after writing, there is no pre-write warning, confirmation, or descriptive comment near the operation about overwriting user files, and the header only states that results are written to a file.

External Transmission

Medium
Category
Data Exfiltration
Content
: "${CF_ACCOUNT_ID:?Set CF_ACCOUNT_ID}"
: "${CF_CRAWL_API_TOKEN:?Set CF_CRAWL_API_TOKEN}"

BASE="https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/browser-rendering/crawl"
JOB_ID="${1:?Usage: poll.sh <job-id>}"
shift
RAW=false
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
: "${CF_ACCOUNT_ID:?Set CF_ACCOUNT_ID}"
: "${CF_CRAWL_API_TOKEN:?Set CF_CRAWL_API_TOKEN}"

BASE="https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/browser-rendering/crawl"
JOB_ID="${1:?Usage: poll.sh <job-id>}"
shift
RAW=false
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
: "${CF_ACCOUNT_ID:?Set CF_ACCOUNT_ID}"
: "${CF_CRAWL_API_TOKEN:?Set CF_CRAWL_API_TOKEN}"

BASE="https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/browser-rendering/crawl"
JOB_ID="${1:?Usage: poll.sh <job-id>}"
shift
RAW=false
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
: "${CF_ACCOUNT_ID:?Set CF_ACCOUNT_ID}"
: "${CF_CRAWL_API_TOKEN:?Set CF_CRAWL_API_TOKEN}"

BASE="https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/browser-rendering/crawl"
JOB_ID="${1:?Usage: poll.sh <job-id>}"
shift
RAW=false
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
: "${CF_ACCOUNT_ID:?Set CF_ACCOUNT_ID}"
: "${CF_CRAWL_API_TOKEN:?Set CF_CRAWL_API_TOKEN}"

BASE="https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/browser-rendering/crawl"
JOB_ID="${1:?Usage: poll.sh <job-id>}"
shift
RAW=false
Confidence
60% 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
88% confidence
Finding
The documentation instructs users to store a token with read and edit privileges but does not warn about the sensitivity of that credential or recommend least-privilege handling. This can lead to unsafe storage, accidental disclosure, or unnecessary blast radius if the token is exposed.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The script sends a request to an external Cloudflare API using a bearer token sourced from the environment, but it provides no user-facing notice beyond terse usage comments. There is no confirmation, logging, or explicit warning in the file that job identifiers and retrieved crawl data will be transmitted to and fetched from a remote service.

Static analysis

No suspicious patterns detected.