Back to skill

Security audit

Web Claw

Security checks for vulnerabilities and agentic risk

Overview

Webclaw is a real web-dashboard admin skill, but its installer fetches unaudited code and installs privileged persistent services, so it needs careful review before installation.

Install only on a dedicated host or VM where you are comfortable granting sudo, changing nginx, running persistent services, and trusting code fetched from the publisher's GitHub tag and package registries. Review the retrieved release contents, templates, dependency manifests, nginx changes, and service units before running the installer, and avoid sharing reset passwords through chat or stored logs.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (5)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/install.sh:35
Finding

Unaudited Remote Source Is Retrieved and Executed During Installation

Content
View full analysis
Remediation
View remediation

T06 · System Persistence

Error
Location
scripts/install.sh:154
Finding

Downloaded Service Definitions Are Installed as Persistent System Services

Content
View full analysis
"$TEMP_SVC" sudo cp "$TEMP_SVC" /etc/systemd/system/webclaw-api.service rm -f "$TEMP_SVC" # Generate web service TEMP_SVC=$(mktemp) sed -e "s|{{INSTALL_DIR}}|$INSTALL_DIR|g" \ -e "s|{{USER}}|$CURRENT_USER|g" \ "$INSTALL_DIR/templates/webclaw-web.service" > "$TEMP_SVC" sudo cp "$TEMP_SVC" /etc/systemd/system/webclaw-web.service rm -f "$TEMP_SVC" # Enable and start sudo systemctl daemon-reload sudo systemctl enable webclaw-api webclaw-web sudo systemctl restart webclaw-api webclaw-web ``` ### Technical Analysis Long-running services are reasonable for the declared web-dashboard functionality. However, the service templates are not present in the reviewed artifact and are obtained through the unverified remote retrieval process. The installer copies those templates into `/etc/systemd/system`, enables them at boot, and immediately starts them. This turns a supply-chain compromise into cross-session persistence. The implementation does not display the rendered units, validate allowed directives, verify the executables they launch, or request separate approval before enabling them. ### Attack Path 1. An attacker alters one of the remotely downloaded systemd templates. 2. The installer substitutes the local installation directory and username into the malicious template. 3. The rendered unit is copied to `/etc/systemd/system` using `sudo`. 4. `systemctl enable` registers the service to start on future boots. 5. `systemctl restart` immediately launches the attacker-selected command. 6. The malicious comman ...[truncated 669 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
scripts/install.sh:54
Finding

Unverified Python and npm Dependencies Can Execute Installation Scripts

Content
View full analysis
/dev/null || npm install npm run build ``` ### Technical Analysis The Python requirements and npm project files are not included in the reviewed artifact. They are downloaded immediately before installation, so their package names, version constraints, integrity metadata, transitive dependencies, and lifecycle behavior cannot be assessed from the Skill package. `npm install` may execute dependency lifecycle hooks such as `preinstall`, `install`, and `postinstall`. `npm run build` explicitly executes the downloaded project's build script. Python package installation can also execute package build backends and installation-related code. Upgrading pip at runtime further introduces mutable external code that is not required to run the application itself. The installer does not demonstrate hash-locked Python requirements or deterministic npm installation. ### Attack Path 1. An attacker compromises the remote manifest, a referenced package, package-maintainer credentials, or a registry release. 2. A malicious package version or lifecycle hook is introduced. 3. The installer resolves the dependency from the public package registry. 4. pip, npm, or the downloaded build script executes attacker-controlled code. 5. The code runs under the installer account and may modify the application subsequently launched by systemd. ### Impact Assessment Exploitation allows code execution with the installer account's privileges. The malicious dependency can read ...[truncated 311 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/install.sh:96
Finding

Unvalidated Domain Value Is Inserted into a Root-Owned nginx Configuration

Content
View full analysis
first script argument > auto-detect IP SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}' || echo "_") DOMAIN="${WEBCLAW_DOMAIN:-${1:-$SERVER_IP}}" log "Server name: $DOMAIN" ``` ```bash TEMP_CONF=$(mktemp) sed -e "s|{{DOMAIN}}|$DOMAIN|g" \ -e "s|{{SSL_CERT}}|$CERT_DIR/cert.pem|g" \ -e "s|{{SSL_KEY}}|$CERT_DIR/key.pem|g" \ "$NGINX_CONF" > "$TEMP_CONF" sudo cp "$TEMP_CONF" /etc/nginx/sites-enabled/webclaw rm -f "$TEMP_CONF" sudo rm -f /etc/nginx/sites-enabled/default 2>/dev/null || true if sudo nginx -t 2>/dev/null; then sudo systemctl reload nginx log "Nginx configured (HTTPS on port 443, self-signed cert)." else err "Nginx config test failed. Check /etc/nginx/sites-enabled/webclaw" fi ``` ### Technical Analysis `DOMAIN` is accepted from the `WEBCLAW_DOMAIN` environment variable or the first positional argument without validation. It is then embedded into both an OpenSSL subject and a root-owned nginx configuration using `sed`. A value containing the sed delimiter, replacement metacharacters, whitespace, or newline characters can alter the rendered configuration. The management script in `db_query.py` performs strict domain validation, but the installer does not apply the same control. The `nginx -t` check only verifies whether the resulting configuration is syntactically valid. It does not prevent an attacker from injecting additional valid nginx directives. ### Attack Path 1. An attacker able to influence the installation environment or command arguments sets a crafted `WEBCLAW_DOMAIN` value. 2. The value is interpolated directly into the sed replacement operation. 3. The rendered configuration contains attacker-selected or corrupted nginx content. 4. The installer copies t ...[truncated 698 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/db_query.py:369
Finding

