Back to skill

Security audit

Three Tier Memory

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local memory skill, but it needs review because it can persist arbitrary conversation data in plaintext without clear consent, retention, deletion, or access-control safeguards.

Install only if you are comfortable with the skill storing conversation and preference data on disk. Avoid storing secrets, credentials, regulated personal data, or confidential business information unless you add your own consent, deletion, retention, encryption, and file-permission controls.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Warning
Location
scripts/memory_manager.py:165
Finding
Unpinned Third-Party Dependency Installation Guidance<![CDATA[ ## Vulnerability Details **File Location**: `scripts/memory_manager.py:165-169` and `scripts/memory_manager.py:181-185` **Vulnerability Type**: Unpinned dependency and software supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```python def init_vector_store(): """初始化向量存储""" try: import chromadb from chromadb.config import Settings except ImportError: print("✗ 需要安装 chromadb: pip install chromadb") return False ``` The same installation guidance is repeated when adding long-term memory: ```python def add_long_term_memory(content: str, metadata: dict = None): """添加长期记忆(向量存储)""" try: import chromadb from chromadb.config import Settings except ImportError: print("✗ 需要安装 chromadb: pip install chromadb") return False ``` ### Technical Analysis When ChromaDB is unavailable, the application instructs users to execute `pip install chromadb` without specifying an audited version, integrity hash, or trusted package index. The code does not automatically execute this command, but its official installation guidance encourages resolution and installation of whichever package version the configured Python package index currently serves. This creates a non-reproducible dependency chain and exposes users to compromised future releases, unsafe transitive dependency changes, package-index substitution, and malicious mirror configuration. Python packages may execute package-controlled build logic during installation and arbitrary module-level code when imported. ### Attack Path 1. An attacker compromises a future `chromadb` release, one of its transitive dependencies, or a package index/mirror used by the victim. 2. The victim runs the memory manager without ChromaDB installed. 3. The script displays the unpinned `pip install chromadb` instruction. 4. The victim follows the instruction in an affected Python environment. 5. Pip resolves the attacker-controlled ...[truncated 677 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Provide a reviewed dependency manifest, such as a locked `requirements.txt` or lockfile, containing an explicitly approved ChromaDB version. 2. Pin all transitive dependencies and use cryptographic hashes where the package-management workflow supports them. 3. Replace the generic instruction with a command that installs from the reviewed manifest, for example: ```bash python3 -m pip install --require-hashes -r requirements.txt ``` 4. Document the approved package index and prevent unintended fallback to untrusted mirrors. 5. Run dependency vulnerability and provenance checks during CI. 6. Install dependencies in an isolated virtual environment with least privilege rather than a system-wide or privileged Python environment. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/memory_manager.py:93
Finding
Conversation and Memory Data Persisted in Plaintext with Inherited Filesystem Permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/memory_manager.py:48-52`, `scripts/memory_manager.py:93-124`, `scripts/memory_manager.py:137-158`, and `scripts/memory_manager.py:191-211` **Vulnerability Type**: Insecure storage of potentially sensitive conversation data **Risk Level**: Medium ### Vulnerable Code The storage directories are created without explicitly enforcing owner-only permissions: ```python def ensure_dirs(): """确保必要的目录存在""" MEMORY_DIR.mkdir(parents=True, exist_ok=True) SUMMARIES_DIR.mkdir(parents=True, exist_ok=True) VECTOR_STORE_DIR.mkdir(parents=True, exist_ok=True) ``` Short-term conversation content is written directly to a plaintext JSON file: ```python def add_short_term_memory(content: str, metadata: dict = None): """添加短期记忆(滑动窗口)""" config = load_config() window_size = config['memory']['short_term']['window_size'] with open(SLIDING_WINDOW_FILE, 'r') as f: data = json.load(f) messages = data.get('messages', []) # 添加新消息 new_message = { 'content': content, 'timestamp': datetime.now().isoformat(), 'metadata': metadata or {} } messages.append(new_message) # 滑动窗口:保持最近 N 条 if len(messages) > window_size: messages = messages[-window_size:] data['messages'] = messages data['updated_at'] = datetime.now().isoformat() with open(SLIDING_WINDOW_FILE, 'w') as f: json.dump(data, f, indent=2, ensure_ascii=False) print(f"✓ 已添加短期记忆,当前窗口: {len(messages)}/{window_size}") return True ``` Medium-term summaries are also persisted as plaintext JSON: ```python def add_medium_term_memory(content: str, summary_type: str = 'auto'): """添加中期记忆(摘要)""" date_str = datetime.now().strftime('%Y-%m-%d') summary_file = SUMMARIES_DIR / f'{date_str}.json' if summary_file.exists(): with open(summary_file, 'r') as f: data = json.load(f) else: ...[truncated 3382 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create memory directories with owner-only permissions, such as mode `0700`, and memory files with mode `0600`. 2. Verify and correct permissions on existing files rather than protecting only newly created files. 3. Use atomic secure file creation and avoid relying solely on the process umask. 4. Encrypt sensitive memory content at rest using a key obtained from an operating-system credential store or dedicated secrets manager. Do not store the encryption key beside the encrypted data. 5. Add configurable retention periods, expiration, deletion, and secure account/workspace cleanup capabilities for every storage tier. 6. Redact or reject credentials, API keys, access tokens, and other recognized secrets before persistence. 7. Require explicit user or administrator consent before enabling durable long-term memory. 8. Document exactly what data is persisted, where it is stored, who can access it, and how users can inspect or delete it. 9. Avoid placing sensitive workspaces in shared, synchronized, indexed, or broadly backed-up locations unless those systems provide equivalent access controls and encryption. 10. Add tests that verify restrictive permissions and confirm that deleted or expired records are removed from JSON storage and ChromaDB. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill advertises commands that read configuration and write persistent memory files, but it declares no explicit tool scope or permissions boundary. In an agent ecosystem, this can cause the skill to be invoked with broader file and environment access than users expect, increasing the chance of unintended data exposure or modification.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The activation guidance is broad enough to encourage use whenever an agent wants context optimization, knowledge base construction, or persistence, which can lead to this skill being applied to sensitive conversations by default. That increases the likelihood that private or regulated data will be stored into local files or a vector database without a clear necessity or user consent.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill explicitly stores conversation content in persistent JSON summaries and a long-term vector store, yet provides no warning that sensitive user data may be retained and later retrieved. In this context, the omission is dangerous because the skill's core purpose is memory persistence, so users and downstream agents may unknowingly retain secrets, personal data, or confidential business information.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The examples explicitly store personal data such as user preferences and a real-looking personal name into short-, medium-, and long-term memory without any warning about persistence, consent, retention, or sensitivity. In a memory-management skill, this normalizes capturing personally identifiable or preference data and can lead downstream integrators to persist user data indefinitely without adequate privacy controls.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The OpenClaw integration example directly passes user_message into a memory storage command, effectively instructing developers to capture and persist arbitrary user input without any user-facing notice, consent flow, filtering, or sensitivity checks. Because this skill is specifically designed for persistent multi-tier memory, the context makes the issue more dangerous: accidental storage of secrets, personal data, regulated data, or prompt contents is a foreseeable outcome.

Tainted flow: 'config_json' from os.environ.get (line 74, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
"""保存配置文件"""
    # 使用 JSON 而非 YAML,减少依赖
    config_json = CONFIG_FILE.with_suffix('.json')
    with open(config_json, 'w') as f:
        json.dump(config, f, indent=2, ensure_ascii=False)
    print(f"✓ 已保存配置: {config_json}")
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Tainted flow: 'SLIDING_WINDOW_FILE' from os.environ.get (line 28, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
# 创建短期记忆文件
    if not SLIDING_WINDOW_FILE.exists():
        with open(SLIDING_WINDOW_FILE, 'w') as f:
            json.dump({'messages': [], 'updated_at': datetime.now().isoformat()}, f, indent=2, ensure_ascii=False)
        print(f"✓ 已创建短期记忆: {SLIDING_WINDOW_FILE}")
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Tainted flow: 'SLIDING_WINDOW_FILE' from os.environ.get (line 28, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
# 创建短期记忆文件
    if not SLIDING_WINDOW_FILE.exists():
        with open(SLIDING_WINDOW_FILE, 'w') as f:
            json.dump({'messages': [], 'updated_at': datetime.now().isoformat()}, f, indent=2, ensure_ascii=False)
        print(f"✓ 已创建短期记忆: {SLIDING_WINDOW_FILE}")
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Tainted flow: 'SLIDING_WINDOW_FILE' from os.environ.get (line 28, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
# 创建短期记忆文件
    if not SLIDING_WINDOW_FILE.exists():
        with open(SLIDING_WINDOW_FILE, 'w') as f:
            json.dump({'messages': [], 'updated_at': datetime.now().isoformat()}, f, indent=2, ensure_ascii=False)
        print(f"✓ 已创建短期记忆: {SLIDING_WINDOW_FILE}")
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill stores arbitrary supplied memory content to local JSON files without any consent prompt, sensitivity check, retention control, or warning that the content becomes persistent on disk. In the context of an AI memory manager, users may supply secrets, personal data, or internal conversation history, so silent persistence materially increases confidentiality and privacy risk if the host is shared, backed up, or later compromised.

Tainted flow: 'summary_file' from os.environ.get (line 146, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
}
    data['summaries'].append(new_summary)
    
    with open(summary_file, 'w') as f:
        json.dump(data, f, indent=2, ensure_ascii=False)
    
    print(f"✓ 已添加中期记忆: {summary_file}")
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The manual summary operation clears the short-term memory file immediately after archiving, with no confirmation, dry-run mode, backup, or undo path. This creates a real integrity/availability risk because a user can lose recent conversation state unexpectedly, especially if the generated summary is poor or incomplete.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
Most of the operational description and usage guidance are written in Chinese, while the file title and some headings are in English. This effectively imposes a language requirement on users without an explicit opt-in or justification, which can conflict with language or locale policy expectations.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
The file content, headings, and descriptions are presented in Chinese only, which can impose a language constraint on users without opt-in. There is no indication that the skill is intentionally region-specific or that alternative language support is available.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
User-facing descriptions, usage examples, and CLI help text are predominantly presented in Chinese, and the file does not indicate that another language is supported or that Chinese is required for a specific region or compliance reason. This can be a locale policy issue when a skill imposes one language without user opt-in.

Static analysis

No suspicious patterns detected.