Back to skill

Security audit

Reflexio

Security checks for vulnerabilities and agentic risk

Overview

This memory plugin is not clearly malicious, but it automatically stores long-term conversation memory and mutates persistent workspace instructions in ways users should review carefully.

Install only if you want an agent to build durable memory from conversations. Before enabling it, review the HEARTBEAT.md modification, active-memory scope, plaintext .reflexio storage, full-transcript extraction, and automatic consolidation/deletion behavior. Avoid using it in sessions that may contain secrets until deterministic redaction, path containment, and user-visible review/delete controls are added.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (4)

T06 · System Persistence

Warning
Location
hook/setup.ts:33
Finding

Automatic Persistent Modification of Workspace Instructions

Content
View full analysis
{ try { setupWorkspaceResources(pluginDir); } catch (err) { log.error?.(`[reflexio-embedded] workspace setup failed: ${err}`); } try { await ttlSweepProfiles(resolveWorkspaceDir()); } catch (err) { log.error?.(`[reflexio-embedded] ttl sweep failed: ${err}`); } return { prependSystemContext: injectBootstrapReminder(), }; }); ``` ### Technical Analysis The plugin rewrites the persistent workspace `HEARTBEAT.md` file automatically whenever the `before_prompt_build` event runs. The appended content configures a recurring call to `reflexio_consolidation_check`. The same hook also injects Reflexio instructions into every system prompt. This behavior is not protected by an explicit user-consent check, an installation marker, or a configuration option. Although plugin act ...[truncated 1479 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
lib/io.ts:65
Finding

Sensitive Data Can Be Persisted Without Code-Level Redaction

Content
View full analysis
0) { lines.push(`supersedes: [${opts.supersedes.join(", ")}]`); } lines.push("---", "", opts.body, ""); try { fs.writeFileSync(tmpPath, lines.join("\n")); fs.renameSync(tmpPath, filePath); } catch (err) { try { fs.unlinkSync(tmpPath); } catch {} throw err; } return filePath; } ``` The playbook writer has the same behavior: ```ts lines.push("---", "", opts.body, ""); try { fs.writeFileSync(tmpPath, lines.join("\n")); fs.renameSync(tmpPath, filePath); } catch (err) { try { fs.unlinkSync(tmpPath); } catch {} throw err; } ``` ### Technical Analysis The Skill and extraction prompts instruct the model not to store secrets, but the enforcement exists only in natural-language instructions. The registered tools accept arbitrary `body` values and pass them to file-writing functions without credential detection, redaction, PII checks, content-size limits, or confirmation. Natural-l ...[truncated 1699 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
lib/write-profile.ts:62
Finding

Untrusted Memory Search Paths Can Cause File Deletion Outside the Memory Directory

