Back to skill

Security audit

sys-updater

Security checks for vulnerabilities and agentic risk

Overview

This is a real system-updater skill, but its code performs privileged package changes and installed-skill updates in places the documentation describes as safer or read-only.

Review this skill carefully before installing. It should not be enabled on a production host until report generation is read-only, dry-run is enforced across child commands, sudo documentation matches actual privileged operations, autoremove is removed or explicitly approved, and OpenClaw skill updates require a separate reviewed action.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/apt_maint.py:558
Finding

Dry-run mode performs real package and OpenClaw Skill updates

Content
View full analysis
subprocess.CompletedProcess[str]: global _dry_run if _dry_run and cmd[0] == "sudo": log.info("[DRY-RUN] Would execute: %s", " ".join(cmd)) return subprocess.CompletedProcess(cmd, 0, stdout="", stderr="") return subprocess.run(cmd, text=True, capture_output=True, check=check, timeout=timeout) ``` Later, `run_6am()` invokes `pkg_maint.py` directly without forwarding the `--dry-run` option: ```python # Run pkg_maint.py for npm/brew checks + planned upgrades try: pkg_maint_path = Path(__file__).parent / "pkg_maint.py" if pkg_maint_path.exists(): log.info("Running: pkg_maint.py check for npm/brew") cp_check = subprocess.run( ["python3", str(pkg_maint_path), "check"], capture_output=True, text=True, timeout=180 ) if cp_check.returncode == 0: log.info("pkg_maint.py check: OK") else: log.warning("pkg_maint.py check: rc=%d, err=%s", cp_check.returncode, cp_check.stderr[:200]) log.info("Running: pkg_maint.py upgrade for npm/brew planned packages") cp_upgrade = subprocess.run( ["python3", str(pkg_maint_path), "upgrade"], capture_output=True, text=True, timeout=600 ) ``` The nested `check` operation calls `check_skills()`, which may update installed OpenClaw Skills. The nested `upgrade` operation performs real npm, pnpm, and Homebrew upgrades. Because neither child command receives `--dry-run`, the parent command's safety option does not cover these mutations. This violates the documented expectation that `run_6am --dry-run` is ...[truncated 1000 chars]
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/apt_maint.py:868
Finding

Report generation silently downloads and installs OpenClaw Skill updates

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/apt_maint.py:285
Finding

Runtime performs privileged APT installation and autoremove operations excluded by the declared sudo policy

Content
View full analysis
tuple[list[str], list[str]]: """Apply explicitly planned non-security upgrades via apt-get install. Returns: (applied_packages, failed_packages) """ # Only attempt packages that are still upgradable now. targets = sorted([p for p in planned if p in upgradable_set]) if not targets: return [], [] try: log.info("Running: sudo apt-get install -y %s", " ".join(targets)) cp = sh(sudo_cmd(["apt-get", "install", "-y", *targets]), check=False, timeout=DEFAULT_TIMEOUT) ``` It also performs unconditional privileged dependency removal during every `run_6am()` execution: ```python # Cleanup orphaned dependencies try: log.info("Running: sudo apt-get autoremove -y") cp = sh(sudo_cmd(["apt-get", "autoremove", "-y"]), check=False, timeout=300) ``` These operations directly contradict the declared security constraints in `SKILL.md:156-158`: ```text - No `apt-get upgrade` without `-s` (simulation only for tracking) - No `apt-get dist-upgrade` or `autoremove` - No package installation/removal through sudo ``` They also conflict with `docs/sudoers.md:45`, which states that no `apt-get install`, `remove`, or `autoremove` permissions are granted. Consequently, either these code paths fail in a correctly configured deployment or administrators must broaden passwordless sudo permissions beyond the documented least-privilege boundary. The package names are passed as an argument list rather than through a shell, which limits shell-injection risk. The primary issue is unauthorized privilege scope and destructive behavior, not s ...[truncated 1332 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
scripts/pkg_maint.py:385
Finding

Packages with unresolved reviews are automatically approved and installed after four days

