Back to skill

Security audit

File Upload to Local Workspace

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent file-upload purpose, but it installs a persistent network service with weak authentication behavior and under-disclosed access to installed skills.

Review carefully before installing. This skill starts a persistent network-accessible upload service, may expose it without authentication in common configurations, reuses gateway credentials in URLs, and includes an under-disclosed endpoint that can export installed skills. Only use it after fixing auth to fail closed, binding to localhost by default, removing skill-export endpoints, adding size limits, and making service installation/removal explicit and reliable.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (6)

T09 · Insecure Skill Coding Practices

Error
Location
src/upload-server.js:26
Finding

Fail-Open Authentication Exposes All Management APIs

Content
View full analysis
{ ``` ### Technical Analysis Authentication is enforced only when `GATEWAY_TOKEN` is non-empty. If the configuration file is missing, unreadable, malformed, or contains only password authentication, `loadGatewayToken()` returns an empty string. The condition then evaluates to false for every request, disabling authentication. The installer calculates `GATEWAY_AUTH_VALUE`, including password-based authentication, but the server never reads that environment variable. Consequently, the documented password compatibility is not implemented. This is a fail-open design. Configuration or parsing failures must not silently convert an authenticated network service into an anonymous service, particularly when the process listens on `0.0.0.0`. ### Attack Path 1. The service starts on a system with a missing, unreadable, malformed, or password-only OpenClaw configura ...[truncated 894 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/upload-server.js:289
Finding

Undeclared Remote Export of Installed Workspace Skills

Content
View full analysis
!f.startsWith('.')) .map(skillName => { const skillPath = path.join(SKILLS_DIR, skillName); const stats = fs.statSync(skillPath); const hasClawhub = fs.existsSync(path.join(skillPath, 'clawhub.json')); const hasSkillMd = fs.existsSync(path.join(skillPath, 'SKILL.md')); return { name: skillName, modified: stats.mtime.toISOString(), hasClawhub, hasSkillMd, path: skillPath }; }) .sort((a, b) => a.name.localeCompare(b.name)); return skills; } catch (e) { console.error('获取技能列表失败:', e); return []; } } ``` ```javascript function zipSkill(skillName, res) { const skillPath = path.join(SKILLS_DIR, skillName); const zipPath = path.join(UPLOADS_DIR, `${skillName}-skill.zip`); if (!fs.existsSync(skillPath)) { res.writeHead(404, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Skill not found' })); return; } const zip = spawn('zip', ['-r', zipPath, skillName], { cwd: SKILLS_DIR, stdio: ['ignore', 'pipe', 'pipe'] }); zip.on('close', (code) => { if (code !== 0) { res.writeHead(500, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: `zip command failed: ${stderr}` })); return; } res.setHea ...[truncated 2796 chars]
Remediation
View remediation

T06 · System Persistence

Error
Location
install.sh:68
Finding

Installer Creates a System-Wide Persistent Service with Potential Root Privileges

Content
View full analysis
/etc/systemd/system/openclaw-upload.service << EOF [Unit] Description=OpenClaw File Upload Service After=network.target [Service] Type=simple User=${USER} WorkingDirectory=${WORKSPACE} Environment=UPLOAD_PORT=15170 Environment=WORKSPACE=${WORKSPACE} Environment=GATEWAY_AUTH_VALUE=${AUTH_VALUE} ExecStart=/usr/bin/node ${WORKSPACE}/upload-server.js Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable openclaw-upload.service systemctl start openclaw-upload.service echo "✅ systemd 服务已创建并启动" fi ``` The fallback also creates a persistent background process for the active session: ```bash nohup env UPLOAD_PORT=15170 WORKSPACE="${WORKSPACE}" GATEWAY_AUTH_VALUE="${AUTH_VALUE}" \ node upload-server.js > upload-server.log 2>&1 & ``` ### Technical Analysis Installation automatically writes to `/etc/systemd/system`, enables the service at boot, starts it immediately, and configures unlimited automatic restarts. This is a system-wide persistence action beyond the package manifest's declared execution, listening, and workspace-write permissions. The service account is selected using `${USER}`. If installation is performed as root, this commonly results in `User=root`, causing a network-facing Node.js process to execute with root privileges. No systemd hardening directives constrain filesystem access, privilege acquisition, namespaces, capabilities, or writable paths. Automatic startup is related to the advertised service functionality, but a system-level service is not the minimum privilege necessary. A user-level service would provide the same convenience with substantially lower risk. ### Attack Pat ...[truncated 873 chars]
Remediation
View remediation
` - an empty capability set - Bind to loopback by default and require explicit configuration for remote access. - Avoid embedding authentication credentials in the service unit. - Declare service-management permissions accurately in package metadata. ]]>

T06 · System Persistence

Error
Location
uninstall.sh:4
Finding

Uninstaller Terminates Before Removing the Persistent Service

Content
View full analysis
/dev/null; then echo "⏹️ 停止 systemd 服务..." systemctl stop openclaw-upload.service systemctl disable openclaw-upload.service rm -f /etc/systemd/system/openclaw-upload.service systemctl daemon-reload fi ``` ### Technical Analysis The second banner line is not prefixed with `echo` and is not a valid shell command. The shell attempts to execute a command beginning with the box-drawing character. Because `set -e` is enabled, the script exits immediately when that command fails. As a result, execution never reaches the logic that stops, disables, and deletes the systemd service. It also fails before deleting the copied server code and log files. ### Attack Path 1. The skill has installed and enabled `openclaw-upload.service`. 2. A user runs `uninstall.sh`. 3. The shell reaches the malformed line near the beginning of the script. 4. Command execution fails. 5. `set -e` terminates the script. 6. The service remains running and enabled across reboots. ### Impact Assessment The network-facing service and its persistence survive an attempted uninstall. The copied executable, web interface, service definition, and logs may remain on the host. Users may incorrectly believe that the exposed service has been removed. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/upload.html:281
Finding

Gateway Credentials Are Reused and Transmitted in Plaintext URL Query Parameters

Content
View full analysis
:15170/?token= ``` The installer also places the authentication value into the systemd service definition: ```bash Environment=GATEWAY_AUTH_VALUE=${AUTH_VALUE} ``` ### Technical Analysis The implementation reuses the primary Gateway token—or, according to the installer and documentation, the Gateway password—as an upload-service bearer credential. It places that secret in the browser's address bar and repeats it in API query strings over plain HTTP. URL credentials can be retained in browser history, copied links, screenshots, access logs, reverse-proxy logs, monitoring systems, and diagnostic records. Plain HTTP also permits interception and modification by an attacker with network visibility. The frontend sends uploaded files only to same-origin endpoints; no third-party exfiltration destination was found. The vulnerability is the insecure transport and handling of sensitive authentication information. ### Attack Path 1. A ...[truncated 881 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/upload-server.js:351
Finding

Unbounded In-Memory Upload Buffering Enables Remote Denial of Service

Content
View full analysis
chunks.push(chunk)); req.on('end', () => { try { const buffer = Buffer.concat(chunks); const parsed = parseMultipart(buffer, boundary); if (!parsed.file) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'No file provided' })); return; } const file = parsed.file; const safeFilename = sanitizeFilename(file.filename); const filePath = path.join(UPLOADS_DIR, safeFilename); fs.writeFileSync(filePath, file.data); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: true, filename: safeFilename, path: filePath, size: file.data.length, sizeFormatted: formatSize(file.data.length) })); } catch (error) { console.error('上传错误:', error); res.writeHead(500, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: error.message })); } }); ``` The metadata advertises a limit that is not enforced: ```json "maxFileSize": "50MB" ``` ### Technical Analysis Every incoming chunk is retained in an array until the client finishes sending the request. `Buffer.concat()` then allocates another contiguous buffer, and multipart parsing creates further representations of the data. The file is finally written using the synchronous `fs.writeFileSync()` operation. There is no validation of `Content-Length`, no streaming byte counter, no connection timeout, no disk quota, and no rate limit. The advertised 50 MB maximum is configuration metadata only. Because authentication can fail open, this resource-e ...[truncated 1032 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (38)

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

Scanner excerpt · SECURITY-AUDIT.md (reported line 13)May include surrounding context.

md
| Web 文件列表 | ✅ | `upload-server.js:48` | `getFileList()` 函数 |
| 自动刷新 | ✅ | `upload.html:520` | 上传成功后调用 `loadFileList()` |
| 手动刷新 | ✅ | `upload.html:526` | 刷新按钮事件监听 |
| 文件删除 | ✅ | `upload-server.js:276` | `DELETE /api/files/<filename>` |
| 文件图标 | ✅ | `upload.html:368` | `getFileIcon()` 函数 |
| 文件大小格式化 | ✅ | `upload-server.js:67` | `formatSize()` 函数 |
| 相对时间显示 | ✅ | `upload.html:397` | `formatDate()` 函数 |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 284)May include surrounding context.

