Back to skill

Security audit

Openclaw Plugin Dev

Security checks for vulnerabilities and agentic risk

Overview

This is a plugin development guide, but it encourages full plaintext logging of LLM requests and responses without privacy or retention safeguards.

Review before installing or using this skill to generate plugins. If you build from its logger examples, avoid logging raw prompts, system prompts, conversation history, tool data, or complete responses unless explicitly required and approved; prefer metadata-only logs with redaction, restrictive file permissions, encryption where needed, and retention limits.

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
SKILL.md:20
Finding
Unrestricted Plaintext Logging of Sensitive LLM Requests and Responses<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 20–37, 84–89, and 146–157 **Vulnerability Type**: Sensitive data exposure through unrestricted plaintext logging **Risk Level**: Medium ### Vulnerable Code The guide identifies prompts, system prompts, and conversation history as data available to the input hook, and stores the complete input event: ```typescript const inFlightRequests = new Map<string, RequestData>(); api.on("llm_input", (event: any) => { const runId = event.runId; inFlightRequests.set(runId, { timestamp: Date.now(), input: event }); }); api.on("llm_output", (event: any) => { const runId = event.runId; const request = inFlightRequests.get(runId); // Successfully paired, record the complete request-response inFlightRequests.delete(runId); }); ``` It then recommends serializing log entries directly into date-based plaintext JSONL files: ```typescript // JSONL format, split files by date const logPath = path.join(basePath, `${new Date().toISOString().split('T')[0]}.jsonl`); fs.appendFileSync(logPath, JSON.stringify(entry) + "\n"); ``` The referenced example is explicitly described as having the following behavior: ```text Features: - Log all LLM API requests and responses - JSONL formatted logs, split by date - Correlate requests and responses using runId - Record metrics such as durationMs and usage ``` ### Technical Analysis The documented pattern captures complete LLM input and output events and recommends writing serialized entries to plaintext JSONL files. The document states that input events may contain prompts, system prompts, and historical messages. These fields can include credentials, API tokens, personal information, proprietary content, hidden system instructions, and other confidential conversation data. The guidance does not include: - A field allowlist limiting collection to operational metadata. - Redaction of passwords, tokens, or personally identifiable information. - Explicit us ...[truncated 2211 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Use metadata-only logging by default** - Record request identifiers, timestamps, latency, token usage, model names, and status codes. - Do not record prompts, system prompts, message history, tool arguments, or complete responses unless explicitly required. 2. **Require explicit opt-in for content logging** - Keep content logging disabled by default. - Display a clear warning that logged content may contain confidential information. - Obtain authorization from the system owner and, where applicable, affected users. 3. **Apply field-level filtering and redaction** - Use an allowlist rather than serializing complete event objects. - Redact authorization headers, API keys, passwords, access tokens, cookies, and known secret formats. - Provide configurable redaction for personal and organization-specific sensitive data. 4. **Protect files at creation time** - Create the log directory with owner-only permissions. - Create files with restrictive permissions such as `0600`. - Reject symlinked log paths and validate that the configured destination is an expected local directory. 5. **Implement retention controls** - Set maximum file sizes and retention periods. - Rotate files and securely delete expired records. - Avoid indefinite accumulation merely by creating a new file each day. 6. **Protect stored content** - Use encryption at rest when logging content is genuinely necessary. - Keep encryption keys separate from the log directory. - Restrict log access to the minimum set of authorized operators and processes. 7. **Document operational safeguards** - Warn administrators not to include raw logs in public bug reports or diagnostic bundles. - Document incident-response procedures for accidental secret logging. - Test redaction and access controls before enabling the plugin in production. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The guide advertises logging of full LLM requests and responses without any warning that these records may include highly sensitive user content, system prompts, conversation history, or generated secrets. This omission makes accidental overcollection and unsafe persistence more likely, especially because developers may copy the example directly into production plugins.

Missing User Warnings

Low
Confidence
85% confidence
Finding
The file-write logging example shows appending JSONL entries to disk but gives no warning about persistence, access control, or the risk of storing sensitive captured content long-term. In the context of surrounding examples that process LLM inputs and outputs, this pattern can normalize writing sensitive conversational data to local logs without protection.

Context-Inappropriate Capability

Low
Confidence
88% confidence
Finding
The skill explicitly promotes a plugin example that logs all LLM API requests and responses, which can capture prompts, system prompts, history, and model outputs containing secrets, credentials, personal data, or proprietary information. In a plugin development guide, presenting full-traffic persistence as a featured example without minimization or safeguards encourages broad surveillance capabilities that are risky if adopted blindly.

Static analysis

No suspicious patterns detected.