Content
View full analysis
int: """Escalate long-pending items to planned upgrades. Policy: - only items with reviewResult == "pending" - not blocked - not already planned - older than `days` since firstSeenAt """ changed = 0 items = tracked.get("items", {}) now = now_utc() for name, meta in items.items(): if meta.get("blocked") or meta.get("planned"): continue if meta.get("reviewResult") != "pending": continue first_seen = meta.get("firstSeenAt") if not first_seen: continue try: first_dt = parse_iso(first_seen) except (ValueError, TypeError): continue if (now - first_dt) < timedelta(days=days): continue meta["planned"] = True note = meta.get("note") or "" suffix = f"Auto-planned after pending>{days}d" meta["note"] = f"{note}; {suffix}" if note else suffix meta["reviewedBy"] = meta.get("reviewedBy") or "auto" changed += 1 ``` `upgrade_mode()` calls this function before processing npm, pnpm, and Homebrew installations: ```python auto_planned_by_manager: dict[str, int] = { manager: auto_plan_long_pending(tracked_by_manager[manager], manager) for manager in MANAGER_ORDER } ``` A `pending` decision means the review engine could not establish that an update was safe—for example ...[truncated 1406 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
  • Rogue AgentSelf-Modification, Session Persistence
Findings (92)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
./scripts/apt_maint.py run_6am

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
./scripts/apt_maint.py run_6am

Self-Modification

High
Category
Rogue Agent
Confidence
91% confidence
Finding

The skill explicitly includes a capability to update installed skills, which is a self-modification/supply-chain risk because future executions may run newly fetched code or altered automation logic. In an agent environment, code that can update its own operational dependencies is especially sensitive because it can bypass normal review expectations and widen the impact of a compromised upstream source.

Content

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

Apply planned upgrades

./scripts/pkg_maint.py upgrade

Update skills only

./scripts/pkg_maint.py skills

text

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
94% confidence
Finding

Manual rm state/apt/.run_6am.lock is dangerous because it bypasses a synchronization control protecting against concurrent executions. If used incorrectly, it can trigger duplicate maintenance runs, race conditions, and inconsistent or corrupted package-tracking state.

Content

Scanner excerpt · docs/operations.md (reported line 86)May include surrounding context.

cat state/apt/.run_6am.lock

If stale (process doesn't exist), remove manually

rm state/apt/.run_6am.lock

text

### "No data" in report

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
92% confidence
Finding

Deleting state/apt/tracked.json resets tracking state and may discard review, block, or recovery metadata without adequate warning. That can alter future updater behavior, make auditing harder, and cause previously blocked or reviewed packages to be reprocessed unexpectedly.

Content

Scanner excerpt · docs/operations.md (reported line 141)May include surrounding context.

cat state/apt/tracked.json | jq '.items | to_entries | map(select(.value.blocked)) | .[].key'

Clear old tracking (reset)

rm state/apt/tracked.json python3 scripts/apt_maint.py run_6am

text

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

python
"""Apt maintenance helper for the OpenClaw host (sys-updater).

Modes:
- run_6am: sudo apt-get update; sudo unattended-upgrade; sudo apt-get -s upgrade; snapshot upgradable pkgs.
- report_9am: render a human report from last run state.

Conservative by design:

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/apt_maint.py (reported line 212)May include surrounding context.

python
def list_upgradable() -> list[str]:
    """List upgradable packages using apt directly (no bash wrapper)."""
    # Use apt list directly, suppressing the warning about CLI stability
    env = os.environ.copy()
    env["LANG"] = "C.UTF-8"
    cp = subprocess.run(
        ["apt", "list", "--upgradable"],

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

A report-generation mode should be observational, but this code inventories and updates skills, creating side effects unrelated to its stated role. Hidden update behavior in a reporting path is especially risky because users may run it frequently and without expecting code or package changes.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
97% confidence
Finding

This code path updates installed skills, which are part of the agent's own executable capability set, creating a self-modification mechanism. In an agent-skill ecosystem, auto-updating skills from a package source can import malicious or compromised code and immediately expand or alter runtime behavior without review.

Content

Scanner excerpt · scripts/pkg_maint.py (reported line 256)May include surrounding context.

python
else:
                log.debug("Skill %s already up to date", slug)
        else:
            log.error("Failed to update skill %s: %s", slug, stderr[:200])
            result["failed"].append({"name": slug, "error": stderr[:200]})
    
    return result

Self-Modification

High
Category
Rogue Agent
Confidence
98% confidence
Finding

The check mode triggers skill updates automatically, meaning a routine maintenance run modifies the agent's installed skills without a distinct approval step. Because skills are executable extensions, this materially increases the risk of supply-chain compromise and unintended capability changes.

Content

Scanner excerpt · scripts/pkg_maint.py (reported line 487)May include surrounding context.

python
blocked_count = _count_flag(tracked_by_manager, "blocked")
    log.info("Summary: planned=%d, blocked=%d", planned_count, blocked_count)

    # Update skills immediately (no quarantine for skills)
    log.info("Updating OpenClaw skills...")
    skills_result = check_skills()
    if skills_result["installed"]:

Self-Modification

High
Category
Rogue Agent
Confidence
91% confidence
Finding

The CLI advertises and normalizes immediate skill updates without quarantine, reinforcing an unsafe operational pattern for self-modifying agent components. While this line is descriptive rather than executable, it documents and encourages the risky behavior implemented elsewhere.

Content

Scanner excerpt · scripts/pkg_maint.py (reported line 703)May include surrounding context.

python
formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Modes:
  check    - Update tracked state + auto-update skills (run daily in run_6am)
  review   - Show packages due for bug review (after 2 days)
  upgrade  - Apply planned npm/pnpm/brew upgrades
  skills   - Update OpenClaw skills immediately (no quarantine)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Line L07 states that the tool generates Telegram reports in Russian as a fixed behavior. This is a natural-language locale policy constraint with no indication that users can choose another language or opt in to Russian output.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
87% confidence
Finding

The skill explicitly requires sudo NOPASSWD for apt-get and unattended-upgrade, meaning the automation can invoke privileged package-management operations without interactive authentication. If the script, its execution environment, or related paths are modified or abused, this creates a strong privilege-escalation and system-integrity risk because package operations run as root.

Content

Scanner excerpt · CLAUDE.md (reported line 21)May include surrounding context.

python3 scripts/apt_maint.py report_9am

text

No external dependencies—uses only Python stdlib. Requires sudo NOPASSWD for apt-get and unattended-upgrade.

## Architecture

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The markdown states that security updates are applied automatically and shows maintenance commands that perform package updates, which can modify system state and installed software. While the behavior is described, it does not include a clear warning or caution to users that running or enabling this skill will make real system changes and should be used only on intended hosts.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
84% confidence
Finding

Requiring Sudo NOPASSWD for apt-get and unattended-upgrade materially increases risk because any compromise of the invoking user, automation account, or script path can lead to passwordless root-level package operations. In the context of an automation skill that regularly runs maintenance, this expands the blast radius and makes post-compromise privilege escalation easier.

Content

Scanner excerpt · README.md (reported line 31)May include surrounding context.

md
- Python 3.10+ (stdlib only, no dependencies)
- Ubuntu with `unattended-upgrades` installed
- Sudo NOPASSWD for apt-get and unattended-upgrade (see [docs/sudoers.md](docs/sudoers.md))

## Directory Structure

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description advertises Telegram reporting but does not prominently warn that package inventory, update status, and potentially hostname/system-maintenance details may be transmitted to an external messaging service. This creates a data exposure risk because operators may enable the skill without understanding that operational metadata leaves the host.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The capability description at L035-L036 says the skill 'checks installed skills and reports update status', which is read/report oriented. But the workflow at L049 says 'skills: auto-update immediately (no quarantine)', implying actual modification of installed skills rather than only checking/reporting. These statements actively describe different behaviors for the same feature.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The workflow states that installed skills are auto-updated immediately with no quarantine, but it does not prominently warn that this modifies the local environment and can execute changed third-party skill content. Immediate self-update behavior increases supply-chain and operational risk because updates may alter automation behavior without prior approval.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
84% confidence
Finding

The skill instructs users to grant passwordless sudo to automation for package-management operations, which materially increases risk if the agent, its scripts, or related dependencies are compromised. Even though the allowed commands are constrained, root-capable package update paths can still be abused for persistence, repository-based compromise, or unintended system changes.

Content

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

md
## Sudoers Configuration

For unattended operation, grant the running user passwordless sudo for specific apt commands only. **Do not add the user to full sudoers.**

Create file `/etc/sudoers.d/sys-updater`:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file presents its operational instructions in Russian, which effectively forces a specific language for users reading or operating the skill. The policy allows locale constraints only when the skill offers user choice or clearly documents a justified region-specific requirement, neither of which is present here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation describes an automated workflow that runs package maintenance commands and writes persistent state, but it does not prominently warn that the skill modifies the host system and should only be used with informed authorization. Even though the commands are standard administrative operations, omission of an explicit modification warning increases the risk of unintended execution in the wrong environment or by an operator who expects read-only behavior.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · docs/how-it-works.md (reported line 68)May include surrounding context.

tracked.json maintains metadata for each non-security package.

Automatic cleanup: Packages that are no longer upgradable (already upgraded or removed from repos) are automatically removed from tracking, unless they are marked as blocked or planned (indicating admin made a decision about them).

json
{

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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 · docs/operations.md (reported line 10)May include surrounding context.

Comment out cron entries:

bash
crontab -e
# Comment the lines with #

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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 · docs/operations.md (reported line 18)May include surrounding context.

Comment out cron entries:

bash
crontab -e
# Comment the lines with #

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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 · docs/scheduling.md (reported line 19)May include surrounding context.

Comment out cron entries:

bash
crontab -e
# Comment the lines with #

Static analysis

No suspicious patterns detected.