md
node src/upload-server.js

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% 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).

Content

Scanner excerpt · uninstall.sh (reported line 17)May include surrounding context.

sh
echo "⏹️  停止 systemd 服务..."
    systemctl stop openclaw-upload.service
    systemctl disable openclaw-upload.service
    rm -f /etc/systemd/system/openclaw-upload.service
    systemctl daemon-reload
    echo "✅ systemd 服务已卸载"
else

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% 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).

Content

Scanner excerpt · uninstall.sh (reported line 28)May include surrounding context.

sh
# 删除文件
echo "🗑️  删除文件..."
rm -f "${WORKSPACE}/upload-server.js"
rm -f "${WORKSPACE}/upload.html"
rm -f "${WORKSPACE}/upload-server.log"

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% 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).

Content

Scanner excerpt · uninstall.sh (reported line 29)May include surrounding context.

sh
# 删除文件
echo "🗑️  删除文件..."
rm -f "${WORKSPACE}/upload-server.js"
rm -f "${WORKSPACE}/upload.html"
rm -f "${WORKSPACE}/upload-server.log"

echo ""

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% 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).

Content

Scanner excerpt · uninstall.sh (reported line 30)May include surrounding context.

sh
echo "🗑️  删除文件..."
rm -f "${WORKSPACE}/upload-server.js"
rm -f "${WORKSPACE}/upload.html"
rm -f "${WORKSPACE}/upload-server.log"

