Back to skill

Security audit

Publish npm + ClawHub

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent and not malicious, but its release-staging script has unsafe path handling that could delete or package unintended local files.

Review before installing. Use the skill only for repositories you intend to publish, require an explicit final approval before any npm or ClawHub command, and avoid running release_guard.py with an existing or sensitive --prepare-release-dir path until its path containment and deletion safeguards are fixed.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/release_guard.py:129
Finding

Unrestricted Release Paths Permit Arbitrary Directory Deletion and Local File Disclosure

Content
View full analysis

Vulnerability Details

File Location: scripts/release_guard.py:129-153 and scripts/release_guard.py:371-376
Vulnerability Type: Unsafe path handling and insufficient filesystem boundary validation
Risk Level: High

Vulnerable Code

python
def copy_selected(repo: Path, include_paths: list[str], output_dir: Path, forbidden_patterns: list[str]) -> None:
    if output_dir.exists():
        shutil.rmtree(output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    for item in include_paths:
        src = repo / item
        if not src.exists():
            continue
        if matches_any(item, forbidden_patterns):
            continue
        dst = output_dir / item
        if src.is_dir():
            def ignore(dirpath: str, names: list[str]) -> set[str]:
                ignored: set[str] = set()
                for name in names:
                    candidate = Path(dirpath) / name
                    rel_path = candidate.relative_to(repo).as_posix()
                    if matches_any(rel_path, forbidden_patterns):
                        ignored.add(name)
                return ignored

            shutil.copytree(src, dst, dirs_exist_ok=True, ignore=ignore)
        else:
            dst.parent.mkdir(parents=True, exist_ok=True)
            shutil.copy2(src, dst)

The function is invoked using a user-supplied output path:

python
if args.prepare_release_dir:
    if not include_paths:
        failures.append("publish.include_paths missing in local config, cannot prepare release dir safely")
    else:
        output_dir = Path(args.prepare_release_dir).resolve()
        copy_selected(repo, include_paths, output_dir, forbidden_patterns)

Technical Analysis

The --prepare-release-dir argument is converted into an absolute path and passed directly to copy_selected(). If that path already exists, the function recursively deletes it with `s ...[truncated 2987 chars]

Remediation
View remediation

Remediation Suggestions

  1. Constrain the output directory

    • Require the output directory to be beneath an approved temporary root.
    • Reject filesystem roots, the user's home directory, the repository itself, and ancestors of the repository.
    • Refuse to delete a directory unless it contains a tool-specific marker created during an earlier safe initialization.
    • Prefer creating a new directory with tempfile.mkdtemp() instead of accepting an arbitrary deletion target.
  2. Validate every include path

    • Reject absolute paths.
    • Reject empty entries and paths containing ...
    • Resolve each source path and verify it remains beneath the resolved repository root using Path.is_relative_to().
    • Resolve each destination parent and verify it remains beneath the output root.
  3. Handle symlinks safely

    • Reject symlinked source files and directories unless explicitly required.
    • Do not follow symlinks during recursive copying.
    • Recheck resolved containment immediately before copying to reduce traversal and symlink risks.
  4. Fail closed

    • Treat any invalid include path as a fatal error instead of silently skipping it.
    • Build and validate the complete copy plan before deleting or creating anything.
    • Abort publication preparation if any source cannot be proven to reside inside the repository.
  5. Add regression tests

    • Test absolute include paths, parent traversal, symlinks escaping the repository, filesystem-root output, home-directory output, repository output, and output paths that are ancestors of the repository.
    • Verify that all unsafe cases fail before filesystem modifications occur.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (26)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The supplied code chunk is only an empty Python package initializer with a docstring indicating pattern helpers for a release guard. Based on this chunk alone, the actual behavior is far narrower and largely unimplemented compared with the broad declared purpose of publishing and release management. This is a material description-behavior mismatch because the declared primary purpose is a full guarded publish workflow, while the code shown provides no such functionality beyond suggesting helper organization.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description centers on publishing and release management workflows for skills/plugins. The provided code does not implement publishing, release preparation, metadata verification, account verification, scanner status checks, or npm/ClawHub interactions. Instead, it supplies regex pattern lists used to identify references to local credential files and disclosure text for manual review. While this may loosely relate to auditing account handling, the primary purpose and behavior of the code chunk are materially different from the declared publish workflow, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

There is a clear mismatch between the declared purpose and the supplied code. The description centers on publishing OpenClaw skills/plugins to npm and ClawHub with guarded release checks and local-account handling. The actual code chunk only contains constant regex patterns for detecting mentions of sensitive files in documentation or review contexts. This is not a supporting implementation detail for publishing in any evident way from the chunk alone; it reflects a different subsystem focused on scanning text for risky references. No publishing, release verification, account loading, metadata checks, or scanner-status investigation logic is present.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description centers on publishing and release-management workflows for skills/plugins, including account handling, release directory sanitization, and metadata/scanner verification. The actual code chunk does not implement any publishing, release, account, metadata, npm, or ClawHub behavior. Instead, it is a scanner rule definition for matching environment access APIs. That is a materially different primary purpose, so this is a clear mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This code chunk does not implement any part of the declared release/publishing workflow. Instead, it provides file-access pattern signatures for a scanner, likely used to detect suspicious local file reads. That is a materially different purpose from publishing skills/plugins to npm and ClawHub, verifying release metadata/accounts, or preparing sanitized release directories. While such scanning might exist somewhere in a broader security pipeline, this specific chunk is unrelated to the declared primary behavior and therefore constitutes a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents a release/publishing skill with guarded workflow behavior, account handling, metadata verification, sanitized release preparation, and scanner-status investigation. The supplied code chunk does not implement any publishing or verification workflow. It only contains a constant list of network-related regex signatures used for suspicious-scan pattern matching. While this could be a small supporting component for investigating ClawHub suspicious results, the chunk’s actual primary behavior is narrow scan-signature definition, which is materially different from the broad declared purpose.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `SKILL.md`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `SKILL.md`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `SKILL.md`

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 · README.md (reported line 56)May include surrounding context.

md
高风险关键词:

- `~/.openclaw/secrets.json`
- 私有 `config.json`
- 自动读取本地 secrets store

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 · README.md (reported line 67)May include surrounding context.

md
高风险关键词:

- `~/.openclaw/secrets.json`
- 私有 `config.json`
- 自动读取本地 secrets store

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 162)May include surrounding context.

md
高风险关键词:

- `~/.openclaw/secrets.json`
- 私有 `config.json`
- 自动读取本地 secrets store

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 208)May include surrounding context.

md
高风险关键词:

- `~/.openclaw/secrets.json`
- 私有 `config.json`
- 自动读取本地 secrets store

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 · references/scanner-playbook.md (reported line 25)May include surrounding context.

md
高风险关键词:

- `~/.openclaw/secrets.json`
- 私有 `config.json`
- 自动读取本地 secrets store

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

python
高风险关键词:

- `~/.openclaw/secrets.json`
- 私有 `config.json`
- 自动读取本地 secrets store

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 · README.md (reported line 74)May include surrounding context.

md
FORBIDDEN_DEFAULTS = [
    ".npmrc",
    ".env",
    "*.tgz",
    "*.local.json",

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 · references/workflow.md (reported line 50)May include surrounding context.

md
FORBIDDEN_DEFAULTS = [
    ".npmrc",
    ".env",
    "*.tgz",
    "*.local.json",

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

python
FORBIDDEN_DEFAULTS = [
    ".npmrc",
    ".env",
    "*.tgz",
    "*.local.json",

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/release_guard.py (reported line 29)May include surrounding context.

python
"""Environment-access signatures that should not live next to network sends."""

ENV_PATTERNS = [
    r"process\.env",
    r"os\.getenv",
    r"os\.environ",
    r"System\.getenv",

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/scan_patterns/env_patterns.py (reported line 4)May include surrounding context.

python
"""Environment-access signatures that should not live next to network sends."""

ENV_PATTERNS = [
    r"process\.env",
    r"os\.getenv",
    r"os\.environ",
    r"System\.getenv",

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill requires and instructs use of powerful capabilities (Read, Write, Bash, plus clawhub/curl/npm interactions) but does not declare an explicit tool scope such as permissions or allowed-tools. That increases the chance the agent will execute filesystem, shell, and network actions more broadly than intended during a real publish workflow.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The activation text uses broad triggers such as 'release, publish, ship, or republish' and also incident-investigation scenarios, which can cause the skill to fire in situations where the user did not intend external side effects. In a skill that can lead to login, logout, publish, and curl actions against real services, over-broad invocation increases the risk of accidental destructive or account-affecting operations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The workflow includes real commands that can authenticate, log out current sessions, publish packages, and upload artifacts, but it does not prominently require user confirmation immediately before executing them. Without an explicit warning and approval gate, an agent could perform irreversible external changes to npm or ClawHub accounts based on an ambiguous request.

Content

No source excerpt is available for this finding.

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/release_guard.py (reported line 74)May include surrounding context.

python
def run(cmd: list[str], cwd: Path) -> subprocess.CompletedProcess[str]:
    return subprocess.run(cmd, cwd=cwd, text=True, capture_output=True)


def load_json(path: Path) -> dict:

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill description switches into Chinese for the operational instructions, which imposes a specific language on users without any opt-in or explanation. Under the policy, language constraints should either be optional for the user or clearly justified as region-specific.

Content

No source excerpt is available for this finding.