Passwords Are Exposed in Process Arguments and Plaintext Action Output

Content
View full analysis
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
  • Rogue AgentSelf-Modification, Session Persistence
Findings (40)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% 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 · CONTRIBUTING.md (reported line 50)May include surrounding context.

The database is auto-created on first API request at ~/.openclaw/webclaw/webclaw.sqlite. To reset it:

bash
rm -f ~/.openclaw/webclaw/webclaw.sqlite
# Restart the API server — tables will be recreated

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill is presented primarily as a browser-based dashboard, but the documented behavior includes privileged host administration actions such as restarting services, configuring nginx/Let's Encrypt, and directly manipulating authentication/session data. This mismatch is dangerous because users or orchestrators may approve or auto-invoke the skill under a lower-risk mental model, while it actually performs sensitive system and credential-management operations.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
## Security Model

- **HTTPS enforced** via Let's Encrypt (setup-ssl action)
- **JWT authentication** — access tokens (15 min) + refresh tokens (7 days, httpOnly cookies)
- **RBAC** — role-based permission checks before every skill action
- **Rate limiting** — 5/min auth, 30/min writes, 100/min general (nginx)
- **Audit logging** — all mutating actions logged to audit_log table

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
94% confidence
Finding

The restart-services action can restart host systemd services via sudo, giving the skill host-level operational control not clearly justified by a dashboard UI feature set. If this action is reachable through an agent or chat-triggered path, an attacker who gains access can disrupt service availability and potentially chain this privileged control with other weaknesses.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/install.sh (reported line 111)May include surrounding context.

sh
EXISTING_CONF="/etc/nginx/sites-enabled/webclaw"
fi

if [ -n "$EXISTING_CONF" ] && sudo nginx -t 2>/dev/null; then
    sudo systemctl reload nginx
    log "Nginx: reusing existing config at $EXISTING_CONF"
else

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

The script forcefully removes /etc/nginx/sites-enabled/default under sudo as part of installation. This is dangerous because it modifies or disables unrelated host configuration outside the skill's own namespace and can break existing web services or weaken an operator's intended server posture.

Content

Scanner excerpt · scripts/install.sh (reported line 141)May include surrounding context.

sh
"$NGINX_CONF" > "$TEMP_CONF"
    sudo cp "$TEMP_CONF" /etc/nginx/sites-enabled/webclaw
    rm -f "$TEMP_CONF"
    sudo rm -f /etc/nginx/sites-enabled/default 2>/dev/null || true

    if sudo nginx -t 2>/dev/null; then
        sudo systemctl reload nginx

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation instructs contributors to delete the SQLite database file to reset state, but it does not clearly warn that this permanently destroys local data. Even in a development context, destructive commands without explicit caution can cause unintended data loss, especially in a web admin product handling users, auth, and configuration.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill declares executable install and runtime behavior that clearly depends on shell, network, and environment/system capabilities, but it does not explicitly constrain or disclose tool scope via permissions or allowed-tools. In an infrastructure/admin skill that can install packages, clone code, configure nginx/certbot, and restart services, missing scope boundaries increases the chance of over-broad execution and unsafe agent invocation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The activation triggers are broad and overlap with common administrative language such as 'login page,' 'users,' 'roles,' 'nginx,' and 'web admin.' For a skill that can create users, reset passwords, clear sessions, configure SSL, and restart services, loose triggering raises the risk of accidental or contextually inappropriate invocation leading to unauthorized or surprising state changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill explicitly supports password resets and even setting a user-supplied password, but it does not require secure handling guidance at the action point. This can lead to weak passwords being set in chat, passwords being exposed in logs/transcripts, or temporary credentials being transmitted insecurely, creating a direct account-compromise risk in an administrative web system.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This script exposes user management, session control, SSL management, and service operations through a Telegram-invoked management interface, which expands the attack surface beyond the stated browser-dashboard role. Hidden or weakly governed out-of-band admin channels are dangerous because they can bypass the primary UI's expected authentication, audit, and authorization controls.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · scripts/db_query.py (reported line 11)May include surrounding context.

