Back to skill

Security audit

DR Context Pipeline

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed memory/context pipeline, but it gives agents durable memory and workspace-modifying behavior with insufficient guardrails for persistence, private debug artifacts, and fixture-driven file writes.

Install only if you want this workspace to use persistent memory as a default operating layer. Review AGENTS.md changes before accepting them, use debug/audit modes only when you are comfortable writing conversation and memory content to disk, avoid committing secrets or pasted third-party instructions to memory, and do not run external test fixtures without isolating the output directory.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • 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 (3)

T02 · Agent Memory Poisoning

Error
Location
references/MEMORY_COMMIT.md:3
Finding
Persistent memory can promote attacker-controlled content into future Agent instructions<![CDATA[ ## Vulnerability Details **File Location**: `references/MEMORY_COMMIT.md:3-49`, `SKILL.md:54-57,99-105`, `references/compressor_prompt.txt:2-15` **Vulnerability Type**: Persistent prompt injection through long-term memory **Risk Level**: High ### Vulnerable Code and Instructions From `references/MEMORY_COMMIT.md:3-49`: ```markdown Trigger phrases: “memorize this”, “store this”, “commit this session”, “we’ll continue later”. ## 1. Append to today’s daily log ```bash cd ~/.openclaw/workspace cat <<'EOF' >> memory/$(date -u +%Y-%m-%d).md - <brief summary of what happened> - Decisions: - <bullet> - Follow-ups: - <bullet> EOF ``` ## 2. Update `memory/now.md` Keep a short, current-state list. ## 3. Update `memory/open-loops.md` Add actionable follow-ups with owners/status. ## 4. Create/update the relevant topic file If a topic exists, edit it; otherwise create one under `memory/topics/`. ## 5. Record durable rules in `MEMORY.md` Add a short bullet under the appropriate section. ``` From `SKILL.md:54-57,99-105`: ```markdown - When he says "let's continue" after a reset, reload `memory/now.md`, `memory/open-loops.md`, and the relevant topic files before acting. Every task must follow `references/RUNTIME_CHECKLIST.md`. 1. Load `memory/always_on.md`. 2. Route the message deterministically using `references/router.yml`. 3. Retrieve relevant snippets from memory; prefer semantic/hybrid memory search when persistent memory is relevant. 4. Build a Retrieval Bundle object that matches the schema and records retrieval mode. 5. Compress to a Context Pack using `references/compressor_prompt.txt`. 6. Lint the Context Pack. If lint fails, fall back to raw retrieved snippets. 7. Call the main reasoning model with always-on policy + Context Pack + user message. ``` From `references/compressor_prompt.txt:2-15`: ```text You are a Context Pack compressor. You receive a Retrieval Bundle JSON containing: - the user message - always-on policy/topic catalog - ret ...[truncated 3246 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Separate policy from memory data** - Do not allow ordinary memory snippets to populate `must_follow`. - Restrict mandatory instructions to authenticated, administrator-controlled policy files. - Represent retrieved memory as quoted, untrusted reference material. 2. **Add provenance and trust metadata** - Record who supplied each memory entry, when it was approved, and whether it is factual data, a preference, or executable policy. - Require a trusted provenance value before content can affect Agent behavior. 3. **Require confirmation for durable rules** - Before writing to `MEMORY.md` or an always-on policy file, show the exact proposed entry. - Require explicit confirmation that the content should become a standing rule. - Do not infer durable rules merely from “memorize this.” 4. **Filter instruction-like and sensitive content** - Detect and quarantine text that tells the Agent to ignore constraints, call tools, disclose data, alter safety behavior, or treat retrieved content as higher-priority instructions. - Prevent credentials, tokens, private keys, and other secrets from being committed to memory. 5. **Harden downstream prompts** - Explicitly state that retrieved snippets are untrusted data and cannot override system, developer, workspace, or current-user instructions. - Require the compressor to classify instruction-like snippets as untrusted context rather than `must_follow`. 6. **Harden fallback behavior** - Do not pass raw snippets directly into an instruction-bearing prompt after lint failure. - Delimit and label fallback snippets as untrusted quotations. 7. **Support review and rollback** - Maintain an auditable memory-change log. - Provide commands to inspect and remove recently committed entries. - Consider expiration for unreviewed memory records. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/schemas/retrieval_bundle.schema.json:7
Finding
Debug and audit artifacts persist full private messages and memory content without confidentiality controls<![CDATA[ ## Vulnerability Details **File Location**: `references/RUNTIME_ARTIFACTS.md:11-37`, `references/schemas/retrieval_bundle.schema.json:7-64`, `SKILL.md:106` **Vulnerability Type**: Plaintext persistence of sensitive Agent context **Risk Level**: Medium ### Vulnerable Code and Configuration From `references/RUNTIME_ARTIFACTS.md:11-37`: ```markdown ## Run folder Use one folder per pipeline run: ```text .openclaw/context-runs/<run_id>/ ``` ## Required artifacts For `debug` and `audit`, write these files when the corresponding step is reached: ```text retrieval_bundle.json context_pack.json lint_result.json reasoning_input_summary.json ``` For `audit`, also write: ```text receipt_ledger.json ``` ``` From `references/schemas/retrieval_bundle.schema.json:7-64`: ```json { "required": [ "retrieval_version", "user_message", "always_on", "query_plan", "snippets", "dropped" ], "properties": { "user_message": { "type": "object", "additionalProperties": false, "required": ["text"], "properties": { "text": { "type": "string", "minLength": 1 }, "timestamp_utc": { "type": "string" } } }, "always_on": { "type": "object", "additionalProperties": false, "required": ["path", "content"], "properties": { "path": { "type": "string" }, "content": { "type": "string" }, "content_hash": { "type": "string" } } }, "snippets": { "type": "array", "items": { "$ref": "#/$defs/snippet" } } }, "$defs": { "snippet": { "type": "object", "additionalProperties": false, "required": [ "snippet_id", "path", "start_line", "end_line", "citation", "text" ], "properties": { "snippet_id": { "type": "string", "pattern": "^S[0-9]+$" }, "path": { "type": "string" }, "citation": { "type": "string" }, "text": { "typ ...[truncated 2241 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Minimize persisted data** - Store hashes, snippet IDs, and redacted summaries by default. - Do not persist the complete user message or retrieved snippet text unless explicitly required. - Make full-content persistence a separate, informed opt-in. 2. **Apply restrictive permissions** - Create `.openclaw/context-runs` with mode `0700`. - Create artifact files with mode `0600`. - Avoid relying on the process's ambient umask. 3. **Add secret and personal-data redaction** - Detect API keys, access tokens, passwords, private keys, session cookies, email addresses, and other sensitive identifiers. - Redact sensitive values before serialization. - Record that redaction occurred without preserving the original value. 4. **Define retention and deletion** - Establish a short default retention period. - Automatically remove expired runs. - Provide a documented command for immediate secure cleanup. 5. **Protect backups and synchronization** - Exclude raw runtime artifacts from source control. - Document whether artifacts may be included in cloud synchronization or backups. - Encrypt artifacts at rest where retention is required. 6. **Obtain explicit consent** - Before entering debug or audit mode, notify the user that message and memory content may be written to disk. - Allow the user to select metadata-only audit output. 7. **Add tests** - Verify artifact modes and permissions. - Verify that representative credentials and personal data are redacted. - Verify that retention cleanup removes expired artifacts. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run_pipeline_tests.py:590
Finding
Fixture-controlled case identifiers allow artifact output path traversal<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run_pipeline_tests.py:378-384,471-482,590-596` **Vulnerability Type**: Path traversal and arbitrary file overwrite through untrusted test fixtures **Risk Level**: Medium ### Vulnerable Code From `scripts/run_pipeline_tests.py:378-384`: ```python written: dict[str, str] = {} for name, data in artifacts.items(): path = run_dir / name write_json(path, data) written[name] = str(path) return written ``` From `scripts/run_pipeline_tests.py:471-482`: ```python for name in tamper.get("delete_artifacts", []): path_str = artifact_paths.get(name) if not path_str: continue path = Path(path_str) if path.exists(): path.unlink() for name, path_str in tamper.get("artifact_path_overrides", {}).items(): artifact_paths[name] = path_str ``` From `scripts/run_pipeline_tests.py:590-596`: ```python run_dir = output_root / ".openclaw" / "context-runs" / f"{case['id']}-{case['mode']}" artifact_paths: dict[str, str] = {} receipt_ledger = None if case["mode"] in {"debug", "audit"}: artifact_paths = write_artifacts(case, run_dir) ``` ### Technical Analysis The test runner reads `case["id"]` from a caller-selected JSON fixture and directly incorporates it into `run_dir`. The value is not constrained to a safe filename and is not checked for: - Absolute paths. - `..` parent-directory components. - Forward or backward path separators. - Resolution outside the configured output root. `write_json()` creates parent directories and writes fixed artifact filenames beneath the resulting path. A malicious identifier containing traversal components can therefore move the effective run directory outside `.openclaw/context-runs`. The affected artifact names include: - `retrieval_bundle.json` - `context_pack.json` - `lint_result.json` - `reasoning_input_summary.json` - `receipt_ledger.json` in audit mode Existing files with those names can be overwritten using the current us ...[truncated 1609 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Validate case identifiers** - Accept only a strict pattern such as `^[A-Za-z0-9._-]+$`. - Reject empty identifiers, path separators, absolute paths, and parent-directory components. - Apply equivalent validation to `mode` before including it in a path. 2. **Enforce canonical containment** - Resolve the canonical context-runs root and candidate run directory. - Verify that the candidate is a descendant of the expected root before creating directories, writing files, hashing files, or deleting files. Example hardening logic: ```python SAFE_ID_RE = re.compile(r"^[A-Za-z0-9._-]+$") def safe_run_dir(output_root: Path, case_id: str, mode: str) -> Path: if not SAFE_ID_RE.fullmatch(case_id): raise ValueError(f"Unsafe case id: {case_id!r}") if mode not in {"normal", "debug", "audit"}: raise ValueError(f"Unsafe mode: {mode!r}") base = (output_root / ".openclaw" / "context-runs").resolve() candidate = (base / f"{case_id}-{mode}").resolve() if candidate.parent != base: raise ValueError("Run directory escapes the context-runs root") return candidate ``` 3. **Protect file writes** - Refuse to overwrite pre-existing files unless an explicit safe overwrite option is enabled. - Use exclusive file creation for newly generated artifacts where possible. - Consider writing to a newly created temporary directory beneath the validated root. 4. **Protect deletions** - Before `unlink()`, resolve the path and verify that it is beneath the current validated run directory. - Do not derive deletion targets from fixture-controlled path strings. - Restrict deletions to a fixed allowlist of generated artifact names. 5. **Treat external fixtures as untrusted** - Document that fixtures can influence filesystem operations. - Run third-party fixtures in an isolated temporary directory under a low-privilege account. - Add regression cases for absolute paths, pare ...[truncated 56 chars]
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description describes a runtime memory/context processing pipeline with semantic retrieval, compression/linting, fallback logic, and watchdog behavior. The supplied code does not implement any of those capabilities. Instead, it is an installation utility that copies files from an assets directory into the workspace and reports file hashes. This is a materially different primary purpose and introduces undeclared filesystem installation/synchronization behavior. While installation could support the larger skill, this specific code chunk is not accurately represented by the declared description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description suggests the skill itself implements a runtime context/memory pipeline with semantic retrieval, compression/linting, fallback logic, and watchdog behavior. The supplied code does not perform any of those pipeline operations. Instead, it is an installer/asset validator: it traverses directories, computes SHA-256 hashes, compares installed files to source assets, checks for extra/missing files, and validates the structure of JSON test files. While the JSON checks reference concepts like retrieval, context packs, fallback fixtures, and anti-fabrication cases, the script only validates fixture presence and shape; it does not execute semantic retrieval checks, compression/lint, fallback handling, or memory watchdog logic. Therefore the actual primary purpose is materially different from the declared purpose.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill instructs the agent to run shell commands and perform file reads/writes, but it declares no explicit tool scope or permissions boundary. That omission makes the capability set non-transparent to users and policy layers, increasing the risk that an agent executes workspace-modifying or environment-dependent actions without informed approval.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The document requires writing multiple runtime artifacts to disk, including retrieval bundles, context packs, and reasoning input summaries, but it does not require data minimization, retention limits, access controls, or redaction of sensitive user/context data. Because these artifacts are explicitly designed to capture pipeline state and may include private context, they create a persistent local record that could expose sensitive information to other processes, users, backups, or later compromise.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The ops route includes very broad substrings such as "error", "failed", "job", and "missed", and routing is first-match-wins. That can cause ordinary user messages to be classified as ops and pull ops-oriented context, daily logs, and derived queries that are unrelated to the actual request, creating context contamination and possible unintended disclosure of operational memory.

Vague Triggers

Medium
Confidence
93% confidence
Finding
Several routes rely on ambiguous phrases like "design", "plan", "why", "review this", and "briefing", with no clear constraints and deterministic first-match behavior. In this skill's context pipeline, misrouting changes which memory sources and retrieval caps are applied, so ambiguous activation can expose irrelevant historical context or suppress the safer intended path.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are broad natural-language commands that can easily appear in ordinary conversation or quoted text, causing unintended execution of the memory-commit workflow. In this skill, that can lead to persistent storage of conversation content into local memory files without an explicit, high-assurance confirmation step, which is a context-integrity and privacy risk.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The document instructs the pipeline to persist multiple runtime artifacts to disk, including retrieval/context summaries and audit receipts, but it does not require any user notice, consent, retention limits, or data-minimization guarantees for persisted data. In a memory/context pipeline, these artifacts can contain sensitive prompts, retrieved snippets, metadata, and traces that increase privacy and data-exposure risk if the filesystem is accessible, backed up, or later inspected.

Vague Triggers

Medium
Confidence
82% confidence
Finding
The activation phrase is generic and reusable as a standing instruction, making it easy to invoke the skill outside a narrowly controlled setup flow. Because the skill’s longer prompt mandates file reads, routing, persistence, and potential fallback behaviors on every message, a broad trigger increases the chance of unintended application and hidden side effects.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The activation prompt goes beyond describing a context/memory runtime pipeline and instructs the operator to install software, validate it, inspect git diffs, and report command outputs. This expands the skill from passive prompting into operational repository manipulation, which can trigger unintended changes or leak repository state when reused in other contexts.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The prompt embeds shell commands that change the workspace (`install --force`, file writes via installer) and inspect repository state, even though the stated purpose is a deterministic memory/context pipeline. In an agent setting, such instructions can induce unnecessary command execution, overwrite local files, or expose sensitive repo metadata beyond what is needed for prompt routing.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The markdown provides direct commands that perform a forced install, write into the workspace, run validation scripts, and inspect repository diffs/status without clearly warning that local files may be modified. Users or agents following these instructions could alter project state or reveal repository information without understanding the consequences.

Vague Triggers

Medium
Confidence
90% confidence
Finding
Doc review routing is triggered by vague phrases like "review this" and "rewrite", which are common in normal conversation and can be matched without clear document-review intent. In this skill, that matters because routing influences derived queries and retrieval behavior, so ambiguous inputs may pull in unrelated memory or apply the wrong handling path to user content.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The router uses case-insensitive substring matching with first-match-wins semantics, and qna/planning include very broad tokens such as "why", "how do", and "plan". This can misroute ordinary conversation into higher-context retrieval paths, causing irrelevant or excessive memory inclusion and increasing the risk of unintended context exposure or incorrect workflow selection.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script captures stderr and, on JSON parse failure, a stdout preview from the subprocess, then includes those values in its JSON output. If the OpenClaw command emits secrets, filesystem paths, tokens, prompts, or sensitive memory content during errors, this watchdog will reflect that data to logs or downstream systems, causing information disclosure.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def run_json_command(command: list[str], timeout_seconds: int) -> tuple[Any | None, dict[str, Any]]:
    proc = subprocess.run(
        command,
        check=False,
        text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.