Back to skill

Security audit

Cloudflare Browser Rendering

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it should be reviewed because it encourages passing website passwords and session cookies on the command line and sends them to Cloudflare without a clear warning.

Review before installing if you may use it on authenticated sites. Avoid passing real passwords, production session cookies, bearer tokens, or sensitive HTML through command-line arguments. Use least-privilege Cloudflare tokens, small scoped crawls, and temporary test accounts or short-lived sessions when authenticated rendering is unavoidable.

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/cf_markdown.py:42
Finding
Website Credentials and Session Cookies Exposed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Locations**: - `SKILL.md:61-62` - `scripts/cf_markdown.py:42-48` - `scripts/cf_markdown.py:95-96` **Vulnerability Type**: Plaintext sensitive data in process arguments **Risk Level**: Medium ### Vulnerable Code Documentation encourages users to provide credentials and session cookies directly on the command line: ```bash python3 scripts/cf_markdown.py --cookies-json '[{"name":"session","value":"abc","domain":"example.com"}]' python3 scripts/cf_markdown.py --authenticate-json '{"username":"u","password":"p"}' ``` The implementation parses these sensitive values directly from command-line arguments and includes them in the remote rendering request: ```python cookies = load_json_arg(args.cookies_json, "--cookies-json") if cookies is not None: body["cookies"] = cookies auth = load_json_arg(args.authenticate_json, "--authenticate-json") if auth is not None: body["authenticate"] = auth ``` The corresponding command-line options are declared as follows: ```python p.add_argument("--cookies-json", help="Raw JSON array for cookies") p.add_argument("--authenticate-json", help="Raw JSON object for authenticate") ``` ### Technical Analysis Command-line arguments are not an appropriate transport mechanism for secrets. Depending on the operating system and execution environment, arguments may be exposed through: - Shell history files - Process inspection utilities - Process-monitoring or endpoint-management software - CI/CD command logs - Debug output from wrappers and orchestration systems - Audit or telemetry systems that record process invocation details The affected arguments can contain usernames, passwords, and active session cookies. The script then sends those values to Cloudflare as part of the Browser Rendering request. Sending page authentication data to Cloudflare is functionally related to remote authenticated rendering and is not hidden behavior, but accepting the secrets directly through process argum ...[truncated 1779 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add file-based secret options such as `--cookies-file` and `--authenticate-file`, and read their contents only at runtime. 2. Support standard-input input modes so secrets do not appear in process arguments. 3. If environment-variable support is provided, use dedicated variables and document that CI systems must mask them. File descriptors or protected files are preferable where feasible. 4. Retain command-line JSON options only for non-sensitive testing, or deprecate them for authentication material. 5. Update `SKILL.md` to remove examples containing authentication data directly in command arguments. 6. Add an explicit warning that real passwords, tokens, and session cookies must not be supplied through command-line arguments. 7. Validate secret files before use and require restrictive permissions where supported, such as owner-only access. 8. Ensure request bodies and authentication fields are redacted from application logs, exception messages, debug output, and CI telemetry. 9. Recommend short-lived, narrowly scoped website sessions and revocation immediately after rendering when authenticated extraction is unavoidable. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The code clearly targets the Cloudflare /crawl endpoint and supports asynchronous crawl orchestration: creating jobs, checking results, waiting, cancelling, and exporting outputs. This aligns with the crawling portion of the description and with configurable crawl/render options such as gotoOptions, source, render, and inclusion flags. However, the declared purpose also claims the skill can convert a rendered page to Markdown with /markdown, which is not present in this code chunk at all. The markdown handling here only saves markdown returned from crawl records; it does not call the /markdown endpoint or perform single-page rendered extraction. Additionally, the code includes job-management capabilities beyond the description’s main emphasis, though those are related rather than unrelated. Because a prominent declared capability (/markdown extraction) is absent from the actual code, this is a description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The code aligns well with the portion of the description about converting a rendered page to Markdown and controlling render/load behavior through gotoOptions, cookies, auth, userAgent, and request filtering. However, the declared purpose also presents the skill as supporting asynchronous whole-site crawling with /crawl, including use cases like documentation-site crawling and multi-page extraction. No crawling functionality, /crawl endpoint usage, async job handling, or multi-page orchestration appears in this code chunk. Because an important declared capability is missing from the actual behavior shown, this is a description-to-behavior mismatch for the supplied chunk.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Main endpoints
- `POST /accounts/{account_id}/browser-rendering/crawl`
- `GET /accounts/{account_id}/browser-rendering/crawl/{job_id}`
- `DELETE /accounts/{account_id}/browser-rendering/crawl/{job_id}`

## Create-job behavior
- Returns a crawl `job_id`
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill declares environment, network, and file output capabilities but does not explicitly constrain or disclose tool scope through a permissions or allowed-tools section. That increases the chance of overbroad execution, unintended network access, or writing sensitive fetched/crawled data to disk without clear policy boundaries.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation explicitly instructs users to pass session cookies and username/password authentication JSON to a third-party Cloudflare rendering API, but it does not clearly warn that these secrets will be transmitted off-host to an external service. In this skill context, that omission is more dangerous because the tool is specifically designed to proxy web content retrieval through Cloudflare, making credential leakage or unintended sharing of authenticated session state a realistic risk.

External Transmission

Medium
Category
Data Exfiltration
Content
import urllib.parse
import urllib.request

API_BASE = "https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/markdown"


def fail(msg: str, code: int = 1):
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
import urllib.parse
import urllib.request

API_BASE = "https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/markdown"


def fail(msg: str, code: int = 1):
Confidence
60% 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.