python
setup-ssl        — Configure HTTPS with Let's Encrypt (--domain required)
  renew-ssl        — Check and renew SSL certificate
  list-users       — List web dashboard user accounts
  create-user      — Create a user (--email, --full-name, --role)
  reset-password   — Generate new password for a user (--email)
  disable-user     — Disable a user account (--email)
  list-sessions    — Show active sessions

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/db_query.py (reported line 131)May include surrounding context.

python
"""Run a command and return (stdout, returncode). cmd is a list of args."""
    if isinstance(cmd, str):
        cmd = cmd.split()
    result = subprocess.run(cmd, capture_output=True, text=True)
    if check and result.returncode != 0:
        _fail(f"Command failed: {' '.join(cmd)}\n{result.stderr[:500]}")
    return result.stdout.strip(), result.returncode

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The password reset flow accepts an operator-supplied password directly and immediately applies it, which enables silent credential setting rather than a safer reset-and-notify workflow. In a remotely invoked admin channel, this increases the risk of unauthorized account takeover, especially if actions are triggered through chat automation or insufficiently verified operators.

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 · scripts/check_deps.sh (reported line 67)May include surrounding context.

sh
# Webclaw post-install script.
# Sets up backend (venv), frontend (npm build), database, nginx, and systemd.
#
# Privileges required: sudo (for nginx config, systemd services, certbot)
# What this script does:
#   1. Clones full source from GitHub if api/web dirs are missing
#   2. Creates Python venv + installs pip dependencies

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 · scripts/db_query.py (reported line 208)May include surrounding context.

python
# Webclaw post-install script.
# Sets up backend (venv), frontend (npm build), database, nginx, and systemd.
#
# Privileges required: sudo (for nginx config, systemd services, certbot)
# What this script does:
#   1. Clones full source from GitHub if api/web dirs are missing
#   2. Creates Python venv + installs pip dependencies

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 · scripts/install.sh (reported line 5)May include surrounding context.

sh
# Webclaw post-install script.
# Sets up backend (venv), frontend (npm build), database, nginx, and systemd.
#
# Privileges required: sudo (for nginx config, systemd services, certbot)
# What this script does:
#   1. Clones full source from GitHub if api/web dirs are missing
#   2. Creates Python venv + installs pip dependencies

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 · scripts/install.sh (reported line 111)May include surrounding context.

sh
# Webclaw post-install script.
# Sets up backend (venv), frontend (npm build), database, nginx, and systemd.
#
# Privileges required: sudo (for nginx config, systemd services, certbot)
# What this script does:
#   1. Clones full source from GitHub if api/web dirs are missing
#   2. Creates Python venv + installs pip dependencies

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 · scripts/install.sh (reported line 112)May include surrounding context.

sh
# Webclaw post-install script.
# Sets up backend (venv), frontend (npm build), database, nginx, and systemd.
#
# Privileges required: sudo (for nginx config, systemd services, certbot)
# What this script does:
#   1. Clones full source from GitHub if api/web dirs are missing
#   2. Creates Python venv + installs pip dependencies

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 · scripts/install.sh (reported line 119)May include surrounding context.

sh
# Webclaw post-install script.
# Sets up backend (venv), frontend (npm build), database, nginx, and systemd.
#
# Privileges required: sudo (for nginx config, systemd services, certbot)
# What this script does:
#   1. Clones full source from GitHub if api/web dirs are missing
#   2. Creates Python venv + installs pip dependencies

Static analysis

No suspicious patterns detected.