Back to skill

Security audit

Disk Cleanup

Security checks for vulnerabilities and agentic risk

Overview

This OpenClaw disk cleanup skill is disclosed and mostly purpose-aligned, but its normal live run has broad destructive host authority and persistent system logging changes that need human review before installation.

Install only if you want an agent-accessible maintenance script with authority to remove logs, caches, Docker artifacts, and workspace files. Run --dry-run first, avoid unattended cron until reviewed, and do not run it as root unless you accept host-wide log retention changes and deletion of rotated security logs.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/disk-cleanup.sh:359
Finding

Default cleanup performs privileged host-wide log destruction and persistent journald reconfiguration

Content
View full analysis

Vulnerability Details

File Location: scripts/disk-cleanup.sh, lines 359-393 and 525-552
Vulnerability Type: Host-wide destructive operations without explicit privileged-operation opt-in
Risk Level: High

Vulnerable Code

bash
# Also set persistent limit to prevent regrowth
JOURNAL_CONF="/etc/systemd/journald.conf.d/openclaw-limit.conf"
if [[ ! -f "$JOURNAL_CONF" && "$DRY_RUN" == "false" ]]; then
  mkdir -p /etc/systemd/journald.conf.d
  cat > "$JOURNAL_CONF" <<'JEOF'
# Installed by openclaw-disk-cleanup.sh
# Prevents journal from growing beyond 500M
[Journal]
SystemMaxUse=500M
SystemKeepFree=1G
MaxFileSec=1week
JEOF
  systemctl restart systemd-journald 2>/dev/null || true
  log "  Installed journal size limit (500M max)"
  ACTIONS+=("Installed journald 500M limit")
fi
bash
# Rotated syslogs older than current + 1
for rotlog in /var/log/syslog.[2-9]* /var/log/auth.log.[2-9]*; do
  if [[ -f "$rotlog" ]]; then
    RSIZE=$(stat -c%s "$rotlog" 2>/dev/null || echo 0)
    SYSLOG_FREED=$((SYSLOG_FREED + RSIZE))
    if [[ "$DRY_RUN" == "false" ]]; then
      rm -f "$rotlog"
    fi
  fi
done

# btmp: SSH brute-force attempts log. Can grow huge on public VPS.
# Truncate instead of delete (system expects it to exist).
BTMP="/var/log/btmp"
if [[ -f "$BTMP" ]]; then
  BTMP_SIZE=$(stat -c%s "$BTMP" 2>/dev/null || echo 0)
  if [[ $BTMP_SIZE -gt 10485760 ]]; then  # >10MB
    SYSLOG_FREED=$((SYSLOG_FREED + BTMP_SIZE))
    if [[ "$DRY_RUN" == "false" ]]; then
      : > "$BTMP"
      log "  Truncated btmp ($(bytes_to_human "$BTMP_SIZE"))"
    else
      log "  [DRY-RUN] Would truncate btmp ($(bytes_to_human "$BTMP_SIZE"))"
    fi
  fi
fi

Technical Analysis

A normal live run can write a persistent system configuration under /etc, restart systemd-journald, remove rotated authentication and system logs, and ...[truncated 2265 chars]

Remediation
View remediation

Remediation Suggestions

  1. Move all /etc, systemctl, /var/log, and host-journal operations behind an explicit --system or --host-cleanup option. Keep this option disabled by default.
  2. Require an explicit confirmation before deleting security logs or changing persistent service configuration. In unattended operation, require a separate configuration value that identifies the approved retention policy.
  3. Check EUID before host-level operations and fail with a clear message rather than relying on individual commands to fail.
  4. Do not truncate btmp or delete authentication logs by default. Use the host's configured log-rotation mechanism and retain records according to organizational security and compliance policies.
  5. Prefer temporary journal vacuuming over installing a persistent journald configuration. If persistent configuration is requested, back up existing settings and report the exact system-wide impact.
  6. Restrict system-log cleanup to explicitly enumerated files and approved retention ages. Record every deletion in a separate protected audit log.
  7. Update SKILL.md to clearly distinguish application cleanup from optional privileged host maintenance and document that host-level operations affect unrelated services.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/disk-cleanup.sh:45
Finding

Unvalidated environment-controlled roots can redirect recursive cleanup to unrelated directories

Content
View full analysis

Vulnerability Details

File Location: scripts/disk-cleanup.sh, lines 45-51, 448-467, and 566-606
Vulnerability Type: Unsafe recursive deletion based on unvalidated environment paths
Risk Level: Medium

Vulnerable Code

