Back to skill

Security audit

VAIBot Guard

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local guard skill, but it needs Review because its security-sensitive service can fail open, persist as a background service, mishandle local paths and redaction, and upload operational receipts when API settings are enabled.

Install only after reviewing the service configuration. Keep it bound to 127.0.0.1, require a strong VAIBOT_GUARD_TOKEN, avoid HTTP or untrusted VAIBOT_API_URL values, treat logs as sensitive, and prefer foreground/manual operation until the path validation, redaction, and high-risk tool default-allow issues are fixed.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (7)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/vaibot-guard-service.mjs:81
Finding

Path Traversal Through Client-Controlled Identifiers

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/vaibot-guard-service.mjs:19
Finding

Protected Guard Endpoints Fail Open When No Token Is Configured

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/vaibot-guard-service.mjs:517
Finding

High-Risk Execution Tools Can Fall Through to an Allow Decision

Content
View full analysis
{ try { return JSON.stringify(params || {}); } catch { return "{unserializable:true}"; } })(); const deny = matchToken(DENY_TOKENS, joined); if (deny) return { decision: "deny", reason: `Denied token: ${deny}` }; const approve = matchToken(APPROVE_TOKENS, joined); if (approve) return { decision: "approve", reason: `Approval required for token: ${approve}`, approvalId: `appr_${randomUUID()}` }; const lower = tn.toLowerCase(); ...[truncated 2928 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/vaibot-guard-service.mjs:992
Finding

Default Redaction Rules Are Invalid and Sensitive Fields Are Not Recursively Sanitized

Content
View full analysis
{ const ks = String(k); const shouldRedact = POLICY.redactEnvKeyPatterns.some((p) => { try { return new RegExp(p).test(ks); } catch { return false; } }); return shouldRedact ? "[REDACTED_ENV_KEY]" : ks; }); } if (typeof clone.command === "string") clone.command = redactString(clone.command); if (Array.isArray(clone.args)) clone.args = clone.args.map((a) => redactString(a)); if (clone.network && Array.isArray(clone.network.destinations)) { clone.network.destinations = clone.network.destinations.map((d) => redactString(d)); } return clone; } ``` ### Technical Analysis JavaScript regular expressions do not support the inline `(?i)` case-insensitive modifier used by the default policy. Calls such as `new RegExp("(?i)token...", "g")` throw a syntax error. The implementation catches and silently ignores these errors. Consequently, the default secret-value patterns and environment-key patterns do not redact anythi ...[truncated 1299 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/vaibot-guard-service.mjs:685
Finding

Configurable Receipt Destination Permits Plaintext Transmission of API Credentials and Operational Telemetry

Content
View full analysis
Remediation
View remediation

T06 · System Persistence

Warning
Location
scripts/vaibot-guard.mjs:239
Finding

Optional Installer Creates a Cross-Session systemd Service

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/vaibot-guard-exec.mjs:45
Finding

Standalone Execution Wrapper Omits Authentication and Sends an Incompatible Request Schema

Content
View full analysis
Remediation
View remediation
` when a token is configured. 4. Consolidate request construction into a shared client module so the CLI and wrapper cannot diverge. 5. Add an integration test that starts an authenticated service and executes the complete wrapper decision flow. 6. Update documentation so the run-plan schema and service intent schema are identical. ]]>
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
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (32)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/vaibot-guard-service.mjs

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/vaibot-guard.mjs install-local

Self-Modification

High
Category
Rogue Agent
Confidence
70% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · references/ops-runbook.md (reported line 18)May include surrounding context.

md
## Shared environment variables

Retention:
- `VAIBOT_LOG_RETENTION_DAYS` (default 14): remove guard log/state files in `VAIBOT_GUARD_LOG_DIR` older than this many days.

Common env vars (see `SKILL.md` for full list):
- `VAIBOT_GUARD_HOST` (default `127.0.0.1`)

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file downplays the skill as only a distribution and UX surface, but the skill metadata describes operational capabilities including running the guard service, managing approvals, and validating receipts or audit logs. This mismatch can mislead reviewers, operators, or marketplace consumers about the effective trust boundary and authority of the skill, causing under-review of privileged behavior and unsafe deployment decisions.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill describes capabilities that require environment-variable access and shell execution, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates an authorization gap: an agent or runtime may expose more capability than reviewers expect, making it easier for the skill to start services, modify user configuration, or invoke local commands without clear boundary declarations.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

The skill explicitly instructs writing tamper-evident audit logs under a persistent local directory and also references sensitive credentials used by the guard service. Persistent logging is not inherently malicious, but in this context it can retain sensitive operational data, approval decisions, command metadata, or tokens if implementations are careless, increasing the blast radius of local compromise or accidental disclosure.

