Back to skill

Security audit

Self Upgrade Gateway

Security checks for vulnerabilities and agentic risk

Overview

This skill performs the upgrade it advertises, but it changes a persistent gateway service through an unpinned npm install that deserves user review.

Install only if you trust the OpenClaw npm package source and are comfortable with an updater that can replace the user-level gateway installation and edit the user systemd service. Prefer reviewing or changing it to install a specific confirmed version from a trusted registry with integrity verification before use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Error
Location
scripts/upgrade-openclaw.sh:265
Finding

Unpinned npm Package Retrieval and Lifecycle Script Execution

Content
View full analysis

Vulnerability Details

File Location: scripts/upgrade-openclaw.sh, lines 265-270
Vulnerability Type: Untrusted supply-chain code execution through an unpinned dependency
Risk Level: High

Vulnerable Code

bash
if npm install -g openclaw@latest 2>&1; then
    NPM_INSTALL_OK=true
    break
fi
log "npm install 第 $retry 次失败,尝试官方 registry..."
if npm install -g openclaw@latest --registry https://registry.npmjs.org 2>&1; then
    NPM_INSTALL_OK=true
    break
fi

The related compatibility precheck also retrieves a mutable version reference:

bash
npm pack openclaw@latest --pack-destination "$TMPDIR" 2>/dev/null || {
    fail "无法获取 openclaw@latest 包信息"
    exit 1
}

Technical Analysis

The script globally installs openclaw@latest, a mutable npm distribution tag, without pinning the package to the version inspected during the compatibility precheck. There is no checksum, signature, provenance, publisher identity, or package-content verification before installation.

The first installation attempt uses the invoking user's configured npm registry. A malicious or compromised registry configuration can therefore supply an attacker-controlled package. The fallback explicitly uses the public npm registry, but remains exposed to package-maintainer account compromise, malicious publication, or an unauthorized change to the latest tag.

An npm installation may execute package lifecycle scripts such as preinstall, install, and postinstall. Consequently, retrieving and installing the package is also a remote code-execution channel. The preliminary npm pack operation does not securely bind the subsequently installed package to the inspected tarball. The latest tag could resolve to a different release between the precheck and installation, creating a time-of-check/time-of-use gap.

Attack Path

  1. An attacker compromises the openclaw npm publisher, the package ...[truncated 1653 chars]
Remediation
View remediation

Remediation Suggestions

  1. Resolve the intended release once, display the exact version to the user, and require explicit confirmation before making changes.
  2. Replace every openclaw@latest reference with the approved exact version, such as openclaw@1.2.3.
  3. Use an explicitly configured trusted registry for both inspection and installation rather than allowing the first attempt to inherit an arbitrary user registry.
  4. Download the exact package tarball once and verify its npm integrity digest, trusted signature, or registry provenance before installation.
  5. Ensure the package inspected for its version and Node.js requirements is the same verified artifact that is installed, eliminating the time-of-check/time-of-use gap.
  6. Where package compatibility permits, install with --ignore-scripts to prevent lifecycle-script execution. If lifecycle scripts are required, inspect or allowlist them and perform installation in a constrained environment.
  7. Run the upgrade under a dedicated, least-privileged service account with access limited to the OpenClaw installation and service resources.
  8. Retain the backup until post-upgrade validation is complete, and account for changes outside the package directory because restoring $CURDIR cannot undo actions performed by malicious lifecycle scripts.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (6)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill clearly describes shell-capable operational behavior such as npm installation, systemd modification, service restart, and rollback, but it does not declare any explicit tool scope or permission boundaries. In an agent setting, this can lead to overbroad execution authority and unsafe command execution against the host environment, especially because the task performs privileged persistence-related changes to services and binaries.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest description and the entire markdown content are written as direct Chinese-only user-facing instructions, including prompts like '展示给主公' and '询问主公是否现在升级', with no indication that another language can be used. This creates a language/locale policy issue because the skill implicitly requires Chinese interaction rather than offering a user-selectable language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file’s user-facing natural language comments and status/failure messages are consistently in Chinese, and there is no indication that users can opt into another language or that the script is intentionally restricted to a Chinese-speaking environment. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
75% confidence
Finding

The script transmits upgrade metadata externally by querying the GitHub API during execution, which discloses that the host is performing an OpenClaw upgrade and creates a dependency on a third-party network response. In this upgrade context the risk is increased because remote release-note content is fetched and then logged, so a compromised upstream, proxy, or hostile environment could inject misleading content into operational logs or leak environment metadata.

Content

Scanner excerpt · scripts/upgrade-openclaw.sh (reported line 220)May include surrounding context.

sh
RN_TAG="${NEW_VERSION}"
# 有些版本标签带 v 前缀
RN=$(curl -sL --connect-timeout 10 \
    "https://api.github.com/repos/openclaw/openclaw/releases/tags/v${RN_TAG}" 2>/dev/null \
    | python3 -c "
import sys, json
try:

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

文件头部注释明确表示所有输出仅写入日志、不向控制台输出,但在 L389 调用 journalctl 打印最近 20 行服务日志。即使脚本前面通过 exec 重定向了标准输出,这段注释对实际行为的描述仍与代码不一致,因为脚本主动采集并输出服务日志内容。

Content

No source excerpt is available for this finding.

External Script Fetching

Low
Category
Supply Chain
Confidence
15% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/upgrade-openclaw.sh (reported line 219)May include surrounding context.

sh
log "查询 GitHub API 获取 release notes..."
RN_TAG="${NEW_VERSION}"
# 有些版本标签带 v 前缀
RN=$(curl -sL --connect-timeout 10 \
    "https://api.github.com/repos/openclaw/openclaw/releases/tags/v${RN_TAG}" 2>/dev/null \
    | python3 -c "
import sys, json