Content
View full analysis
{ let results = await memorySearch(query, maxResults, runner); if (type) { const typeDir = type === "profile" ? "/profiles/" : "/playbooks/"; results = results.filter((r) => r.path.includes(typeDir)); } return results; } ``` The deletion primitive unlinks the supplied path directly: ```ts export function deleteFile(filePath: string): void { try { fs.unlinkSync(filePath); } catch (err: any) { if (err.code !== "ENOENT") throw err; console.error(`[reflexio] warning: file already gone: ${filePath}`); } } ``` ### Technical Analysis The plugin treats a path returned by `openclaw memory search` as an authorized deletion target. The only path-related filter verifies that the string contains `/profiles/` or `/playbooks/`. It does not canonicalize the path, reject `..` components, reject absolute paths, resolve symbolic links, or verify containment beneath the expected `.reflexio` directory. Absolute search-result paths are passed directly to `unlinkSync`. Relative paths are concatenated with the workspace using string interpolation instead of secure path resolution and containment validat ...[truncated 1506 chars]
Remediation
View remediation

T02 · Agent Memory Poisoning

Error
Location
lib/consolidate.ts:178
Finding

Prompt Injection in Stored Memory Can Control Persistent Writes and Destructive Consolidation

Content
View full analysis
f.id).join(", ")}`); const prompt = CONSOLIDATION_PROMPT.replace("{cluster}", formatCluster(cluster)); const llmResult = await opts.inferFn(prompt); if (!llmResult) { console.error(`[reflexio] consolidation: inferFn returned empty for cluster, skipping`); continue; } let decision: LlmConsolidationResult; try { decision = JSON.parse(llmResult); } catch (err) { console.error(`[reflexio] consolidation: JSON parse failed: ${err}, skipping cluster`); continue; } console.info(`[reflexio] consolidation: decision="${decision.action}" rationale="${(decision.rationale ?? "").slice(0, 100)}"`); if (decision.action === "keep_all") continue; if (decision.action === "consolidate" && decision.facts && decision.ids_to_delete) { // Build id→file lookup for deletion const idToFile = new Map(cluster.map((f) => [f.id, f])); // Write new fact files for (const fact of decision.facts) { if (type === "profile") { const sourceFiles = (fact.source_ids ?? []).map((id) => idToFile.get(id)).filter((f): f is FileEntry => f !== undefined); const ttl = sourceFiles.length > 0 ? pickSmallestTtl(sourceFiles) : pickSmallestTtl(cluster); const supersedes = fact.source_ids?.filter((id) => idToFile.has(id)); writeProfileFile({ slug: fact.slug, ttl, body: fact.body, supersedes, workspace: opts.workspaceDir }); result.filesWritten++; } else { const supersedes = fact.source_ids?.filter((id) => idToFile.has(id)) ...[truncated 3525 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (32)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · README.md (reported line 42)May include surrounding context.

md
openclaw plugins uninstall --force reflexio-embedded

# 2. Clean up state files
rm -f ~/.openclaw/reflexio-consolidation-state.json

# 3. Restart the gateway
openclaw gateway restart

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

rm -rf .reflexio/ is a forceful recursive deletion command that removes all persisted user memory for the skill. In this context, .reflexio/ contains user profiles and playbooks accumulated across sessions, so misuse, copy-paste execution from the wrong directory, or misunderstanding of consequences can cause irreversible loss of data.

Content

Scanner excerpt · README.md (reported line 51)May include surrounding context.

Your .reflexio/ user data (profiles and playbooks) is preserved by default. To remove it:

bash
rm -rf .reflexio/

What it does

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

A skill that can delete or rewrite stored memory files while presenting itself primarily as simple capture/retrieval introduces integrity risk. Users may believe memories are only stored and recalled, while the system can silently consolidate, expire, or remove prior records, which can destroy auditability and alter long-term agent behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

A skill that can delete or rewrite stored memory files while presenting itself primarily as simple capture/retrieval introduces integrity risk. Users may believe memories are only stored and recalled, while the system can silently consolidate, expire, or remove prior records, which can destroy auditability and alter long-term agent behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

A skill that can delete or rewrite stored memory files while presenting itself primarily as simple capture/retrieval introduces integrity risk. Users may believe memories are only stored and recalled, while the system can silently consolidate, expire, or remove prior records, which can destroy auditability and alter long-term agent behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

A skill that can delete or rewrite stored memory files while presenting itself primarily as simple capture/retrieval introduces integrity risk. Users may believe memories are only stored and recalled, while the system can silently consolidate, expire, or remove prior records, which can destroy auditability and alter long-term agent behavior.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

Session-end extraction from the full transcript is a significant privacy risk because it enables bulk mining and persistence of everything discussed, not just explicitly approved memory items. This broadens collection beyond clear user intent and can capture sensitive data, mistakes, and transient context into long-lived storage.

Content

No source excerpt is available for this finding.

Ssd 1

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Untrusted profile/playbook contents are interpolated directly into the consolidation prompt, so any previously stored text can inject instructions to the model such as deleting files, fabricating facts, or overriding consolidation rules. Because this skill persists memory across sessions, a single poisoned memory entry can influence later consolidation runs and lead to durable corruption or loss of agent memory.

Content

No source excerpt is available for this finding.

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

md
2. If the information is already captured in existing profiles (see below), do NOT re-extract it.
3. Always include `ttl` for new profiles; pick the shortest TTL that the fact will plausibly remain true for.
4. Never output behavioral rules for the agent here — those belong to the playbook extractor.
5. **Never extract secrets or credentials.** Do not create profile entries for API keys, access tokens, passwords, OAuth secrets, private keys, auth headers, `.env` values, connection strings, or any other credential-shaped content, even if the user pasted such content into the conversation. Treat those as noise; skip them.
6. Return `[]` when there is nothing new to extract.

## Existing profiles for context (do NOT re-extract these)

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 · prompts/profile_extraction.md (reported line 122)May include surrounding context.

md
2. If the information is already captured in existing profiles (see below), do NOT re-extract it.
3. Always include `ttl` for new profiles; pick the shortest TTL that the fact will plausibly remain true for.
4. Never output behavioral rules for the agent here — those belong to the playbook extractor.
5. **Never extract secrets or credentials.** Do not create profile entries for API keys, access tokens, passwords, OAuth secrets, private keys, auth headers, `.env` values, connection strings, or any other credential-shaped content, even if the user pasted such content into the conversation. Treat those as noise; skip them.
6. Return `[]` when there is nothing new to extract.

## Existing profiles for context (do NOT re-extract these)

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 · skills/reflexio-embedded/SKILL.md (reported line 173)May include surrounding context.

md
2. If the information is already captured in existing profiles (see below), do NOT re-extract it.
3. Always include `ttl` for new profiles; pick the shortest TTL that the fact will plausibly remain true for.
4. Never output behavioral rules for the agent here — those belong to the playbook extractor.
5. **Never extract secrets or credentials.** Do not create profile entries for API keys, access tokens, passwords, OAuth secrets, private keys, auth headers, `.env` values, connection strings, or any other credential-shaped content, even if the user pasted such content into the conversation. Treat those as noise; skip them.
6. Return `[]` when there is nothing new to extract.

## Existing profiles for context (do NOT re-extract these)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README documents a recursive deletion of .reflexio/, which the text identifies as user data containing profiles and playbooks, but it does not explicitly warn that this permanently removes learned memory. In an agent-skill context centered on persisting user facts across sessions, omission of a strong warning increases the chance of accidental destructive use and loss of potentially important user state.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
80% confidence
Finding

The skill instructs use of exec, config mutation, and filesystem writes but declares no explicit tool scope or allowed-tools boundary. That creates a privilege/transparency gap: an agent may invoke more capability than a reviewer expects, increasing the chance of unintended command execution or environment exposure.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The core design persists user facts and corrections across sessions, creating an inherent privacy and data minimization risk even if external services are not used. Cross-session natural-language memory can retain sensitive personal or organizational information longer than necessary and make it retrievable in future contexts.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The setup section says that if active-memory is declined, the agent 'must run openclaw memory search via exec at turn start' and also frames exec fallback/manual commands as part of operation. Later, the Retrieval section explicitly says 'Do NOT use ... exec with openclaw memory search — use the reflexio_search tool instead,' which is a direct contradiction in documented intent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The capture triggers are broad enough to match ordinary conversation, so the agent may persist more personal data than the user intended across sessions. In a memory skill, over-collection is especially risky because retention compounds privacy exposure and can surface sensitive context later in unrelated conversations.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Using the user's full message as the retrieval query at each turn increases the chance that sensitive current inputs will be semantically matched against prior stored data and reused broadly. That can amplify privacy leakage and cause unrelated or stale memories to be surfaced in contexts where the user did not expect cross-session recall.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This skill persistently stores extracted profiles and playbooks from conversation transcripts into .reflexio/, but the description and workflow do not require an explicit user-facing warning or consent before creating durable memory entries. That creates a real risk of unintended retention of sensitive personal, operational, or incorrect transcript content across sessions, especially because the skill is designed to run on ordinary user preferences and corrections.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The header comments say no workspace file copying is needed and imply behavior remains within the extension directory, but the code actually writes into the user’s workspace HEARTBEAT.md. This discrepancy is security-relevant because it conceals persistent cross-session modification of operational context, undermining reviewer and user trust and making unauthorized behavior harder to detect.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The setup hook writes to a workspace-level HEARTBEAT.md even though the skill’s stated purpose is to persist data under .reflexio/. Modifying a shared workspace control/instruction file expands the skill’s influence beyond its declared scope and can silently inject persistent agent guidance that affects future sessions or other skills.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The plugin exposes api.runtime.system.runCommandWithTimeout as runner and passes it into multiple memory-management paths (writeProfile, writePlaybook, search, and consolidation), giving the skill a general-purpose command execution primitive beyond simple persistence. In a memory-capture skill, that expands the trusted computing base significantly: if downstream code constructs shell commands from model-derived or user-influenced data, the plugin can execute arbitrary local commands in the agent environment, turning transcript processing into a host-execution path.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code accepts LLM output and directly uses it to create new memory files and delete existing ones, with no confirmation step, schema hardening, or policy checks tying deletions to safe provenance. In this skill, the stored '.reflexio' memory influences future agent behavior across sessions, so a bad or manipulated consolidation response can silently poison long-term memory or erase valid constraints and preferences.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The function sends raw user text to an external inference function for preprocessing, and this skill is explicitly designed to capture persistent user facts, preferences, configs, and corrections—data that may include sensitive or identifying information. Because there is no consent gate, redaction step, locality guarantee, or clear restriction that inferFn must be on-device, this creates a real privacy and data-exfiltration risk rather than a purely theoretical concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The deduplication path transmits both newly captured content and previously stored memory content to the inference function, compounding exposure by sending historical and fresh sensitive data together. In the context of a long-term memory skill, this is especially dangerous because stored snippets may contain accumulated private facts, credentials, or operational details, and the code applies no minimization, sanitization, or user-facing warning before disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code deletes an existing file as part of the merge flow, but the only disclosure is an internal console log after the deletion occurs. There is no confirmation prompt or explicit user warning at the point of the destructive action, and the operation is not clearly surfaced beyond implementation comments.

Content

No source excerpt is available for this finding.