Back to skill

Security audit

Reflexlearn

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly purpose-aligned, but it can automatically write user-derived content into persistent agent behavior files without the review gate it claims to use.

Install only if you are comfortable with the skill logging prompts locally and influencing future agent behavior. Keep MODE set to cautious, disable or avoid heartbeat reinforcement until SOUL.md writes are staged for review, regularly inspect and prune ~/.openclaw/MEMORY.md, ~/.openclaw/SOUL.md, ~/.openclaw/reflex_history.json, and reflexlearn-pending.md, and prefer pinned dependencies in an isolated environment.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T02 · Agent Memory Poisoning

Error
Location
reflex_learn.py:250
Finding

Untrusted Query Content Can Poison Persistent Agent Memory and Personality State

Content
View full analysis
str: if use_ollama: body = _ollama_reflect(original, repeated, ollama_model) else: body = (f"User repeated a similar query {REPEAT_COUNT_THRESHOLD}+ times " f"(similarity={sim:.3f}).\n" f"Original: \"{original}\"\nRepeated: \"{repeated}\"\n" f"**Implication**: The previous answer did not fully satisfy the user. " f"Review and improve the response style, completeness, or factual accuracy.") append_memory(mem, f"### Reflection: Answer Improvement Needed\n\n{body}\n\n" f"**Action**: Update response strategy for queries similar to: \"{repeated}\"") key = f"improve:{_slug(repeated)}" value = (f"User repeated '{repeated[:60]}…' — previous answer was insufficient. " f"Prioritise completeness and clarity for this topic.") if MODE == "aggressive": upsert_soul_pattern(soul, key, value) else: append_pending(pending, f"### Proposed Improvement Update\n\n{body}\n\n" f"**Proposed SOUL.md entry**: `{key}`: {value}\n\n" f"To approve: move this entry to SOUL.md under `## ReflexLearn Patterns`.\n" f"To reject: delete this block.") ``` ```python def write_reinforcement(mem: Path, soul: Path, entry: dict) -> None: q = entry["query"] append_memory(mem, f"### Reinforcement: Successful Pattern\n\n" f"The answer to \"{q}\" was not repeated — the user was satisfied.\n" f"**Action ...[truncated 3396 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned Dependencies Create a Non-Reproducible Supply-Chain Risk

Content
View full analysis
=2.2.2 numpy>=1.24.0 huggingface-hub>=0.14.0 ``` ```bash # ── Step 1: Install Python dependencies ────────────────────────────────────── echo "" echo "▶ Step 1/2: Installing Python dependencies..." pip install --quiet -r "$SKILL_DIR/requirements.txt" echo " ✓ Dependencies installed." ``` ### Technical Analysis All direct dependencies use open-ended lower bounds. Running the installer therefore selects whatever newer versions and transitive dependencies are available from the configured package index at installation time. This makes installations non-reproducible and prevents the audited source tree from defining the code that will actually execute. A compromised package release, compromised transitive dependency, unsafe future version, or malicious package served through a misconfigured package index could execute with the privileges of the user running `install.sh`. The installer also invokes `pip` without creating or enforcing an isolated virtual environment, so dependencies may be installed into the active user or system Python environment. ### Attack Path 1. A direct or transitive dependency publishes a compromised or otherwise unsafe version satisfying the configured lower bound. 2. Alternatively, the host is configured to use an untrusted or compromised Python package index. 3. The user confirms and runs `install.sh`. 4. `pip` resolves the affected version because no exact version or integrity hash is required. 5. Package installation or later import executes the compromised dependency with the installing user's privileges. 6. If a shared Python environment is used, the compromised or incompatible package can also affect other local applications. ### Impact Assessment A malicious dependency can execute arbitr ...[truncated 418 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

The skill description emphasizes offline repeated-query learning, but the file also instructs users to run an install script that installs packages from PyPI and downloads model weights from Hugging Face. That mismatch is dangerous because users or orchestration systems may approve the skill under an incomplete mental model, while the actual deployment path includes supply-chain exposure and persistence-related file writes.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · example_soul_snippet.md (reported line 11)May include surrounding context.

md
## ReflexLearn Patterns

<!-- ReflexLearn will automatically append learned patterns below this line. -->
<!-- Example entries (auto-generated by ReflexLearn): -->

<!-- - **improve:write-a-python-script-to-parse-json**: User repeated 'Write a Python script to parse JSON…' — previous answer was insufficient. Prioritise completeness and clarity for this topic. -->

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README prominently advertises automatic behavioral logging and writes to MEMORY.md/SOUL.md, but it does not give a clear upfront privacy warning or require explicit consent before persisting user interaction-derived inferences. This is risky because repeated queries and inferred preferences can reveal sensitive behavioral patterns, and users may not realize their prompts are being durably recorded and used for future model behavior.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
87% confidence
Finding

The skill explicitly maintains session history, embeddings, reflections, and inferred preferences across interactions, creating persistent behavioral memory. While this is core functionality rather than obviously malicious behavior, it increases privacy risk and the chance that sensitive or adversarially induced data will accumulate and later influence responses in unintended ways.

Content

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

md
**v1.1.0** adds critical safeguards that make this production-ready:

- **Multi-repeat threshold**: Requires 2+ repeats before flagging failure (avoids false positives from natural follow-ups)
- **Modifier detection**: "Write a Python script to parse JSON **with type hints**" is treated as *preference extraction*, not failure
- **Tiered memory**: In `cautious` mode (default), SOUL.md updates are staged in `reflexlearn-pending.md` for your review before being applied
- **Aggressive mode**: For power users who want instant SOUL.md writes on first confirmed failure
- **Slash commands**: `/reflex status` and `/reflex ignore-last` for manual control

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Aggressive mode allows direct automatic modification of SOUL.md, which appears to influence persistent agent behavior, without a strong warning about integrity and prompt-manipulation risks. An attacker or even normal user interactions could steer the agent's long-term behavior by intentionally repeating crafted prompts, causing unsafe or biased rules to be written into the agent's durable instruction state.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill declares no explicit tool scope or permissions despite documented capabilities to read and write local files and to perform network activity during installation. This weakens the trust boundary for operators and automated policy systems, because a skill with persistence and install-time downloads can be invoked without a machine-readable declaration of those privileges.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The snippet explicitly tells the user to add a section to ~/.openclaw/SOUL.md and states that ReflexLearn will automatically append learned patterns there, but it does not clearly warn about the persistence, sensitivity, or behavioral impact of those writes. Because SOUL.md influences future agent behavior, silent or poorly disclosed modification can alter the assistant’s long-term responses and persist potentially sensitive user-derived inferences.

Content

No source excerpt is available for this finding.

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 · reflex_learn.py (reported line 62)May include surrounding context.

python
resolved = p.resolve()
    try: resolved.relative_to(_OPENCLAW_BASE)
    except ValueError:
        print(f"[ReflexLearn] SECURITY: refusing to write outside ~/.openclaw/: {resolved}",
              file=sys.stderr); sys.exit(1)
    return resolved

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill persistently stores full user queries and embeddings in history, then later uses that data to drive durable behavior updates. In a learning/memory skill, this creates a real semantic retention channel for secrets, personal data, credentials, or sensitive business text that users may include in prompts.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes detecting repeated queries and learning by writing local reflections and patterns. The --use-ollama path adds an extra capability to send prompts to a local HTTP service for generation, which is not necessary to perform repetition detection or local memory updates and is not disclosed in the stated purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

When --use-ollama is enabled, the code sends the original and repeated user queries verbatim to a local HTTP service without strong user-facing disclosure or minimization. Even though the destination is localhost, local model backends may log prompts or expose them to other local users/processes, creating an avoidable privacy leak.

Content

No source excerpt is available for this finding.

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · reflex_learn.py (reported line 177)May include surrounding context.

python
f"Original: {original}\nRepeated: {repeated}\n"
            f"In 2-3 sentences, identify what went wrong and suggest an improvement."
        }).encode("utf-8")
        req = urllib.request.Request("http://localhost:11434/api/generate", data=payload,
                                     headers={"Content-Type": "application/json"})
        with urllib.request.urlopen(req, timeout=15) as resp:
            return json.loads(resp.read().decode("utf-8")).get("response", "").strip()

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Memory, pending, and SOUL entries explicitly embed original user text in plain language, turning transient prompts into long-lived semantic instructions and records. This increases both privacy risk and prompt-poisoning risk, because malicious or sensitive user text can be preserved and influence future behavior beyond the original interaction.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes continuous learning by writing reflections and patterns to MEMORY.md and SOUL.md. In the default cautious mode, preference updates are written to MEMORY.md plus a separate pending review file, not to SOUL.md, which means the implemented behavior is narrower and different from the stated write target.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

