Back to skill

Security audit

r2-uploader

Security checks for vulnerabilities and agentic risk

Overview

This Cloudflare R2 upload skill is not malicious, but it needs review because its instructions can publish local or URL-fetched content with too little scoping and include unsafe shell examples.

Install only if you are comfortable with an agent using your Wrangler login to write to R2. Before any upload, confirm the exact local path, destination bucket/path, and whether the object will be public; avoid home-directory searches, broad globs, and URL imports from untrusted sources. Do not use the concurrent xargs example as written.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
references/advanced.md:40
Finding
Shell Command Injection Through Attacker-Controlled Filenames<![CDATA[ ## Vulnerability Details **File Location**: `references/advanced.md:40-41` **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```bash find . -name "*.jpg" -print0 | xargs -0 -P 4 -I FILE \ sh -c 'wrangler r2 object put "$R2_BUCKET/agent/$(date +%Y%m%d)/$(basename FILE)" --file FILE --remote' ``` ### Technical Analysis The command uses `xargs` to substitute each discovered filename directly into the command string evaluated by `sh -c`. Although null-delimited filenames are used between `find` and `xargs`, the filename is not safely passed as a positional argument to the shell. A filename containing shell metacharacters or single quotes can alter the command passed to `sh -c`. Because filenames are under the control of anyone able to create files in the upload directory, a crafted `.jpg` filename can break out of the intended command and inject arbitrary shell operations. The injected command executes with the same operating-system privileges and environment as the agent running this Skill. ### Attack Path 1. An attacker creates or causes the creation of a `.jpg` file with a filename containing shell syntax. 2. The user or agent invokes the documented concurrent-upload workflow in the directory containing that file. 3. `find` returns the crafted filename and `xargs` substitutes it directly into the `sh -c` script. 4. The shell interprets the substituted metacharacters as executable syntax. 5. The attacker's command executes with the privileges of the agent process. ### Impact Assessment Successful exploitation permits arbitrary command execution as the local account running the Skill. An attacker could read or modify accessible files, steal environment variables and Cloudflare credentials, upload sensitive data, tamper with R2 objects, or execute additional local and network operations. The scope is limited by the permissions of the executing account, but may include all resources available through that ac ...[truncated 36 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Pass the filename as a positional argument instead of interpolating it into shell source: ```bash find . -name '*.jpg' -print0 | xargs -0 -P 4 -n 1 sh -c ' file=$1 wrangler r2 object put \ "$R2_BUCKET/agent/$(date +%Y%m%d)/$(basename "$file")" \ --file "$file" \ --remote ' sh ``` Additionally: - Quote every filename expansion. - Avoid `sh -c` where a direct command invocation can perform the operation. - Treat filenames as untrusted data, even when they originate from the local filesystem. - Test the workflow with filenames containing spaces, quotes, newlines, semicolons, and command-substitution characters. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:48
Finding
Server-Side Request Forgery and Data Disclosure Through Unrestricted URL Uploads<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:48-52` **Vulnerability Type**: Server-side request forgery and unintended data upload **Risk Level**: High ### Vulnerable Code ```bash ## 从 URL 直接上传 ```bash curl -sL "<url>" | wrangler r2 object put "$R2_BUCKET/$R2_PATH" --file - --remote ``` ``` The operative command is: ```bash curl -sL "<url>" | wrangler r2 object put "$R2_BUCKET/$R2_PATH" --file - --remote ``` ### Technical Analysis The Skill permits a user-controlled URL to be retrieved using `curl` without validating the protocol, hostname, resolved IP address, port, or redirect destination. The `-L` option automatically follows redirects, allowing an initially benign-looking external URL to redirect to loopback, link-local, private-network, or cloud metadata addresses. The fetched response is streamed directly into Cloudflare R2. Consequently, content reachable from the agent's network environment can be copied into object storage without being inspected or restricted. If the resulting object is publicly accessible, this behavior can turn SSRF into direct disclosure of internal data. ### Attack Path 1. An attacker asks the agent to upload content from a URL controlled by the attacker. 2. The supplied URL either directly targets an internal address or redirects to one. 3. `curl -L` follows the redirect and retrieves a service available only from the agent's network environment. 4. The response body is streamed into the configured R2 bucket. 5. The generated object URL is returned or otherwise exposed. 6. The attacker retrieves the uploaded internal content from R2. Potential targets include loopback services, private network applications, link-local endpoints, and cloud instance metadata services, subject to the agent's network access. ### Impact Assessment Exploitation may disclose internal service responses, metadata, credentials, configuration data, or other content reachable from the agent. It can also be used to probe inter ...[truncated 205 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Permit only explicitly approved schemes, preferably `https`. - Resolve the hostname before connecting and reject loopback, unspecified, private, link-local, multicast, and reserved IP ranges for both IPv4 and IPv6. - Disable automatic redirects by default. If redirects are necessary, validate every redirect target before following it. - Use an allowlist of approved domains when the workflow permits it. - Reject URLs containing embedded credentials or unexpected ports. - Apply response-size and request-time limits. - Require explicit user confirmation before uploading remotely fetched content. - Avoid making uploaded content public by default. - Log the final validated destination without exposing credentials or sensitive response data. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/error-handling.md:61
Finding
Predictable Temporary File Permits Symlink Attacks<![CDATA[ ## Vulnerability Details **File Location**: `references/error-handling.md:61-65` **Vulnerability Type**: Insecure temporary-file creation **Risk Level**: Medium ### Vulnerable Code ```bash TMP_FILE="/tmp/r2-upload-$(date +%s)" cp "<source-path>" "$TMP_FILE" wrangler r2 object put "$R2_BUCKET/$R2_PATH" --file "$TMP_FILE" --remote rm "$TMP_FILE" ``` ### Technical Analysis The temporary pathname is derived solely from the current Unix timestamp and is therefore predictable. The file is placed in the shared `/tmp` directory without atomic exclusive creation or validation that the path is a regular file owned by the current user. A local attacker can predict the timestamp and pre-create the path as a symbolic link. The subsequent `cp` can follow that link and overwrite another file writable by the executing user. Depending on the target and timing, the upload command may also read and upload unintended content through the attacker-controlled path. The cleanup is not protected by a trap, so interruptions can leave temporary content behind. ### Attack Path 1. A local attacker predicts when the documented upload workflow will run. 2. The attacker creates `/tmp/r2-upload-<timestamp>` as a symbolic link to a chosen target. 3. The agent executes `cp "<source-path>" "$TMP_FILE"`. 4. `cp` follows or otherwise interacts with the attacker-controlled destination path. 5. A file writable by the agent may be overwritten, or unintended content may be selected for upload. 6. The final `rm` removes the temporary directory entry but does not reverse any overwrite or disclosure that already occurred. ### Impact Assessment The issue can result in overwriting files accessible to the agent account, uploading unintended local data to R2, and leaving sensitive temporary copies on disk after abnormal termination. It does not independently grant privileges beyond those of the executing user, but it allows another local user to abuse those privileges and file-access righ ...[truncated 7 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Create the temporary file atomically with `mktemp` and guarantee cleanup with a trap: ```bash TMP_FILE=$(mktemp --tmpdir r2-upload.XXXXXX) || exit 1 trap 'rm -f -- "$TMP_FILE"' EXIT HUP INT TERM cp -- "<source-path>" "$TMP_FILE" || exit 1 wrangler r2 object put \ "$R2_BUCKET/$R2_PATH" \ --file "$TMP_FILE" \ --remote ``` Additional hardening measures: - Set a restrictive `umask`, such as `umask 077`, before creating temporary files. - Check all command exit statuses. - Do not construct temporary paths from timestamps, process IDs, or other predictable values. - Prefer avoiding the temporary copy entirely when the original path can be passed safely using proper quoting. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:21
Finding
Overbroad Home-Directory Search Can Select and Upload Unintended Sensitive Files<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:21-27` **Vulnerability Type**: Excessive filesystem discovery and ambiguous file selection **Risk Level**: Medium ### Vulnerable Code ```bash # 用户提供文件名时,查找文件 find ~ -name "<filename>" -type f 2>/dev/null | head -5 # 验证文件存在 ls -la "<file-path>" ``` ### Technical Analysis The documented workflow recursively searches the user's entire home directory when only a filename is supplied. This scope may include credentials, private documents, application data, hidden directories, and unrelated project files. If multiple files share the requested name, the first five filesystem-order matches are returned without a requirement that the user verify the intended file before upload. Suppressing error output with `2>/dev/null` also hides access and traversal problems that could otherwise reveal unsafe assumptions. This does not bypass operating-system permissions, but it violates least-privilege principles by searching substantially more data than is necessary for the upload task. ### Attack Path 1. An attacker or mistaken user supplies an ambiguous filename rather than an exact path. 2. The agent recursively searches the entire home directory. 3. The search discovers an unrelated sensitive file with the same name. 4. The agent selects that match without obtaining confirmation of its full path. 5. The file is uploaded to R2 and may become available through the generated object URL. ### Impact Assessment The issue may expose private file locations and cause accidental upload of sensitive files accessible to the agent account. The affected scope includes the user's home directory and any traversable locations beneath it. If R2 objects are public or broadly shared, accidental selection can become external data disclosure. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Require an explicit file path whenever possible. - Restrict filename searches to the current working directory or a user-approved directory. - Do not search the entire home directory by default. - Display canonical paths for all matches and require the user to confirm the exact file before upload. - Refuse ambiguous selections when multiple files have the same name. - Consider excluding hidden directories and known sensitive locations. - Preserve relevant errors or report them safely instead of suppressing all diagnostic output. A safer limited search would be: ```bash SEARCH_ROOT="${PWD}" find "$SEARCH_ROOT" -maxdepth 3 -type f -name "<filename>" -print ``` The selected canonical path should still be shown to the user and explicitly confirmed before uploading. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger phrases include generic terms like '上传' and '存储', which can match ordinary file-handling requests not specifically meant for Cloudflare R2. This raises the risk of accidental activation, causing unintended remote upload of local files or disclosure of public URLs when the user only asked for local handling or another storage target.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill centers on uploading local files to remote R2 storage and returning a public URL, but it provides no user-facing warning about off-device transmission or public exposure. In an agent setting, this can lead to inadvertent exfiltration of sensitive local data or publication of files the user did not intend to expose.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The direct-from-URL flow fetches third-party content with curl and immediately writes it into the user's R2 bucket, without warning about relaying external content into their storage. This can result in storage abuse, ingestion of malicious or illegal content, or unexpected cost and compliance issues if a user supplies or is tricked into supplying an untrusted URL.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The skill is described as upload-focused, but it also documents bucket enumeration and object deletion commands. Expanding capability beyond the declared purpose increases the chance an agent could perform destructive or discovery actions a user did not intend, especially if invoked under a broad upload-related trigger context.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The examples perform bulk uploads of local files to a remote Cloudflare R2 bucket using broad file globs and directory iteration, but provide no warning that all matched files will be transmitted off-host. In an agent skill context focused on uploading, this increases the chance of accidental exfiltration of unintended files, especially if users or downstream agents run the snippets with an overbroad directory or bucket variable.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The concurrent upload example discovers files automatically with `find` and uploads them in parallel to a remote bucket, which can rapidly exfiltrate a large set of local files if run from the wrong directory or with a broader pattern than intended. The lack of any caution, dry-run step, or scope validation makes accidental bulk transfer more dangerous in this skill because the surrounding purpose is to automate remote file upload.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The title and all operational guidance are written in Chinese, with no indication that the user can choose another language or that the document is intentionally limited to a Chinese-speaking audience. Under the stated policy, forcing a specific language without opt-in is a natural-language policy issue.

Static analysis

No suspicious patterns detected.