Back to skill

Security audit

Memory Tiers

Security checks for vulnerabilities and agentic risk

Overview

This memory-tier skill is review-worthy because it scans local agent transcripts, rewrites persistent memory files, and retains raw search queries in a shipped state file.

Install only if you are comfortable with this skill reading local OpenClaw session transcripts and modifying persistent memory files. Run maintenance in dry-run mode first, review proposed promotions/demotions carefully, delete or reset the bundled state/access-log.json before use, and avoid retaining raw search queries unless you explicitly want that telemetry.

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)

T02 · Agent Memory Poisoning

Warning
Location
scripts/track.js:117
Finding
Untrusted Transcript Content Can Trigger Persistent Memory Promotion<![CDATA[ ## Vulnerability Details **File Location**: `scripts/track.js:117-129`, `scripts/maintain.js:68-80`, `scripts/maintain.js:171-186`, `scripts/maintain.js:228-252` **Vulnerability Type**: Untrusted access metadata influencing persistent agent memory **Risk Level**: Medium ### Vulnerable Code `scripts/track.js:117-129`: ```js // Also check tool results that contain memory file content if ((role === 'tool' || role === 'toolResult') && (message.content || entry.content)) { const rawContent = message.content || entry.content; const content = typeof rawContent === 'string' ? rawContent : JSON.stringify(rawContent); // Check if search results reference memory files const matches = content.match(/(?:MEMORY\.md|tier[23]-\w+\.md|\d{4}-\d{2}-\d{2}\.md)/g); if (matches) { for (const m of [...new Set(matches)]) { accesses.push({ type: 'search_result', file: m.includes('/') ? m : `memory/${m}`, timestamp, }); } } } ``` `scripts/maintain.js:68-80`: ```js function getLastAccess(accessLog, filePath, sectionTitle) { const normFile = filePath.replace(WORKSPACE + '/', ''); // Check section-level access const sectionKey = `${normFile}#${sectionTitle}`; if (accessLog.sections[sectionKey]) { return new Date(accessLog.sections[sectionKey].lastAccessed).getTime(); } // Fall back to file-level access if (accessLog.files[normFile]) { return new Date(accessLog.files[normFile].lastAccessed).getTime(); } return 0; // never accessed } ``` `scripts/maintain.js:171-186`: ```js // === PROMOTION: Tier 2/3 → Tier 1 (accessed in last 24h) === const promotionCutoff = now - (24 * 60 * 60 * 1000); for (const tier of [2, 3]) { for (const section of tiers[tier].sections) { const lastAccess = getLastAccess(accessLog, TIER_FILES[tier], section.title); if (lastAccess > promotionCutoff) { actions.push({ action: 'promote', section: section.title, from: tier, ...[truncated 3562 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove filename inference from arbitrary tool-result text. Do not treat a textual filename mention as proof of file access. 2. Accept access events only from authenticated, structured `read`, `memory_get`, or `memory_search` records with verifiable tool identity and arguments. 3. Record exact file and section provenance for search results rather than deriving it with a broad regular expression. 4. Do not use file-level timestamps as a fallback when deciding whether to promote individual sections. 5. Require a recent, exact section-level access event before automatic promotion. 6. Validate timestamps and reject malformed, future-dated, or implausibly old transcript events. 7. Add an approval step before lower-tier content is written into `MEMORY.md`, particularly when the content originated from untrusted sources. 8. Apply limits to the number of sections and total bytes promoted in one maintenance run. 9. Preserve and display the provenance of every proposed promotion in dry-run output. 10. Add regression tests in which arbitrary tool results mention tier filenames and verify that no access or promotion is recorded. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/track.js:263
Finding
Plaintext Retention and Distribution of Sensitive Memory Search Queries<![CDATA[ ## Vulnerability Details **File Location**: `scripts/track.js:263-275`, `state/access-log.json:131-170` **Vulnerability Type**: Excessive plaintext collection and storage of user activity **Risk Level**: Medium ### Vulnerable Code `scripts/track.js:263-275`: ```js // Track search queries if (access.type === 'search' && access.query) { if (!log.searches) log.searches = []; log.searches.push({ query: access.query, timestamp: now, }); // Keep only last 100 searches if (log.searches.length > 100) { log.searches = log.searches.slice(-100); } } ``` Representative records distributed in `state/access-log.json:131-170`: ```json "searches": [ { "query": "agentview browser text-based token reduction", "timestamp": "2026-02-19T13:24:03.214Z" }, { "query": "job tracking list positions applications", "timestamp": "2026-02-20T22:24:41.364Z" }, { "query": "applications submitted last night February 19-20", "timestamp": "2026-02-20T15:01:00.925Z" }, { "query": "moltbook", "timestamp": "2026-02-21T00:40:38.862Z" } ] ``` ### Technical Analysis The access tracker persists complete memory-search query strings in plaintext, although the tier-management functionality only requires access timestamps and counters. Search queries can contain private topics, names, employment information, confidential project terms, credentials, or other sensitive data. The state file is stored inside the Skill project directory rather than a dedicated private runtime-data location. The audited artifact already includes populated search history, demonstrating that runtime behavioral data can be packaged or distributed with the Skill. Limiting retention to 100 entries reduces volume but does not address unnecessary collection, plaintext exposure, or artifact leakage. No network transmission or active exfiltration was found. Exposure occurs when the project directory or its state file is read, copied, backed up, comm ...[truncated 1323 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Stop retaining raw search-query text unless it is strictly necessary for an explicitly documented feature. 2. For access-frequency tracking, store only an aggregate search count and timestamp. 3. If query correlation is required, use a keyed cryptographic hash rather than a reversible or unsalted hash. 4. Apply redaction for credentials, tokens, email addresses, identifiers, and other sensitive patterns before any persistence. 5. Move runtime state outside the distributable Skill directory to a user-specific private data location. 6. Exclude `state/access-log.json`, maintenance logs, and other runtime state from source control and package artifacts. 7. Ship only an empty state template when initialization data is required. 8. Delete the populated state file from existing artifacts and review repository history or published packages for prior disclosure. 9. Create state files with restrictive permissions, such as owner read/write only where supported. 10. Define a short retention period and provide a command for users to erase all tracking data. 11. Document precisely what telemetry is stored and obtain user consent before recording behavioral information. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The description claims an automated tiered memory manager with LRU-style behavior and access-based promotion/demotion across hot/warm/cold tiers. The supplied code is only a manual command-line script for listing sections and moving them between three markdown files. It does not track access frequency/recency, does not automatically promote or demote items, and does not implement cache eviction or LRU logic. Its actual purpose is narrower and materially different: manual manipulation of markdown-backed memory tiers. Additionally, it performs filesystem reads/writes in the user's home workspace, which is an operational capability not reflected in the empty declared permissions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The declared description suggests an active tiered memory management system that implements LRU-like behavior across hot/warm/cold tiers, including automatic promotion, demotion, and access tracking. This code chunk only generates a 'Memory Tier Health Report' by reading existing memory tier files and an access-log JSON file, computing counts and staleness, and outputting recommendations. It does not track accesses itself beyond consuming prior tracking data, does not promote or demote content, does not enforce LRU behavior, and does not modify memory state. The code is therefore materially different in primary purpose and capabilities from the declared description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description suggests an active memory-management component that maintains hot/warm/cold tiers and automatically promotes or demotes items using LRU-style logic. The supplied code does not do that. Instead, it is an offline analytics/tracking utility: it scans session transcript JSONL files, extracts memory-related tool calls and tool outputs, records file/section access counts and timestamps, and saves an access log. While it does perform access tracking, that is only one small part of the declared functionality; the primary behavior is audit/log analysis rather than memory-tier management. The code also performs undeclared file-system scanning and persistence of tracking data, which are inconsistent with the stated purpose.

Ae1

High
Category
analysis-evasion
Content
node scripts/maintain.js --dry-run # preview changes
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/maintain.js --dry-run # preview changes
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/maintain.js --dry-run # preview changes
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/report.js # pretty-printed
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/report.js # pretty-printed
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding
The skill instructs users to run local Node scripts that read and write memory and state files, but it does not declare any tool scope or permissions. That omission reduces transparency and weakens policy enforcement, making it easier for an agent or user to invoke filesystem-capable behavior without an explicit trust decision.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill explicitly recommends running maintenance commands that may modify memory files, but it does not prominently warn that content can be moved between tiers or changed on disk. In an agent-memory context, silent reorganization of workspace files can cause data loss, integrity issues, or unintended exposure of sensitive context to tiers with different loading/search behavior.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The script persistently mines agent session transcripts and stores derived telemetry about memory access, which goes beyond a narrowly described LRU-style memory tier manager. Even if intended for optimization, transcript mining and durable logging can capture sensitive usage patterns and create a secondary surveillance dataset that increases privacy and data-governance risk.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script writes detailed access-tracking data to a local JSON file without any user-facing warning, consent flow, or clear retention policy. Silent persistence of behavioral metadata is dangerous because local logs are often overlooked, may have weak permissions, and can later be accessed by other tools or users on the system.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
This code parses broad session transcripts, extracts tool calls, and records search activity, allowing it to infer user interests and agent behavior far beyond cache management. Because transcripts may contain sensitive prompts, file paths, and contextual metadata, this creates unnecessary exposure and a privacy-sensitive audit trail that could be abused or leaked.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
Tracking writes to memory files and persisting file/section-level access telemetry creates a durable map of what information was touched and modified. In an agent environment, that metadata can reveal sensitive projects, priorities, or knowledge areas even without storing the full content, making it a meaningful privacy and operational-security concern.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
Persisting raw session search queries is especially sensitive because queries often directly encode user intent, secrets, investigative topics, or proprietary context. In a memory-tiering skill, this collection is poorly justified, and if the log is exposed it could disclose far more than simple cache statistics.