bash
# ─── Detect OpenClaw home ───
OPENCLAW_HOME="${OPENCLAW_HOME:-$HOME/.openclaw}"
if [[ ! -d "$OPENCLAW_HOME" ]]; then
  echo "ERROR: OpenClaw home not found at $OPENCLAW_HOME"
  exit 1
fi

WORKSPACE="${OPENCLAW_WORKSPACE:-$(pwd)}"
bash
# Workspace-local .npm and .cache (created by sandbox or agent installs)
for WS_CACHE in "$WORKSPACE/.npm" "$WORKSPACE/.cache"; do
  if [[ -d "$WS_CACHE" ]]; then
    WC_SIZE=$(du -sb "$WS_CACHE" 2>/dev/null | cut -f1 || echo 0)
    if [[ $WC_SIZE -gt 52428800 ]]; then
      PKG_CLEANED=$((PKG_CLEANED + 1))
      PKG_FREED=$((PKG_FREED + WC_SIZE))
      if [[ "$DRY_RUN" == "false" ]]; then
        rm -rf "$WS_CACHE"
        log "  Cleaned workspace cache: $WS_CACHE ($(bytes_to_human "$WC_SIZE"))"
      else
        log "  [DRY-RUN] Would clean workspace cache: $WS_CACHE ($(bytes_to_human "$WC_SIZE"))"
      fi
    fi
  fi
done
bash
# Orphaned Python venvs in scripts/ (older than 30 days, not recently used)
while IFS= read -r -d '' venv; do
  VENV_AGE=$(find "$venv" -maxdepth 0 -mtime +30 -print 2>/dev/null | wc -l)
  if [[ $VENV_AGE -gt 0 ]]; then
    VENV_SIZE=$(du -sb "$venv" 2>/dev/null | cut -f1 || echo 0)
    if [[ $VENV_SIZE -gt 52428800 ]]; then  # >50MB
      MIGRATION_COUNT=$((MIGRATION_COUNT + 1))
      safe_rm "$venv"
    fi
  fi
done < <(find "$WORKSPACE/scripts" -maxdepth 2 -name "venv" -type d -print0 2>/dev/null)

The deletion helper used by these paths is:

bash
safe_rm() {
  local target="$1"
  local size
  size=$(du -sb "$target" 2>/dev/null | cut -f1 || echo 0)
  if [[ "$DRY_RUN" == "true" ]]; then
    log "  [DRY-RUN] Wo
...[truncated 2693 chars]
Remediation
View remediation

Remediation Suggestions

  1. Canonicalize configured roots with realpath -e before using them.
  2. Reject empty values, /, the user's home directory itself, /tmp, /var, /etc, and other broad or security-sensitive roots.
  3. Require the resolved OpenClaw home and workspace to reside under explicitly approved parent directories.
  4. Verify directory ownership and permissions before deletion. Refuse to clean roots owned by another user unless an explicit privileged mode is enabled.
  5. Validate deployment identity using expected OpenClaw marker files rather than checking only whether the directory exists.
  6. Do not default the workspace to $(pwd) for destructive operations. Require an explicit OPENCLAW_WORKSPACE value or derive it from trusted OpenClaw configuration.
  7. Before every recursive deletion, verify that the canonical target remains a strict descendant of the approved canonical root.
  8. Reject symbolic-link roots and check filesystem boundaries where cleanup must not cross into mounted or unrelated filesystems.
  9. Prefer deleting individually validated files with narrow find predicates over recursively removing entire directories.
  10. For automated execution, use a sanitized environment and a dedicated low-privilege account with filesystem access limited to the intended OpenClaw deployment.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger list includes very generic phrases such as "cleanup script," "prune," "vacuum," and "free space," which can match ordinary user requests outside the intended OpenClaw maintenance context. Because this skill performs destructive cleanup actions and recommends direct shell execution, overly broad activation increases the chance of accidental invocation and unintended deletion or system changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script performs broad destructive actions across user, workspace, Docker, and system locations in live mode by default, without an explicit confirmation step. In the context of an agent skill, this increases the chance of accidental or unattended data loss if invoked by automation, misconfiguration, or an imprecise user request.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script goes beyond transient cleanup and writes a persistent journald configuration under /etc/systemd/journald.conf.d, then restarts the service. That changes long-term system logging behavior and can reduce forensic retention or violate operator expectations, especially when the skill is presented as cleanup/maintenance rather than configuration management.

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.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest's stale migration artifacts example mentions items like QMD models after backend switch, but the code additionally removes any scripts/*/venv directories older than 30 days and larger than 50MB. Deleting Python virtual environments is a broader workspace artifact cleanup capability than the documented categories suggest.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.