Back to skill

Security audit

Memory Consolidate

Security checks for vulnerabilities and agentic risk

Overview

This memory skill is mostly coherent, but it can send persistent memory to a configurable LLM endpoint and load that model-generated text into future sessions without enough safeguards.

Install only if you intentionally want an automated, persistent memory system that stores summaries in your OpenClaw workspace, runs on a schedule, injects MEMORY_SNAPSHOT.md into future sessions, and may send selected memory content to your configured LLM provider. Use a trusted HTTPS endpoint, a dedicated low-privilege API key, review generated snapshots before enabling session injection, and avoid enabling the cron or semantic step for workspaces containing secrets or sensitive client data.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/memory_semantic_consolidate.py:38
Finding

Private memory content and API credentials can be transmitted to an arbitrary endpoint

Content
View full analysis
Dict[str, str]: """Load Anthropic API config from openclaw.json tui provider.""" base_url = os.environ.get("ANTHROPIC_BASE_URL", "") api_key = os.environ.get("ANTHROPIC_API_KEY", "") model = os.environ.get("SEMANTIC_LLM_MODEL", "claude-haiku-4-5-20251001") if not base_url or not api_key: try: cfg_path = Path.home() / ".openclaw" / "openclaw.json" cfg = json.loads(cfg_path.read_text("utf-8")) tui = cfg.get("models", {}).get("providers", {}).get("tui", {}) if not base_url: base_url = tui.get("baseUrl", "") if not api_key: api_key = tui.get("apiKey", "") except Exception: pass return {"base_url": base_url.rstrip("/"), "api_key": api_key, "model": model} def _call_anthropic(prompt: str, system: str, cfg: Dict[str, str]) -> Optional[str]: """Call Anthropic Messages API. Returns assistant text or None on failure.""" url = f"{cfg['base_url']}/v1/messages" body = json.dumps({ "model": cfg["model"], "max_tokens": 4096, "system": system, "messages": [{"role": "user", "content": prompt}], }).encode("utf-8") headers = { "Content-Type": "application/json", "x-api-key": cfg["api_key"], "anthropic-version": "2023-06-01", } try: req = Request(url, data=body, headers=headers, method="POST") with urlopen(req, timeout=60) as resp: data = json.loads(resp.read().decode("utf-8")) for block in data.get("content", []): if block.get("type") == "text": return block["text"] except Exception as exc: print(f"[semantic] LLM call fa ...[truncated 3601 chars]
Remediation
View remediation

T02 · Agent Memory Poisoning

Error
Location
scripts/memory_semantic_consolidate.py:137
Finding

Untrusted LLM output can poison the persistent snapshot injected into future sessions

Content
View full analysis
Optional[Dict[str, Any]]: """Extract sections dict and user_traits from LLM response.""" # Strip markdown fences if present cleaned = re.sub(r"^```(?:json)?\s*\n?", "", raw.strip()) cleaned = re.sub(r"\n?```\s*$", "", cleaned) try: data = json.loads(cleaned) if isinstance(data, dict): result = data.get("sections", {}) # Attach user_traits at top level for caller to extract if "user_traits" in data: result["__user_traits__"] = data["user_traits"] return result except json.JSONDecodeError: pass return None ``` Returned text receives only basic type, emptiness, item-count, and character-length checks: ```python if raw_response: parsed = _parse_llm_response(raw_response) if parsed: used_llm = True for key, limits in SECTION_LIMITS.items(): items = parsed.get(key, []) if not isinstance(items, list): continue cleaned = [] for idx, item in enumerate(items[:limits["items"]]): text = str(item.get("text") or "") if isinstance(item, dict) else str(item) text = text.strip() if not text: continue if len(text) > limits["chars"]: text = text[:limits["chars"] - 1] + "…" cleaned.append({ "rank": idx + 1, ...[truncated 4970 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

This mismatch is more severe because the documented purpose omits that the skill sends data to an external Anthropic-compatible API using configured credentials. Undeclared external network transmission in a memory-related skill can expose sensitive session-derived content and credentials context, while users may believe the tool is only performing local consolidation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

This mismatch is more severe because the documented purpose omits that the skill sends data to an external Anthropic-compatible API using configured credentials. Undeclared external network transmission in a memory-related skill can expose sensitive session-derived content and credentials context, while users may believe the tool is only performing local consolidation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill requests or implies powerful capabilities (environment access, file read/write, shell, and network via external API use) but does not declare an explicit tool scope or permissions boundary. This is dangerous because users and the hosting agent cannot reliably constrain what the skill may do, increasing the chance of over-privileged execution, data exfiltration, or unintended system modification during installation and operation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The activation rules are unusually broad and include many generic phrases about memory issues, making the skill likely to trigger in situations where the user did not intend to authorize file, config, cron, or network-affecting guidance. In context, this increases risk because the skill also recommends persistent system modifications and may route memory-related content into external processing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs the agent/user to patch configuration, inject a file into every session, and install a daily cron job, all of which create persistent system changes and ongoing automated execution. Without an explicit warning and consent checkpoint, this can lead to surprise persistence, repeated processing of sensitive logs, and long-lived changes that are hard for users to notice or undo.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script serializes extracted memory candidates and writes them to both a latest file and a timestamped history file, creating persistent on-disk copies of potentially sensitive session-derived content. In a memory-consolidation skill, this is especially risky because the data source is agent session logs and extracted facts/decisions, which can include secrets, personal data, internal project details, or operational context; history retention also multiplies exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README explicitly states that the skill reads daily logs and session transcripts and later injects a generated memory snapshot into every session, but it does not prominently warn users that sensitive data from conversations and workspace files may be collected, retained, summarized, and resurfaced automatically. In a persistent memory system, this creates a real privacy and data-minimization risk because secrets, personal data, or sensitive project context may be unintentionally ingested and propagated across future sessions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README documents automatic extraction of identity information from IDENTITY.md and USER.md without an explicit warning or consent flow. This is dangerous because identity attributes such as owner name, timezone, and language can be silently harvested from workspace files and then used in generated memory artifacts, increasing the chance of privacy leakage and unintended exposure in downstream agent context.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The activation criteria are unusually broad and include many generic phrases about memory being stale, missing, broken, or needing optimization. This can cause the skill to trigger in contexts where the user did not intend persistent memory operations, increasing the chance of unnecessary access to session logs and accidental modification of long-lived memory artifacts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the agent to patch runtime configuration to inject MEMORY_SNAPSHOT.md into every session and to install a daily cron job, both of which create persistent behavior changes. Without an explicit warning and user confirmation, this can silently establish ongoing data collection, recurring automation, and broad propagation of potentially sensitive memory content across future sessions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The summary content is prefixed with the fixed Chinese string "归档回流[{label}]:", which forces a specific language in generated output. The file does not offer a language choice or document a justified region-specific constraint, so this is a natural-language locale policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code sets a default owner_language of English, which imposes a specific language preference whenever IDENTITY.md or USER.md do not provide one. The policy for this category prohibits forcing a language or locale unless the user is given a choice or the constraint is clearly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The normalization logic rewrites multiple English and Chinese prefixes into fixed Chinese labels such as "问题:", "决策:", and "方案:", and also prepends those Chinese labels when none are present. This is a natural-language locale policy concern because the file forces Chinese output conventions rather than preserving the user's original language or offering a language choice.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The function accepts caller-supplied agent IDs and constructs paths to sibling agents' session directories, then enumerates recent session logs from each. In a memory-consolidation skill, those logs can contain sensitive user and assistant content, so broad cross-agent access expands the data exposure boundary beyond the current agent unless strict authorization and scoping are enforced elsewhere.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code parses session JSONL files and extracts text from user and assistant messages for later processing, which is effectively surveillance of conversation content. In the context of persistent memory generation, that creates privacy risk and potential secret retention because users may not realize their full message text is being harvested and transformed into durable memory.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This Python file performs many persistent writes, including replacing active memory files, archive files, snapshot files, health/status files, and state data. While the module docstring describes consolidation at a high level, there is no user-facing disclosure such as logging, print output, or confirmation that these files will be modified, and the operations include purging/archive behavior that can materially affect retained data.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/memory_consolidate/pipeline.py (reported line 51)May include surrounding context.

python
status["steps"].append(step)
            break
        try:
            completed = subprocess.run(
                ["python3", str(script_path)],
                cwd=str(WORKSPACE),
                check=True,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes a persistent memory workflow that reads logs, extracts knowledge, manages lifecycle, and renders a snapshot. Spawning external Python interpreters to run multiple scripts is a broader capability than the stated memory-purpose operations and introduces general command-execution behavior that is not explicitly justified by the manifest text.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The generated snapshot hardcodes English section headings and user-facing labels such as 'User', 'Prefers', 'Timezone', and multiple English section titles. This creates a locale-policy concern because the skill emits a fixed language regardless of the user's preferred language, even though a language preference field is available.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script reads API credentials from the user's global OpenClaw config when environment variables are absent, which grants this skill access to a broader trust domain than its own local function requires. In a memory-consolidation context, this creates an unnecessary secret-access path and can enable unintended external use of the user's provider credentials if the skill is run without explicit per-skill configuration.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code sends memory candidate content to an external Anthropic-compatible endpoint over HTTP(S), which may include sensitive session-derived facts, decisions, and user traits. Because the endpoint is configurable via environment or global config, this creates a real exfiltration path for persistent memory data to a remote service outside the local memory processor's expected boundary.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill transmits memory-candidate data to a remote endpoint without any explicit user-facing warning or consent mechanism in the code path. Since this skill processes persistent memory derived from session logs, lack of disclosure increases the risk of silent exposure of sensitive personal or operational data.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The manifest describes a persistent memory system that reads session logs, extracts memories, manages lifecycle, and generates MEMORY_SNAPSHOT.md. In this config module, the skill also parses IDENTITY.md and USER.md to extract assistant and owner identity details, which goes beyond straightforward memory-consolidation configuration and log processing as described.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The docstring explicitly constrains pattern handling to Chinese and English only. That is a natural-language locale limitation, and the file does not indicate user opt-in, configurability, or a documented region-specific justification for excluding other languages.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The generated summary text is hard-coded in Chinese, which forces one language for user-visible output regardless of user preference or environment. The file does not offer a locale choice or document that the skill is intentionally limited to a Chinese-language context.

Content

No source excerpt is available for this finding.