Back to skill

Security audit

NAS File Courier Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent NAS file courier, but its broad file access and insecure transfer examples could expose or mishandle private files.

Review before installing. Use it only with NAS shares and messaging channels you trust, require explicit user confirmation for each file, avoid the HTTP fallback for sensitive files, and prefer per-request private temp directories plus validated rclone arguments before operational use.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:61
Finding
Shell and Python Injection Through Unsafe Input Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:61`, `SKILL.md:78`, `SKILL.md:205-207`, `references/rclone-ops.md:18-24`, `references/rclone-ops.md:30`, `references/http-temp-link.md:25-26` **Vulnerability Type**: Command injection through unsafe shell and Python interpolation **Risk Level**: High ### Vulnerable Code `SKILL.md:61`: ```bash rclone lsf nas:<SHARE> --recursive --include "*关键词*" ``` `SKILL.md:78`: ```bash rclone lsl nas:<SHARE>/path/to/file.pdf ``` `SKILL.md:205-207`: ```text 🔍 搜索: rclone lsf nas:<SHARE> --recursive --include "*keyword*" 📏 大小: rclone size nas:<SHARE>/path --json 📥 下载: rclone copy nas:<SHARE>/path /tmp/openclaw/nas-courier/ ``` `references/rclone-ops.md:18-24`: ```bash rclone lsf nas:<SHARE> --recursive --include "*关键词*" # 按扩展名 + 关键词 rclone lsf nas:<SHARE> --recursive --include "*关键词*.pdf" # 按修改时间过滤(最近 N 天) rclone lsf nas:<SHARE> --recursive --include "*关键词*" --max-age 30d ``` `references/rclone-ops.md:30`: ```bash rclone lsl nas:<SHARE>/path/to/file.pdf ``` `references/http-temp-link.md:25-26`: ```bash FILENAME="file.pdf" # 替换为实际文件名 ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${FILENAME}'))") ``` ### Technical Analysis The documented commands interpolate user-controlled search terms, share names, paths, and potentially NAS-controlled filenames into shell commands. Several rclone examples do not establish safe argument boundaries around the remote specification. Even where double quotes are shown, double quotes do not neutralize shell command substitution constructs such as `$(...)` or backticks when generated command text is subsequently interpreted by a shell. The HTTP-link procedure introduces an additional injection boundary by embedding `FILENAME` directly into Python source code. A filename containing a single quote can terminate the `urllib.parse.quote()` string literal and append attacker-controlled Python syntax. Because the Python interpreter is launched by the ...[truncated 1320 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Invoke rclone through an execution API that accepts an argument array and does not invoke a shell. - Treat search terms, share names, remote paths, and filenames as untrusted data. - Validate share names against an explicit allowlist of configured NAS shares. - Reject control characters, path traversal, unexpected remote syntax, and embedded shell metacharacters where they are not required. - Preserve user values as individual arguments rather than concatenating them into command strings. - Pass the filename to Python through `argv` rather than embedding it in Python source: ```bash ENCODED=$(python3 -c \ 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1]))' \ "$FILENAME") ``` - If shell execution cannot be avoided, use positional parameters with a fixed script body and never evaluate dynamically generated command text. - Add tests using filenames and search terms containing spaces, quotes, backticks, `$()`, semicolons, newlines, and leading hyphens. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
references/http-temp-link.md:19
Finding
Temporary HTTP Server Exposes the Entire Shared Delivery Directory<![CDATA[ ## Vulnerability Details **File Location**: `references/http-temp-link.md:19-22` **Vulnerability Type**: Inadequate recipient isolation and overbroad file exposure **Risk Level**: High ### Vulnerable Code ```bash rclone serve http /tmp/openclaw/nas-courier/ \ --addr "${TAILSCALE_IP}:${PORT}" \ --read-only & SERVE_PID=$! ``` ### Technical Analysis The fallback procedure serves the entire global `/tmp/openclaw/nas-courier/` directory rather than a per-request directory containing only the confirmed file. The server is read-only and bound to a Tailscale address, but those controls do not provide recipient-level authorization. Any stale files, files left after failed cleanup, or files belonging to concurrent delivery requests fall within the published server root. Other peers able to reach the service through the Tailscale network may retrieve unrelated content through known or guessed paths and potentially through directory enumeration. Network membership therefore becomes the only access-control boundary for all files in the shared directory. ### Attack Path 1. A previous failed delivery, hidden file, or concurrent request leaves another sensitive file in `/tmp/openclaw/nas-courier/`. 2. A user requests a file through a channel that requires the HTTP fallback. 3. The Agent starts `rclone serve http` with the entire shared directory as its root. 4. Another Tailscale peer connects to the fixed address and port while the server is active. 5. The peer enumerates, guesses, or otherwise requests the path of an unrelated file. 6. The server returns that file because it is located beneath the published root. ### Impact Assessment The issue can disclose any file present in the shared courier directory to unintended Tailscale peers. This may include confidential NAS documents from other users or delivery sessions. It does not directly grant write access because `--read-only` is enabled, but it breaks least-privilege and recipient-isolation boundaries ...[truncated 51 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Create a unique private directory for every request: ```bash REQUEST_DIR=$(mktemp -d /tmp/openclaw/nas-courier.XXXXXXXX) chmod 700 "$REQUEST_DIR" ``` - Copy only the user-confirmed file into that request directory and serve only that directory. - Use a high-entropy, unguessable URL component or authentication token for each delivery. - Disable directory listing where supported. - Avoid a fixed port when possible, or verify that an existing process is not already bound to the selected port. - Restrict network access to the intended recipient where the surrounding Tailscale policy supports identity-based ACLs. - Stop the server and delete the request directory through a guaranteed `trap` or equivalent `finally` handler on success, failure, interruption, and timeout. - Do not reuse a serving directory across users or simultaneous delivery operations. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:160
Finding
Wildcard Cleanup Leaves Hidden Files and Deletes Concurrent Deliveries<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:160-163`, `SKILL.md:211` **Vulnerability Type**: Unsafe temporary-file lifecycle and shared-directory cleanup **Risk Level**: Medium ### Vulnerable Code `SKILL.md:160-163`: ```bash kill $SERVE_PID 2>/dev/null # 如果使用了 Step 4b rm -f /tmp/openclaw/nas-courier/* ls /tmp/openclaw/nas-courier/ # 验证为空 ``` `SKILL.md:211`: ```text 🧹 清理: rm -f /tmp/openclaw/nas-courier/* ``` ### Technical Analysis The cleanup command uses the shell glob `*`, which does not normally match filenames beginning with a dot. A hidden NAS file downloaded into the courier directory can therefore survive the mandatory cleanup procedure. The subsequent `ls` command also omits hidden entries by default, so it may incorrectly appear to verify that the directory is empty. The same fixed directory is shared by all deliveries. Cleanup for one request indiscriminately removes all non-hidden entries, including files staged by another request. This creates a cross-request race condition and prevents reliable ownership of temporary resources. Residual hidden files can later be exposed when the directory is served through the HTTP fallback. Concurrent deletion can also cause failed or incorrect deliveries. ### Attack Path 1. A hidden file is downloaded from the NAS, or two delivery jobs use the shared directory at the same time. 2. One job executes `rm -f /tmp/openclaw/nas-courier/*`. 3. A hidden file is not matched and remains on disk, while non-hidden files belonging to another active job may be deleted. 4. The default `ls` verification fails to reveal the residual hidden file. 5. A later HTTP fallback can publish the residual file, or the concurrent job fails because its staged file has been removed. ### Impact Assessment A hidden sensitive file can persist beyond the intended retention period and may be disclosed during a later HTTP-serving session. Concurrent operations can delete each other's files, causing denial of servic ...[truncated 180 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace the global working directory with a unique per-request directory created through `mktemp -d`. - Set restrictive permissions such as mode `0700` before staging any sensitive file. - Track the exact directory created for the request and remove only that directory: ```bash REQUEST_DIR=$(mktemp -d /tmp/openclaw/nas-courier.XXXXXXXX) chmod 700 "$REQUEST_DIR" cleanup() { if [ -n "${SERVE_PID:-}" ]; then kill "$SERVE_PID" 2>/dev/null || true fi case "$REQUEST_DIR" in /tmp/openclaw/nas-courier.*) rm -rf -- "$REQUEST_DIR" ;; esac } trap cleanup EXIT INT TERM ``` - Validate the temporary-directory prefix before recursive deletion. - Do not use a shared wildcard cleanup command for resources owned by multiple requests. - If emptiness must be verified, use a method that includes hidden entries, such as `find "$REQUEST_DIR" -mindepth 1 -print`, before removing the directory. - Ensure cleanup executes on success, failure, timeout, cancellation, and signal-driven termination. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (14)

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Content
---
name: nas-file-courier
description: Search files on NAS (via rclone + Tailscale) and send to user via messaging API. Triggers on file search, find file, send file, 找文件, 发文件, NAS 查找, 下载文件.
---

# NAS File Courier Skill

> **Purpose**: 通过 rclone 在 NAS 上查找文件,并通过 IM 消息渠道发送给用户。

---

## 🎭 [ROLE] Your Identity

You are a **File Courier Agent** operating with minimal privileges (no sudo).

**Primary Mission**: Safely locate files on NAS and deliver them to the user via messaging channel, with strict temp file hygiene.

---

## 🔧 [PREREQUISITES] Envir
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Chaining Abuse

High
Category
Tool Misuse
Content
|-------------------|-----------------------------------------|--------------------------------------------|
| Tailscale VPN     | `tailscale status`                      | Must be connected to the secure mesh network |
| rclone            | `which rclone`                          | Including fuse3 dependency                  |
| sudo access       | (for initial setup only)                | Install rclone, fuse3, configure remotes    |
| Full Linux/macOS  | `uname -s`                              | Docker environments untested                |

---
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
kill $SERVE_PID 2>/dev/null  # 如果使用了 Step 4b
rm -f /tmp/openclaw/nas-courier/*
ls /tmp/openclaw/nas-courier/  # 验证为空
```
Confidence
85% confidence
Finding
The cleanup command uses a wildcard deletion in a shared temp path without additional safety checks. If the directory path is incorrect, replaced by a symlink, or contains unexpected files from other processes, the command can delete unintended data and may be abused through filesystem manipulation.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
📤 投递: 回复中包含 MEDIA: /tmp/openclaw/nas-courier/<文件名>
📤 备用: rclone serve http ... (见 references/http-temp-link.md)
✅ 验证: 必须询问用户是否收到
🧹 清理: rm -f /tmp/openclaw/nas-courier/*
```
Confidence
85% confidence
Finding
The quick reference repeats the unsafe wildcard cleanup pattern, which normalizes potentially dangerous shell usage and increases the likelihood it will be copied into implementations. In a file-handling skill, destructive cleanup commands are especially sensitive because they run after every transfer attempt.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger list is broad and includes generic phrases like 'find file', 'send file', and '下载文件', which can cause the skill to activate in situations the user did not intend. In a skill that can search a NAS and transmit files externally, accidental activation increases the chance of unintended data disclosure.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
|-------------------|-----------------------------------------|--------------------------------------------|
| Tailscale VPN     | `tailscale status`                      | Must be connected to the secure mesh network |
| rclone            | `which rclone`                          | Including fuse3 dependency                  |
| sudo access       | (for initial setup only)                | Install rclone, fuse3, configure remotes    |
| Full Linux/macOS  | `uname -s`                              | Docker environments untested                |

---
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
|-------------------|-----------------------------------------|--------------------------------------------|
| Tailscale VPN     | `tailscale status`                      | Must be connected to the secure mesh network |
| rclone            | `which rclone`                          | Including fuse3 dependency                  |
| sudo access       | (for initial setup only)                | Install rclone, fuse3, configure remotes    |
| Full Linux/macOS  | `uname -s`                              | Docker environments untested                |

---
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
```
允许: .pdf .docx .xlsx .pptx .txt .md .csv .jpg .png .gif .webp .svg .zip .tar.gz .7z .mp3 .mp4 .mkv
禁止: .exe .sh .bat .cmd .msi .app .dll .so .sys .plist .db .sqlite .sql
```

---
Confidence
75% 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.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The document explicitly describes reading a local file stream and uploading it to Feishu, but it provides no warning, consent requirement, or restriction guidance around exfiltrating local data to an external messaging platform. In the context of a NAS file courier skill, this omission is security-relevant because users may trigger transfer of sensitive internal files without clear notice that data leaves the local environment.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The Telegram section states that local files are loaded and sent directly into chat, yet it omits any notice that this action transmits potentially sensitive NAS or local content to a third-party service. Because the skill’s purpose is to search and send files, lack of disclosure and guardrails materially increases the chance of unintended data exposure.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This section explains that the system reads local media into memory and uploads it to QQ endpoints, but it does not mention the privacy implications of transmitting local/NAS data externally. In a file-delivery skill, that missing warning is dangerous because it normalizes outbound transfer without highlighting that confidential files may be disclosed to third-party messaging services.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The document instructs operators to expose a directory over plain HTTP and share a direct download link, but it does not warn that anyone with Tailscale network access who learns the URL can fetch the file during the exposure window. Although access is limited to the Tailscale IP and the service is read-only, the lack of authentication, TLS, and confidentiality guidance makes accidental overexposure of sensitive NAS files a real risk in this skill’s file-transfer context.

Natural-Language Policy Violations

Low
Confidence
80% confidence
Finding
The skill content, headings, and operational guidance are all presented in Chinese, which can impose a language constraint on users without explicit opt-in. The file does not indicate that the skill is region-specific or provide an alternative language option.

Missing User Warnings

Low
Confidence
90% confidence
Finding
This markdown file includes an rclone copy command that downloads a NAS file into /tmp/nas-courier/, which affects local storage and creates a local copy of user data. The surrounding description does not warn about the file write, temporary-data persistence, or the need to verify the destination before running the command.

Static analysis

Detected: suspicious.generated_source_template_injection

User-controlled placeholder is embedded directly into generated source code.

Critical
Code
suspicious.generated_source_template_injection
Location
references/http-temp-link.md:26