Content

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

md
# OpenClaw Guard Skill (VAIBot v2.1)

Provide a **local policy decision service** plus a CLI to gate OpenClaw tool calls and write **tamper-evident audit logs** in `.vaibot-guard/`.

## Sensitive credentials
- `VAIBOT_GUARD_TOKEN` — bearer token for Guard endpoints (recommended)

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

md
Two options are provided:
- **Local workstation mode (recommended):** user service (`systemctl --user`)
- **VPS / production mode:** system service (`sudo systemctl`) — **templates are not shipped in the ClawHub skill artifact**; generate/copy your own unit file (see notes below).

## Shared environment variables

Session Persistence

Medium
Category
Rogue Agent
Confidence
82% confidence
Finding

systemctl --user enable --now vaibot-guard creates user-level persistence by both starting the service and enabling it for future sessions. In a skill context, persistence is more sensitive because users may execute setup steps without fully understanding they are installing a background service tied to their account.

Content

Scanner excerpt · references/ops-runbook.md (reported line 42)May include surrounding context.

bash
systemctl --user daemon-reload
systemctl --user enable --now vaibot-guard
systemctl --user status vaibot-guard

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/ops-runbook.md (reported line 49)May include surrounding context.

md
Notes:
- The installer writes:
  - `~/.config/systemd/user/vaibot-guard.service`
  - `~/.config/vaibot-guard/vaibot-guard.env` (recommended `chmod 600`)
- Systemd templates are provided under `references/systemd/` for reference; do not assume `.service` files ship in the ClawHub artifact.

### Logs

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/vaibot-guard.mjs (reported line 188)May include surrounding context.

js
Notes:
- The installer writes:
  - `~/.config/systemd/user/vaibot-guard.service`
  - `~/.config/vaibot-guard/vaibot-guard.env` (recommended `chmod 600`)
- Systemd templates are provided under `references/systemd/` for reference; do not assume `.service` files ship in the ClawHub artifact.

### Logs

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/vaibot-guard.mjs (reported line 352)May include surrounding context.

js
Notes:
- The installer writes:
  - `~/.config/systemd/user/vaibot-guard.service`
  - `~/.config/vaibot-guard/vaibot-guard.env` (recommended `chmod 600`)
- Systemd templates are provided under `references/systemd/` for reference; do not assume `.service` files ship in the ClawHub artifact.

### Logs

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

  1. Create a dedicated user:
bash
sudo useradd --system --create-home --home-dir /var/lib/vaibot-guard --shell /usr/sbin/nologin vaibot-guard
  1. Create /etc/vaibot-guard/vaibot-guard.env and set required env vars (at minimum VAIBOT_GUARD_TOKEN, VAIBOT_POLICY_PATH, VAIBOT_GUARD_LOG_DIR).

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

  1. Create a dedicated user:
bash
sudo useradd --system --create-home --home-dir /var/lib/vaibot-guard --shell /usr/sbin/nologin vaibot-guard
  1. Create /etc/vaibot-guard/vaibot-guard.env and set required env vars (at minimum VAIBOT_GUARD_TOKEN, VAIBOT_POLICY_PATH, VAIBOT_GUARD_LOG_DIR).

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

  1. Create a dedicated user:
bash
sudo useradd --system --create-home --home-dir /var/lib/vaibot-guard --shell /usr/sbin/nologin vaibot-guard
  1. Create /etc/vaibot-guard/vaibot-guard.env and set required env vars (at minimum VAIBOT_GUARD_TOKEN, VAIBOT_POLICY_PATH, VAIBOT_GUARD_LOG_DIR).

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

  1. Create a dedicated user:
bash
sudo useradd --system --create-home --home-dir /var/lib/vaibot-guard --shell /usr/sbin/nologin vaibot-guard
  1. Create /etc/vaibot-guard/vaibot-guard.env and set required env vars (at minimum VAIBOT_GUARD_TOKEN, VAIBOT_POLICY_PATH, VAIBOT_GUARD_LOG_DIR).

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
75% confidence
Finding

sudo systemctl enable --now vaibot-guard establishes persistence by starting the service immediately and enabling it on boot. While legitimate for service installation, this creates durable execution, which is security-relevant in a skill artifact because it can outlive the invoking session if the service or its configuration is later compromised.

Content

Scanner excerpt · references/ops-runbook.md (reported line 105)May include surrounding context.

bash
sudo systemctl daemon-reload
sudo systemctl enable --now vaibot-guard
sudo systemctl status vaibot-guard

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

