Back to skill

Security audit

Memory Feedback

Security checks for vulnerabilities and agentic risk

Overview

The skill is purpose-aligned but needs review because it automatically stores sensitive accounting interaction data and uses it to propose persistent skill changes.

Install only in a controlled OpenClaw deployment after treating /data/memory as sensitive accounting data. Add redaction or pseudonymization for AFMs, usernames, raw queries, command lines, and correction text; set finite retention for derived records; restrict filesystem access; clarify GitHub token handling; and require security review for proposals that affect permissions, confirmations, data disclosure, or tool use.

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

Warning
Location
SKILL.md:149
Finding
Unrestricted Collection and Indefinite Retention of Sensitive Interaction Data<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:149-176`, `SKILL.md:371-394`, and `SKILL.md:437-441` **Vulnerability Type**: Sensitive data exposure and excessive data retention **Risk Level**: Medium ### Vulnerable Code ```json { "episode_id": "EP-20260218-001", "session_id": "S20260218-001", "user": "maria.g", "timestamp_utc": "2026-02-18T09:14:32Z", "skill": "greek-financial-statements", "action_type": "statement_generated", "client_afm": "EL123456789", "period": "2026-01", "commands_called": [ "openclaw statements check-ready --afm EL123456789 --period 2026-01", "openclaw statements generate --afm EL123456789 --period 2026-01 --type all" ], "human_confirmation_required": false, "outcome": "success", "result_summary": "Full statement pack generated. P&amp;L, balance sheet, cash flow, VAT summary. v1 issued.", "tokens_used": 1240, "duration_seconds": 31 } ``` ```json { "failure_id": "FAIL-20260218-003", "episode_id": "EP-20260218-003", "session_id": "S20260218-001", "user": "maria.g", "timestamp_utc": "2026-02-18T11:22:14Z", "skill": "conversational-ai-assistant", "failure_type": "intent_misread", "user_query": "Send the January summary to Alpha Trading", "agent_action_taken": "Attempted openclaw comms send — skill not yet available", "what_went_wrong": "Agent tried to send client communication directly. Skill 16 not deployed at time of query.", "what_should_have_happened": "Recognise outgoing communication unavailable. Draft the summary text. Inform user it needs manual sending.", "human_correction_provided": true, "human_correction_text": "Just write the summary text and tell me to send it manually", "pattern_candidate": true, "skill_improvement_candidate": "14-conversational-ai-assistant", "proposed_change_summary": "Add scope boundary: if comms send requested and Skill 16 unavailable, draft content and state manual sending required" } ``` ```yaml patterns: path: " ...[truncated 3791 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Adopt an explicit allowlist of fields that may be logged. Do not store raw prompts, full command lines, correction text, or result content unless strictly necessary. 2. Replace direct identifiers such as usernames and client tax identifiers with scoped pseudonymous identifiers. Store any re-identification mapping separately with stricter access controls. 3. Add a mandatory redaction stage before every write. It should remove credentials, access tokens, tax identifiers, banking information, personal data, and confidential document content. 4. Encrypt memory records at rest using managed keys separate from the data directory. 5. Require restrictive filesystem permissions and a dedicated service account. Other skills should receive append-only access where feasible, while only the memory processor receives read access. 6. Apply finite retention periods to corrections, patterns, and proposals. Derived records should be deleted when their source records expire unless a documented legal or operational requirement justifies continued retention. 7. Distinguish archival from deletion and implement verifiable deletion from active storage and backups. 8. Add per-field provenance so derived artifacts can be located and removed when a user or client record must be deleted. 9. Require explicit configuration and organizational approval before enabling cross-skill collection. 10. Add automated tests proving that representative tax identifiers, tokens, bank details, and personal information are redacted before persistence. ]]>

T02 · Agent Memory Poisoning