echo ""
echo "╔═══════════════════════════════════════════════════════╗"

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document explicitly recommends accessing the page with the gateway token in the URL query string. Query-string tokens commonly leak via browser history, bookmarks, screenshots, proxy/server access logs, and Referer headers, which contradicts the report's claim that token values are not exposed in logs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation presents destructive file deletion and token-in-URL access as normal usage without clearly warning users about the security implications. This can lead operators to deploy an interface that enables accidental or unauthorized deletion and exposes bearer tokens through routine URL handling.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill description is written as a Chinese-language skill and later instructs how the AI should answer user questions entirely in Chinese examples, with no indication that users can choose another language. This creates a locale/language constraint without explicit opt-in, which matches the policy-violation category for natural-language requirements.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

These instructions tell the AI to direct users to a configuration file that contains live authentication secrets and to identify the exact secret fields. Even though the template avoids printing the token directly, it trains the assistant to facilitate secret discovery and handling, which increases the chance of credential exposure through social engineering, shoulder-surfing, screen sharing, or future prompt misuse.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The example response explicitly teaches the AI to help users retrieve token/password values from a local config file containing secrets. In context, this is more dangerous because the skill is specifically about exposing a local web upload endpoint; guiding secret retrieval lowers the barrier to accessing that service and normalizes handling of sensitive credentials in chat.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This response identifies the auth location inside the configuration, again conditioning the AI to assist with locating stored secrets. While intended for convenience, it creates a repeatable pattern of secret discovery assistance that could be exploited by an attacker posing as the user or by unsafe downstream automation.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 306)May include surrounding context.

  1. 检查防火墙:
