Back to skill

Security audit

plugin-creator

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent OpenClaw plugin-development guide with an observability example that needs privacy-aware use but does not show hidden or malicious behavior.

Install this skill if you want an agent to help with OpenClaw plugin development. Be careful when using or copying the bundled observability-lab example: enabling capture may write prompts, responses, tool activity, and context to a local telemetry.jsonl file, so avoid sensitive sessions or add redaction, permissions, retention, and a purge command before production use.

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

Warning
Location
references/observability-lab-source/hooks/telemetry.ts:180
Finding

Unredacted Sensitive Telemetry Stored in Unbounded Plaintext Logs

Content
View full analysis

Vulnerability Details

File Location: references/observability-lab-source/hooks/telemetry.ts:180-186, 204-210, 231-237, 259-265; references/observability-lab-source/src/observability.ts:175-196
Vulnerability Type: Plaintext storage of potentially sensitive telemetry without redaction, restrictive permissions, or retention controls
Risk Level: Medium

Vulnerable Code

ts
enqueueTelemetryEvent({
  stateDir: api.runtime.state.resolveStateDir(),
  record: {
    type,
    at: new Date().toISOString(),
    event: { ...event },
    context: { ...context },
  },
});

The same complete-event capture pattern is used for message, LLM, and tool events. Assistant transcript messages are also captured:

ts
enqueueTelemetryEvent({
  stateDir: api.runtime.state.resolveStateDir(),
  record: {
    type: "before_message_write",
    at: new Date().toISOString(),
    event: { message: event.message as Record<string, unknown> },
    context: { ...context },
  },
});

Queued records are serialized and appended to a persistent JSONL file:

ts
function startTelemetryFlush(logPath: string, queue: TelemetryQueue): void {
  if (queue.flushPromise) {
    return;
  }
  queue.flushPromise = Promise.resolve()
    .then(async () => {
      await fs.mkdir(path.dirname(logPath), { recursive: true });
      // Drain in batches so a burst of hook events still collapses into a small number of writes.
      while (queue.pendingLines.length > 0) {
        const lines = queue.pendingLines.splice(0, queue.pendingLines.length);
        await fs.appendFile(logPath, lines.join(""), "utf8");
      }
    })
    .finally(() => {
      queue.flushPromise = null;
      if (queue.pendingLines.length > 0) {
        startTelemetryFlush(logPath, queue);
        return;
      }
      if (telemetryQueues.get(logPath) === queue) {
        telemetryQueues.delete(logPath);
      }
    });
}

Technical Analysis

The observability hooks copy complete event and context object ...[truncated 2866 chars]

Remediation
View remediation

Remediation Suggestions

  1. Use an explicit field allowlist

    • Store only operational metadata required for diagnostics, such as event type, timestamp, duration, model identifier, and success status.
    • Do not serialize complete event or context objects.
  2. Redact sensitive content

    • Remove authorization headers, cookies, API keys, access tokens, passwords, private keys, and credential-like values.
    • Redact prompt text, user content, tool arguments, and tool results by default.
    • Apply recursive redaction before records enter the in-memory queue.
  3. Separate metadata and content capture

    • Keep metadata-only telemetry as the default.
    • Require a distinct, explicit opt-in for full-content recording.
    • Clearly warn that full-content capture may retain secrets and personal data.
  4. Restrict filesystem permissions

    • Create the plugin directory with mode 0o700.
    • Create the telemetry file with mode 0o600.
    • Validate existing file ownership and permissions before appending.
  5. Implement retention controls

    • Add configurable maximum file size and record age.
    • Rotate logs and cap the number of retained files.
    • Provide an authenticated purge command and document secure deletion behavior.
  6. Reduce activation scope

    • Make activation explicit rather than activating from any plugin interaction.
    • Display a visible recording indicator while capture is active.
    • Allow immediate per-session deactivation without changing the global configuration.
  7. Handle disk and serialization failures safely

    • Limit queue size to prevent unbounded memory growth during filesystem failures.
    • Catch write failures and degrade telemetry without crashing unrelated plugin functionality.
    • Avoid recursively logging telemetry errors containing sensitive records.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