Heartbeat mode automatically writes positive reinforcement derived from user queries into SOUL.md without a review gate, creating persistent self-modification from implicit signals. In this skill’s context, SOUL.md appears to influence future behavior, so silently promoting user-derived content into long-lived guidance can be abused for prompt/data poisoning and persistence.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency is specified with a lower-bound only version constraint, which permits installation of any newer release. This harms build reproducibility and can unintentionally introduce vulnerable or breaking upstream versions through normal installs or future rebuilds.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
sentence-transformers>=2.2.2
numpy>=1.24.0
huggingface-hub>=0.14.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The unpinned numpy requirement allows different environments to resolve to different versions, including versions later found to contain security defects. In a skill that continuously learns and may run repeatedly, non-deterministic dependency resolution increases supply-chain and maintenance risk over time.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
sentence-transformers>=2.2.2
numpy>=1.24.0
huggingface-hub>=0.14.0

Unverifiable Dependency: numpy has 16 known advisory(ies) (CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
82% confidence
Finding

The manifest does not pin numpy, and numpy has multiple known advisories across historical releases, so it is impossible to determine from this file alone whether an affected version may be installed. This creates uncertainty around exposure and makes vulnerability management weaker, even though the file does not prove a specific CVE is present.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The huggingface-hub dependency is not pinned, so future installations may silently pull newer releases with changed behavior or newly introduced issues. Because this skill's context references model-related functionality, dependency drift in this package can affect network/model-fetch code paths and increase supply-chain exposure.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
sentence-transformers>=2.2.2
numpy>=1.24.0
huggingface-hub>=0.14.0

Static analysis

No suspicious patterns detected.