This command enables system-wide boot persistence for the guard service, causing it to run automatically across reboots under systemd. In the context of a skill artifact, system-level persistence is materially more dangerous than ordinary documentation because it can institutionalize long-lived execution on a host if the service, policy, or environment file is misconfigured or later abused.

Content

Scanner excerpt · references/ops-runbook.md (reported line 105)May include surrounding context.

bash
sudo systemctl daemon-reload
sudo systemctl enable --now vaibot-guard
sudo systemctl status vaibot-guard

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The service is described as a local guard, but it is explicitly configured to send proof receipts and audit-derived data to remote VAIBot endpoints when VAIBOT_API_URL and VAIBOT_API_KEY are set. Even with some redaction, this can transmit execution intent, commands, paths, results, and session metadata off-host, creating a confidentiality and trust-boundary issue if operators expect strictly local processing.

Content

No source excerpt is available for this finding.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
97% confidence
Finding

If ALLOWLISTED_DOMAINS is empty, isDomainAllowlisted returns true for any destination, effectively disabling outbound network restrictions. In a guard service that is supposed to enforce tool decisions and constrain risky actions, this fail-open behavior can allow arbitrary egress, remote fetches, and data exfiltration without the intended approval barrier.

Content

Scanner excerpt · scripts/vaibot-guard-service.mjs (reported line 353)May include surrounding context.

js
function isDomainAllowlisted(dest) {
  // Tight allowlist semantics:
  // - If allowlist is empty: allow all (legacy behavior).
  // - Exact host match is allowed.
  // - Subdomains are ONLY allowed when the allowlist entry is explicitly wildcarded as "*.example.com".
  if (ALLOWLISTED_DOMAINS.length === 0) return true;

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The proof submission path sends receipt contents, including redacted intent and audit data, to a remote /prove service using a bearer token. Because this occurs automatically and the service is framed as local policy enforcement, it creates a meaningful risk of unintended disclosure of sensitive operational context.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The governance receipt uploader sends structured execution metadata to an external API using a bearer credential, which expands the system from a local guard into a telemetry/reporting component. If enabled without strong operator awareness, it can leak sensitive command summaries, cwd values, policy decisions, and session identifiers to a third party.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code performs credential-backed network transmission to a remote receipts API using VAIBOT_API_KEY, but there is no user-facing disclosure at the point of use that execution metadata will be uploaded. Silent background exfiltration of operational metadata is risky in a guard service because users may assume decisions and logs remain local.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% 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/vaibot-guard.mjs (reported line 190)May include surrounding context.

js
if (tok.created) {
    console.error(`Generated VAIBOT_GUARD_TOKEN and wrote ${envFile} (chmod 600).`);

    // If systemd user unit appears installed, offer to restart it so the running service picks up the new token.
    const userUnitPath = path.join(os.homedir(), ".config", "systemd", "user", "vaibot-guard.service");
    const hasUnit = fs.existsSync(userUnitPath);

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% 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/vaibot-guard.mjs (reported line 354)May include surrounding context.

js
if (tok.created) {
    console.error(`Generated VAIBOT_GUARD_TOKEN and wrote ${envFile} (chmod 600).`);

    // If systemd user unit appears installed, offer to restart it so the running service picks up the new token.
    const userUnitPath = path.join(os.homedir(), ".config", "systemd", "user", "vaibot-guard.service");
    const hasUnit = fs.existsSync(userUnitPath);

Session Persistence

Medium
Category
Rogue Agent
Confidence
94% confidence
Finding

This code offers to enable and start a systemd user service, which creates persistence across user sessions. Although it is gated by an interactive prompt and consistent with the skill's stated purpose, persistence mechanisms are security-sensitive because a compromised or misconfigured guard service would continue running automatically and could mediate future tool decisions.

Content

Scanner excerpt · scripts/vaibot-guard.mjs (reported line 294)May include surrounding context.

js
// cmdConfigure exits on success; if it doesn't, continue.
    }

    const ans3 = (await rl.question("Enable + start vaibot-guard now (systemctl --user enable --now)? [y/N]: ")).trim().toLowerCase();
    if (ans3 === "y" || ans3 === "yes") {
      const { execSync } = await import("node:child_process");
      execSync("systemctl --user daemon-reload", { stdio: "inherit" });

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.exposed_secret_literal

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/vaibot-guard-exec.mjs:3

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/vaibot-guard.mjs:201

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
tests/guard-service.test.mjs:32

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/vaibot-guard-exec.mjs:18

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/vaibot-guard.mjs:20

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
tests/guard-service.test.mjs:22

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/vaibot-guard.mjs:330