Back to skill

Security audit

web-observer

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed website monitoring skill that schedules checks and uses existing Vercel or GA4 credentials only for the monitoring features it describes.

Before installing, confirm you want this skill to create scheduled monitoring jobs and store local alert state. If you enable Vercel or GA4, understand that it will read those delegated skills' configured credentials from OpenClaw config and pass them to the matching child skill. Keep raw Vercel log messages disabled unless you are comfortable with application log text being delivered into chat.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (41)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This code chunk does not implement website uptime checks, Vercel error log retrieval, Core Web Vitals, or GA4 analytics access. Instead, it is infrastructure for credential handling: locating a skill's configured apiKey/env values, determining whether a skill is disabled, collecting credential overlays, and constructing child process environments. That is a materially different primary purpose from the declared monitoring behavior. While such credential plumbing could support a monitoring skill, the code shown itself is not performing the declared monitoring actions and introduces an undeclared capability around reading and propagating configured secrets.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This code does not implement website uptime checks, Vercel log retrieval, Core Web Vitals collection, or GA4 traffic reporting. Its primary function is credential/configuration bridging for scheduled delegated skill execution. That is a materially different purpose from the declared monitoring/reporting description. While such plumbing could support another monitoring skill, the supplied chunk itself performs undeclared configuration-file access and secret/environment handling, which are substantial capabilities not reflected in the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description is about a monitoring tool for websites, Vercel, and GA4. The actual code chunk is only a TypeScript declaration for a CLI dispatcher function. It exposes a generic main(argv, env, streams) interface and discusses exit-code behavior for cron/piped output, but contains no implementation showing any monitoring, alerting, analytics access, or Vercel integration. While a CLI wrapper could be a supporting detail, this chunk by itself does not substantiate the declared purpose and instead reflects a different immediate behavior: generic command dispatch. Therefore this code chunk does not accurately represent the described functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose is operational website monitoring and reporting on uptime, Vercel errors, Core Web Vitals, and GA4 traffic. The code chunk does not implement any of those monitoring or reporting behaviors. Instead, it models a diagnostic doctor command that evaluates whether the system is correctly configured and what setup issue is blocking functionality. This is a materially different primary purpose from the declared end-user monitoring behavior, so it should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents an operational monitoring skill that watches websites and reports production signals (uptime, Vercel errors/Core Web Vitals, GA4 traffic). This code chunk does not perform that monitoring or answer those user-facing queries. Instead, it is an internal/setup diagnostic command that audits whether the monitoring system is correctly configured and scheduled. While these checks support the declared product, the actual behavior here is materially different from the declared purpose and includes undeclared capabilities around local setup validation, credential inspection, and cron schedule verification. Therefore this chunk does not accurately match the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The declared description describes a broader skill covering three areas: website uptime checks, Vercel errors/Core Web Vitals, and GA4 traffic. This code chunk only implements the Vercel portion: scheduled polling of Vercel error logs and performance budget checks, with alert/recovery logic and state tracking. There is no code here for checking whether a site is up or down, and no GA4 traffic querying. While the implemented behavior is consistent with part of the description, the description as a whole is not accurately represented by this supplied code chunk alone, so this should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Yes, this is a mismatch for the provided code chunk. The declared description promises operational functionality around website uptime, Vercel errors, Core Web Vitals, and GA4 traffic. However, the actual code shown is only a small metadata module that defines and exports a version constant. It does not access websites, external APIs, logs, analytics, or triggers, and it does not perform any monitoring or reporting. While this file could be a supporting implementation detail within a larger skill, evaluating this chunk alone, its behavior does not match the 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 390)May include surrounding context.

md
Also read: each delegated skill's `SKILL.md` for its version, and whether its

Self-Modification

High
Category
Rogue Agent
Confidence
85% 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 · examples/web-observer-monitor.service (reported line 16)May include surrounding context.

text
#   systemctl --user daemon-reload
#   systemctl --user enable --now web-observer-monitor.timer
#
# Edit SKILL_DIR below if the skill is installed elsewhere.

[Unit]
Description=Web Observer uptime round

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 · lib/bridge/credentials.js (reported line 135)May include surrounding context.