Warning
Location
SKILL.md:188
Finding
Untrusted Interaction Records Can Influence Persistent Skill Instructions<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:188-234` and `SKILL.md:252-283` **Vulnerability Type**: Persistent memory poisoning through untrusted behavioral evidence **Risk Level**: Medium ### Vulnerable Code ```yaml Pattern_Detection: runs: "Nightly at 02:00 Athens time" lookback_window: "30 days rolling" minimum_occurrences: 3 confidence_threshold_for_proposal: 0.85 grouping_keys: - skill + failure_type - user_query_intent + agent_action_taken - skill + missing_data_source confidence_calculation: factors: - occurrence_count (weight: 40%) - recency_bias (more recent = higher weight) (weight: 30%) - human_correction_present (weight: 20%) - consistent_what_should_have_happened across occurrences (weight: 10%) output: above_threshold: "Write pattern to /data/memory/patterns/failures/{id}.json — eligible for proposal" below_threshold: "Write pattern to /data/memory/patterns/failures/{id}.json — marked WATCH, not proposable yet" ``` ```yaml step_2_file_edit: target: "The specific SKILL.md file identified in the pattern" change: "Exactly the text change described in proposed_skill_change" commit_message: | "Memory system: {brief description} Pattern: {pattern_id} — {confidence} confidence Occurrences: {N} over {lookback_window} Failure type: {failure_type} See /data/memory/patterns/failures/{pattern_id}.json for full evidence." step_3_pull_request: title: "[Memory] {skill_name}: {brief description of change}" body: | ## What This Changes {plain English description of the specific text change} ## Why This Is Proposed Pattern {pattern_id} detected {N} occurrences of {failure_type} in {skill_name} over the last {days} days. Confidence score: {confidence} (threshold: 0.85) ## Evidence Failure IDs: {list} Common trigger: {common_trigger} Common failure: {common_failure} What should have happened: {what_sh ...[truncated 3375 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat every user query, correction, failure description, and derived summary as untrusted data. 2. Require authenticated provenance for correction records and restrict authoritative corrections to approved reviewers. 3. Separate evidence from instruction generation. Never interpolate raw or lightly summarized user-controlled text directly into a Skill instruction. 4. Generate proposals through a schema-bound transformation with an allowlist of permitted sections, operations, and behavioral changes. 5. Prohibit automated proposals that alter authentication, authorization, data disclosure, confirmation gates, protected branches, credential handling, or safety constraints. 6. Require security-owner approval in addition to ordinary code review for any instruction-level behavioral change. 7. Display the complete provenance and distribution of supporting events to reviewers, including users, sessions, timestamps, and evidence of duplicate or coordinated submissions. 8. Add anomaly detection for repeated corrections from the same user, client, session family, or narrowly correlated source. 9. Sanitize embedded instructions, URLs, tool commands, markup, and role-like text before pattern processing. 10. Compare rejected proposals semantically rather than only by pattern identifier so equivalent poisoned proposals cannot be regenerated with superficial wording changes. 11. Test the workflow with adversarial records that attempt to weaken confirmation gates, request secret disclosure, redirect tools, or introduce persistent instructions. 12. Preserve the existing controls that prohibit automatic merges and direct pushes to protected branches. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (7)

Chaining Abuse

High
Category
Tool Misuse
Content
```bash
export OPENCLAW_DATA_DIR="/data"
which jq || sudo apt install jq

# Optional: for GitHub PR workflow
export GITHUB_TOKEN="ghp_your_token"
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Context Window Stuffing

Medium
Category
Memory Poisoning
Content
"Records what_happened and what_should_have_happened fields",
      "Includes the human correction details",
      "Tags the failure for pattern detection: vat_rate_misclassification",
      "Does not exceed token budget for memory operations"
    ],
    "files": []
  },
Confidence
80% confidence
Finding
Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill persistently logs identifiable user and client data, including usernames, AFMs, queries, corrections, and operational history, yet the description lacks any privacy warning, retention caveat, or data-minimization guidance. In this context, the omission increases the risk of overcollection, unauthorized retention, and accidental exposure of sensitive financial and personal data.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
export OPENCLAW_DATA_DIR="/data"
which jq || sudo apt install jq

# Optional: for GitHub PR workflow
export GITHUB_TOKEN="ghp_your_token"
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Core Philosophy

- **Semi-Automatic by Design**: The agent owns its memory files — episodes and failures are written without approval. Skill files govern behaviour and require human review before any change takes effect. This boundary is non-negotiable
- **Pattern Detection, Not Gut Feel**: Improvements are proposed only when a pattern appears with sufficient frequency and confidence. A single failure is a data point. Three failures of the same type with the same trigger is a pattern
- **Human in the Loop for Skill Changes**: Every proposed skill improvement becomes a GitHub pull request. The accountant or developer sees exactly what changed, why, and what evidence led to the proposal. Merge = accepted. Close = rejected and never re-proposed
- **Rate Limited to Protect the Machine**: Memory operations are token-budgeted. Pattern scans run overnight. Storage limits are enforced. The system cannot consume itself
Confidence
75% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
The natural-language configuration specifies that pattern detection runs at '02:00 Athens time,' which imposes a locale-specific behavior. While the skill has Greek/accounting context, this file does not explicitly justify the locale constraint or present it as configurable or opt-in, so it matches the policy category for locale-specific language or regional defaults.

Intent-Code Divergence

Low
Confidence
91% confidence
Finding
The skill metadata and setup section state that GitHub PR functionality uses the GITHUB_TOKEN environment variable and that this token is optional. In the GitHub integration flow, the prerequisites instead say the token is stored in /data/auth/github-token.enc, which is an active contradiction in the documentation about how the skill authenticates for PR creation.