The declared description is for a development/auditing skill that helps build, review, debug, and diagnose OpenClaw plugins and related SDK artifacts. The supplied code does not provide general plugin-building or debugging assistance. Instead, it implements specific observability plugin command handlers (/observe, /observe_help, /observe_tail) that control telemetry capture, message rewrite behavior, transcript prefixes, and reading/flushing telemetry logs from runtime state. These are materially different runtime capabilities and resource accesses than the declared purpose. While both are plugin-related, this code is for operating an observability plugin, not for creating/modifying/debugging plugins in the general sense described.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description is for a development/debugging skill that helps create or modify OpenClaw plugins and diagnose plugin availability issues. The supplied code is not a general plugin-building or review utility; it is concrete plugin runtime hook logic for observability. It registers hooks for session_start, message_received, llm_input, llm_output, before_tool_call, after_tool_call, before_message_write, and session_end; conditionally captures and enqueues telemetry records; flushes them to state storage; tracks capture activation state; and rewrites assistant messages by prefixing transcript text. Those are substantive runtime monitoring and output-modification behaviors not represented by the declared purpose. While telemetry could support debugging, the primary behavior here is operational observability instrumentation rather than building/reviewing/debugging plugins in the stated sense.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description is about developing and debugging arbitrary OpenClaw plugins and diagnosing plugin/runtime availability issues. The supplied code does not provide plugin-building or SDK-debugging functionality. Instead, it is concrete runtime code for a specific plugin (observability-lab) that manages observability configuration, enables/disables capture for sessions and conversations, writes telemetry events to disk, and reads telemetry logs. While this could support debugging in a broad sense, its primary purpose is observability data capture and storage for one plugin, which is materially narrower and different from the declared general plugin development/debugging capability.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description promises a broad OpenClaw plugin development and debugging capability: creating/modifying plugins, manifests, hooks, slash commands, tools, tests, and diagnosing runtime loading issues. The supplied code does not perform any of those tasks. It simply registers a tool observe_demo_echo that returns a fixed confirmation message with a few echoed parameters. While it references a plugin ID and may be useful as a lightweight verification aid inside a plugin, its primary purpose is a deterministic demo/observability echo, not plugin construction, review, debugging, or diagnosis as described. This is a material description-to-behavior mismatch.

Content

No source excerpt is available for this finding.

Context Leakage

High
Category
Data Exfiltration
Confidence
93% confidence
Finding

The document states that after a user invokes the plugin, later message, LLM, tool, and transcript events are recorded for the session. Even though activation is session-scoped rather than always-on, this still enables broad context capture that can include sensitive prompts, model outputs, and user content, making context leakage plausible if logs are accessed, shared, or mishandled.

Content

Scanner excerpt · references/observability-lab-source/README.md (reported line 95)May include surrounding context.

md
### Session-scoped activation

This plugin does not record every message by default. Instead:

1. the user first calls a plugin command or skill in the current session
2. the plugin detects that activation point

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 · references/observability-lab-source/README.md (reported line 59)May include surrounding context.

md
- `/observe status`
- `/observe on`
- `/observe off`
- `/observe rewrite on`
- `/observe rewrite off`
- `/observe prefix [text]`
- `/observe_tail`

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README explicitly describes collection of session telemetry and persistent storage to a local JSONL file, but it does not clearly warn users that messages, LLM inputs/outputs, and tool activity may be captured after activation. In a plugin context focused on observability, this creates a real privacy and consent risk because operators may enable it for debugging without understanding the scope of captured conversational data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This hook set records message content, LLM input/output, and tool-call data once capture is activated, but this file provides no user-facing notice, consent gate, or data minimization before sensitive conversation data is enqueued to persistent state. In a plugin/observability skill context, these streams can contain secrets, personal data, prompts, and tool arguments/results, so silent capture materially increases privacy and data-exposure risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The plugin responses and help text are presented only in Chinese, including status messages and command guidance. This imposes a specific language on users without any visible opt-in or locale-selection mechanism, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This test explicitly flushes telemetry events to a local JSONL file and then reads that file back, demonstrating persistent recording of conversation/tool activity. In this code file there is no confirmation prompt, user-facing log, or comment/docstring warning that telemetry data will be written to disk, which matters because persisted session data can affect user privacy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The description string is written entirely in Chinese, which can impose a locale/language requirement on users or downstream tooling without any opt-in or alternative language indicated. The policy specifically flags language or locale constraints when the skill does not offer user choice or document a justified regional scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The function enqueues arbitrary telemetry records and persists them to a JSONL log via appendFile, which can capture message, LLM, and tool-call event data. In this file there is no confirmation prompt, visible user-facing log, or comment/docstring warning users that conversational and tool activity may be recorded to disk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The comment and returned user-facing text are written in Chinese, including the primary confirmation message and field labels. This forces a specific language for tool responses without offering the user a language choice or documenting a justified locale restriction, which matches the language/locale policy violation category.

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 · references/pitfalls-and-debugging.md (reported line 149)May include surrounding context.

md
## Pitfall 11: treating a tool as a guaranteed business step

In OpenClaw, a tool is a callable capability, not an automatically executed workflow step.

Common mistakes:

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The command responses and help text are consistently hard-coded in Chinese, including status, usage, and telemetry descriptions. This imposes a specific language on all users without any opt-in or documented locale constraint, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The inline comment is written in Chinese, and a similar Chinese-only comment appears later in the file. For a general plugin source file, this imposes a language choice in natural-language content without offering an alternative or documenting a locale-specific reason.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

This comment is also written only in Chinese, reinforcing a language-specific constraint in natural-language content. There is no indication in this file that the plugin is intended solely for Chinese-speaking maintainers or users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest description is written entirely in Chinese, which can indicate a language-specific constraint for the skill metadata without any user opt-in or justification. Under the policy, locale or language restrictions should either offer a choice or be clearly documented as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The constant value "【可观测实验室】" hard-codes a Chinese-language marker in the skill behavior. This appears to impose a specific locale choice without offering users a language option or documenting why the locale restriction is required.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.