js
result.problems.push(resolved.problem);
        }
    }
    const configured = typeof entry?.env === "object" && entry.env !== null && !Array.isArray(entry.env)
        ? entry.env
        : {};
    for (const name of [spec.primaryEnv, ...spec.optional]) {

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 · lib/bridge/vercel.js (reported line 185)May include surrounding context.

js
for (const problem of credentials.problems) {
        note(context.streams, `warning: ${problem}`);
    }
    const result = await runGa4(status, passthrough, childEnv(context.env, credentials.env));
    return relay(context.streams, result, GA4_SLUG);
}
/**

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 · lib/cli/main.js (reported line 195)May include surrounding context.

js
for (const problem of credentials.problems) {
        note(context.streams, `warning: ${problem}`);
    }
    const result = await runGa4(status, passthrough, childEnv(context.env, credentials.env));
    return relay(context.streams, result, GA4_SLUG);
}
/**

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 · lib/commands/delegate.js (reported line 83)May include surrounding context.

js
for (const problem of credentials.problems) {
        note(context.streams, `warning: ${problem}`);
    }
    const result = await runGa4(status, passthrough, childEnv(context.env, credentials.env));
    return relay(context.streams, result, GA4_SLUG);
}
/**

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 · lib/commands/doctor.js (reported line 186)May include surrounding context.

js
for (const problem of credentials.problems) {
        note(context.streams, `warning: ${problem}`);
    }
    const result = await runGa4(status, passthrough, childEnv(context.env, credentials.env));
    return relay(context.streams, result, GA4_SLUG);
}
/**

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 · lib/commands/doctor.js (reported line 240)May include surrounding context.

js
for (const problem of credentials.problems) {
        note(context.streams, `warning: ${problem}`);
    }
    const result = await runGa4(status, passthrough, childEnv(context.env, credentials.env));
    return relay(context.streams, result, GA4_SLUG);
}
/**

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 · lib/commands/doctor.js (reported line 241)May include surrounding context.

js
for (const problem of credentials.problems) {
        note(context.streams, `warning: ${problem}`);
    }
    const result = await runGa4(status, passthrough, childEnv(context.env, credentials.env));
    return relay(context.streams, result, GA4_SLUG);
}
/**

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 · lib/commands/vercelWatch.js (reported line 160)May include surrounding context.

js
for (const problem of credentials.problems) {
        note(context.streams, `warning: ${problem}`);
    }
    const result = await runGa4(status, passthrough, childEnv(context.env, credentials.env));
    return relay(context.streams, result, GA4_SLUG);
}
/**

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

md
- `schedule`, which prints the `openclaw cron add` commands a configuration
  needs, and creates them with `--apply`.
- `--dry-run` on every command that would send a request or an alert.
- A systemd unit and timer, as a fallback for installs running with OpenClaw's
  cron disabled.

### Notes on how this works, all verified against a live OpenClaw 2026.7.1-2

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · README.md (reported line 67)May include surrounding context.

3. Copy the example configuration and edit it.

bash
mkdir -p ~/.openclaw/web-observer
cp ~/.openclaw/workspace/skills/web-observer/examples/config.json \
   ~/.openclaw/web-observer/config.json

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · SETUP.md (reported line 31)May include surrounding context.

~/.openclaw/web-observer/config.json. Copy the example there:

bash
mkdir -p ~/.openclaw/web-observer
cp <skill-dir>/examples/config.json ~/.openclaw/web-observer/config.json

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · SETUP.md (reported line 236)May include surrounding context.

timer in examples/. Install them with:

bash
mkdir -p ~/.config/systemd/user
cp <skill-dir>/examples/web-observer-monitor.* ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now web-observer-monitor.timer

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill explicitly documents access to environment variables and network destinations, but it does not declare an explicit tool/permission scope in the manifest. In an agent ecosystem, missing scope declarations weaken sandboxing and user visibility, and this skill also forwards selected credentials to subprocesses, so the absence of a formal capability boundary is a real security issue even if the documented behavior is legitimate.

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

md
through as written. Web Observer's alerts therefore carry counts, statuses and
  routes. If somebody wants the text, they run `vercel errors` themselves, or
  set `includeMessages: true` knowing what it means.
- **Do not ask the user to paste a token into the conversation.** Point them at
  `openclaw config set`.

## Commands

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · examples/web-observer-monitor.service (reported line 11)May include surrounding context.

text
# to reimplement the scheduling that both cron and systemd already do.
#
# Install:
#   mkdir -p ~/.config/systemd/user
#   cp web-observer-monitor.* ~/.config/systemd/user/
#   systemctl --user daemon-reload
#   systemctl --user enable --now web-observer-monitor.timer

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

md
#   mkdir -p ~/.config/systemd/user
#   cp web-observer-monitor.* ~/.config/systemd/user/
#   systemctl --user daemon-reload
#   systemctl --user enable --now web-observer-monitor.timer
#
# Edit SKILL_DIR below if the skill is installed elsewhere.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
lib/bridge/delegate.js:18