Back to skill

Security audit

Learnings Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its learning-memory purpose, but it handles workspace memory and credentials with under-scoped network and persistence controls that users should review carefully.

Install only if you trust the workspace .env file and the MeiliSearch endpoint. Prefer a localhost-only MeiliSearch instance with a scoped key, review extracted entries before using --apply, avoid storing secrets or personal data in learnings, and treat retrieved learnings as advisory notes rather than instructions that can override current user or safety requirements.

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
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
lib/config.sh:12
Finding

Executable Workspace Environment File Enables Arbitrary Code Execution

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
lib/config.sh:20
Finding

Unrestricted MeiliSearch Destination Can Expose Credentials and Workspace Memory

Content
View full analysis
&2 exit 1 fi export MEILI_HOST MEILI_KEY ``` ```python for fname in sorted(glob.glob(f"{daily_dir}/*.md")): try: file_date = datetime.strptime(os.path.basename(fname)[:10], "%Y-%m-%d") except: continue if file_date < cutoff: continue with open(fname, "r") as f: content = f.read() ``` ```python if found and not dry_run: logged = 0 for item in found: doc_id = f"auto-{datetime.now().strftime('%Y%m%d')}-{hash(item['text']) % 10000:04d}" doc = [{ "id": doc_id, "category": item["category"], "what_happened": item["text"], "fix": "(auto-extracted)", "context": f"From {item['source']}", "importance": 0.6, "tags": ["auto-extracted", f"category/{item['category']}", f"date/{item['date']}"], "date": item["date"], "source": "auto_extract" }] doc_file = tempfile.mktemp(prefix='learn-auto-', suffix='.json') os.chmod(doc_file, 0o600) with open(doc_file, "w") as f: json.dump(doc, f) subprocess.run([ "curl", "-s", "-X", "POST", f"{ms_host}/indexes/learnings/documents", "-H", f"Authorization: Bearer {ms_key}", "-H", "Content-Type: application/json", "-d", f"@{doc_file}" ], capture_output=True) os.unlink(doc_file) logged += 1 ``` ### Technical Analysis The documentation declares localhost ...[truncated 1963 chars]
Remediation
View remediation
` or an explicitly approved Unix socket. - Parse the URL and validate the scheme, hostname, port, user-information component, and resolved IP address. - Reject redirects or use `curl --max-redirs 0` so an approved local URL cannot redirect credentials elsewhere. - Require explicit, informed configuration and confirmation before permitting remote MeiliSearch instances. - Use a narrowly scoped API key instead of a MeiliSearch master key. - Implement structured redaction and data classification rather than relying only on a small regex list. - Require user review of extracted entries before transmission. - Set connection and total timeouts, use `--fail-with-body`, and verify response status. - If remote operation is required, enforce HTTPS with certificate verification and do not permit plaintext transmission. ]]>

T02 · Agent Memory Poisoning

Error
Location
scripts/auto_extract.sh:103
Finding

Untrusted Note Content Can Poison Persistent Agent Learnings

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/auto_extract.sh:154
Finding

Non-Atomic Temporary File Handling Enables Race Conditions and Extraction Failure

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a functional skill that continuously learns from mistakes, stores corrections, and manages its own MeiliSearch index. The supplied code does not implement any of that behavior. It only loads environment configuration for MeiliSearch access and exports credentials for other scripts. While configuration loading could support such a skill, this chunk’s actual purpose is materially different from the declared primary purpose, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The description presents a capability centered on continuous learning: logging mistakes, preventing repetition, and learning rules/preferences/behavioral corrections using its own MeiliSearch index. The supplied code only retrieves existing records from the learnings MeiliSearch index, prints summary statistics, and optionally generates a markdown document (LEARNINGS.md). There is no logic to capture new failures, store corrections, adapt behavior, infer rules, or prevent repetition. While use of a MeiliSearch index is consistent, the primary implemented behavior is distillation/reporting, not continuous learning or logging, so this is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · lib/config.sh (reported line 11)May include surrounding context.

sh
WORKSPACE="/root/.openclaw/workspace"
fi

# Load .env if it exists
ENV_FILE="${WORKSPACE}/.env"
if [ -f "$ENV_FILE" ]; then
  set -a

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

This script sources ${WORKSPACE}/.env directly into the shell, which executes any shell code contained in that file rather than safely parsing key-value pairs. If an attacker can modify WORKSPACE or the .env file, they can achieve arbitrary command execution in the context of any script that sources this config, and the learning skill's persistent/shared workspace makes that especially dangerous.