bash
sudo iptables -L -n | grep 15170

上传失败

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This manifest is in scope for vague-trigger review, and its keyword list contains very generic terms such as "upload" and "file" without any narrowing invocation context. Without explicit scope constraints or negative examples, these broad triggers could overlap with everyday user requests and cause unintended skill activation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger list ends with '类似的文件上传相关问题', which is an open-ended activation condition rather than a specific bounded set of phrases. Without exclusion criteria or negative examples, this broad wording can overlap with many general support questions and make it unclear when the skill should or should not activate.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The guide repeatedly instructs users to place an authentication token directly in a URL, but does not consistently warn that URLs are commonly exposed via browser history, logs, bookmarks, screenshots, and proxy/referrer leakage. Embedding bearer-style secrets in query strings materially increases the risk of credential compromise and unauthorized access to the upload service.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The guide gives inconsistent security guidance: one template asserts the upload service is localhost-only, while other sections tell users to access it via a server IP. This can mislead users into assuming the service is not remotely reachable when it may in fact be exposed, increasing the chance of unsafe deployment or credential disclosure.

Content

No source excerpt is available for this finding.

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

Scanner excerpt · SKILL.md (reported line 322)May include surrounding context.

5️⃣ 检查文件权限

bash
ls -la ~/.openclaw/workspace/

如果还是不行,把错误信息发给我,我帮你分析!

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

Scanner excerpt · docs/AI-REPLY-GUIDE.md (reported line 220)May include surrounding context.

5️⃣ 检查文件权限

bash
ls -la ~/.openclaw/workspace/

如果还是不行,把错误信息发给我,我帮你分析!

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation presents operation without authentication as a usable fallback and shows direct installation/use guidance with only mild cautionary language. In the context of a file-upload service, an unauthenticated mode can expose the service to anyone with network reachability, enabling unauthorized uploads, abuse, or lateral impact if the service is bound beyond loopback or later reconfigured.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation explicitly instructs users to place long-lived gateway credentials in the URL query string (for both token and password modes). Query parameters are commonly exposed via browser history, server/access logs, reverse proxies, referrer headers, screenshots, and shared links, so this guidance materially increases credential leakage risk and can lead to unauthorized access to the upload service or upstream gateway.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The installer extracts the main OpenClaw gateway token/password from the user's config file and reuses it for a different service. This broadens the exposure of a sensitive credential to another process, another interface, and potentially process listings, service definitions, logs, or local privilege boundaries, violating credential separation and increasing blast radius if the upload service is compromised.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script injects gateway credentials into the runtime environment of a long-lived service with no warning about exposure risks. Environment variables may be visible to local users, administrators, crash reports, service metadata, or debugging tools, so this can leak a highly sensitive credential and enable unauthorized access to the gateway.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script creates and immediately enables/starts a persistent systemd service as part of installation. While persistence is not automatically malicious, silently installing a long-running network service expands the attack surface and can surprise users by exposing a new listener beyond the install phase.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The installer performs privileged system changes and starts a background service without any confirmation or prominent security warning. In the context of a file upload server, that means a user may unknowingly expose a new service on port 15170 and create persistence on the host, increasing the chance of accidental exposure or misuse.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.generated_source_template_injection

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/upload-server.js:200

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

Critical
Code
suspicious.generated_source_template_injection
Location
docs/AUTH-COMPATIBILITY.md:143

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

Critical
Code
suspicious.generated_source_template_injection
Location
SECURITY-AUDIT.md:94