Content

Scanner excerpt · lib/config.sh (reported line 12)May include surrounding context.

sh
fi

# Load .env if it exists
ENV_FILE="${WORKSPACE}/.env"
if [ -f "$ENV_FILE" ]; then
  set -a
  source "$ENV_FILE"

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/setup_index.sh (reported line 32)May include surrounding context.

sh
sleep 1

# Configure settings
curl -s -X PATCH "${MEILI_HOST}/indexes/${INDEX}/settings" \
  -H "Authorization: Bearer ${MEILI_KEY}" \
  -H "Content-Type: application/json" \
  -d '{

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README explicitly promotes continuous logging of failures, corrections, patterns, and user preferences, but provides no warning, consent model, retention limits, or guidance on avoiding sensitive data collection. In an agent skill context, these logs can easily capture secrets, personal data, operational history, and behavioral profiles, creating a privacy and data-handling risk if the information is stored, indexed, or later queried without controls.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares executable, read, and write capabilities in prose but does not define an explicit tool scope such as permissions or allowed-tools. That creates an authorization ambiguity where an agent runtime may grant broader access than reviewers expect, especially since the skill reads local notes, loads secrets from ~/.openclaw/workspace/.env, writes files, and invokes shell commands.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 15)May include surrounding context.

md
- **Credentials**: MeiliSearch key is loaded from `~/.openclaw/workspace/.env` — never hardcoded in scripts
- **Sensitive data filtering**: Auto-extraction skips content containing tokens, passwords, API keys, and credentials
- **Safe defaults**: Distillation and auto-extract default to `--dry-run`; use `--apply` to write
- **Secure temp files**: All temp files use `mktemp` with `chmod 600` and are cleaned up on exit

## Capabilities (declared)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/distill_learnings.sh (reported line 30)May include surrounding context.

sh
- **Credentials**: MeiliSearch key is loaded from `~/.openclaw/workspace/.env` — never hardcoded in scripts
- **Sensitive data filtering**: Auto-extraction skips content containing tokens, passwords, API keys, and credentials
- **Safe defaults**: Distillation and auto-extract default to `--dry-run`; use `--apply` to write
- **Secure temp files**: All temp files use `mktemp` with `chmod 600` and are cleaned up on exit

## Capabilities (declared)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/log_learning.sh (reported line 43)May include surrounding context.

sh
- **Credentials**: MeiliSearch key is loaded from `~/.openclaw/workspace/.env` — never hardcoded in scripts
- **Sensitive data filtering**: Auto-extraction skips content containing tokens, passwords, API keys, and credentials
- **Safe defaults**: Distillation and auto-extract default to `--dry-run`; use `--apply` to write
- **Secure temp files**: All temp files use `mktemp` with `chmod 600` and are cleaned up on exit

## Capabilities (declared)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/search_learnings.sh (reported line 24)May include surrounding context.

sh
- **Credentials**: MeiliSearch key is loaded from `~/.openclaw/workspace/.env` — never hardcoded in scripts
- **Sensitive data filtering**: Auto-extraction skips content containing tokens, passwords, API keys, and credentials
- **Safe defaults**: Distillation and auto-extract default to `--dry-run`; use `--apply` to write
- **Secure temp files**: All temp files use `mktemp` with `chmod 600` and are cleaned up on exit

## Capabilities (declared)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This script collects text from local daily notes and, when run with --apply, posts the extracted content to a MeiliSearch service without any explicit confirmation at send time or clear disclosure that note contents may leave the local context. The built-in sensitive-data filter is heuristic and incomplete, so private or regulated information in notes could still be exfiltrated to a remote index, especially given this skill’s purpose is to mine behavioral corrections and past mistakes from personal workspace memory.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/setup_index.sh (reported line 17)May include surrounding context.

sh
# Wait for MeiliSearch
for i in $(seq 1 10); do
  if curl -s "${MEILI_HOST}/health" > /dev/null 2>&1; then break; fi
  sleep 1
done

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/setup_index.sh (reported line 32)May include surrounding context.

sh
sleep 1

# Configure settings
curl -s -X PATCH "${MEILI_HOST}/indexes/${INDEX}/settings" \
  -H "Authorization: Bearer ${MEILI_KEY}" \
  -H "Content-Type: application/json" \
  -d '{

Static analysis

No suspicious patterns detected.