Back to skill

Security audit

MemCore

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent memory-system skill, but it needs Review because it persists and automatically recalls user memory with weak scoping, deletion safeguards, and integration warnings.

Install only if you are comfortable with a local memory database under your home directory retaining user preferences, task state, knowledge, and episodic memory across sessions. Do not store secrets or regulated data unless the host application adds consent, deletion/export controls, access isolation, and encryption as needed. Treat suggested_context as untrusted retrieved content, and review or disable automatic forgetting before relying on the store as durable memory. Avoid exposing JSONBackend category names to untrusted input until path validation is added.

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

Error
Location
memcore_enhanced.py:133
Finding

Persistent Untrusted Context Injection Through Agent Memory

Content
View full analysis
str: episode_id = f"ep_{hashlib.md5(str(datetime.now()).encode()).hexdigest()[:12]}" episode = EpisodicMemoryEntry( id=episode_id, content=f"{context_summary} -> {conclusion}", timestamp=datetime.now(), priority=priority, episode_type=episode_type, context_summary=context_summary, conclusion=conclusion, related_topics=related_topics or [], participants=participants or [] ) conflicts = self.conflict_resolver.detect_conflict( episode, list(self.episodic_memory.values()) ) if conflicts: episode, _ = self.conflict_resolver.resolve(episode, conflicts) self.episodic_memory[episode_id] = episode self.confidence_tracker.register_memory( episode_id, source, confidence, extraction_method="record_episode" ) if self.backend: self.backend.save_episodic_memory(episode) self._auto_create_trigger(related_topics or [], [episode_id]) return episode_id ``` The persisted memory is later converted directly into suggested agent context: ```python if mem_id in self.episodic_memory: episode = self.episodic_memory[mem_id] episode.touch() conf = self.confidence_tracker.get_confidence(mem_id) if conf >= 0.5: result["loaded_memories"].append({ "type": "episodic", "content": episo ...[truncated 4630 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
persistent_backend.py:416
Finding

Path Traversal in JSON Persistence Backend

Content
View full analysis
str: return os.path.join(self.data_dir, f"{category}.json") def save(self, category: str, data: Dict): filepath = self._get_file_path(category) existing = {} if os.path.exists(filepath): with open(filepath, 'r', encoding='utf-8') as f: existing = json.load(f) existing.update(data) with open(filepath, 'w', encoding='utf-8') as f: json.dump(existing, f, ensure_ascii=False, indent=2, default=str) def load(self, category: str) -> Dict: filepath = self._get_file_path(category) if not os.path.exists(filepath): return {} with open(filepath, 'r', encoding='utf-8') as f: return json.load(f) def delete(self, category: str, key: str): filepath = self._get_file_path(category) if not os.path.exists(filepath): return with open(filepath, 'r', encoding='utf-8') as f: data = json.load(f) if key in data: del data[key] with open(filepath, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2, default=str) ``` ### Technical Analysis `_get_file_path()` concatenates an unrestricted caller-controlled `category` with the `.json` suffix. It does not reject absolute paths, path separators, or `..` traversal components and does not verify that the normalized destination remains under `self.data_dir`. For example, a category such as `../../target` produces a path equivalent to: ```text /../../target.json ``` After path normalization by the operating system, this resolves outside the intended data directory. An absolute category can also cause `os.path.join()` to discard the configured base directory. The same unsafe path is use ...[truncated 1535 chars]
Remediation
View remediation
str: if not re.fullmatch(r"[A-Za-z0-9_-]+", category): raise ValueError("Invalid category") base = os.path.realpath(self.data_dir) candidate = os.path.realpath(os.path.join(base, category + ".json")) if os.path.commonpath([base, candidate]) != base: raise ValueError("Path escapes data directory") return candidate ``` 4. Consider opening files relative to a trusted directory descriptor with platform-supported no-follow protections to reduce symbolic-link attacks. 5. Use restrictive directory and file permissions because memory data may contain sensitive user information. 6. Write updates atomically through a temporary file in the same validated directory, then replace the destination. 7. Add tests covering `../`, absolute paths, nested separators, symbolic links, empty category names, and platform-specific path syntax. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (30)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The forgetting cycle permanently deletes stored memories automatically based on a risk threshold, with no confirmation, preview, backup, or user warning. In a system that stores user memories and preferences, this can cause irreversible loss of important data and can be triggered as part of normal operation, making the behavior especially dangerous in this skill context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README describes an automatic forgetting cycle that deletes low-priority memories based on age and access patterns, but it does not clearly warn about irreversible data loss or how users can disable or tune the behavior. For a persistent memory system, silent deletion can destroy important state, auditability, or user data unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README states that user memory and task data are automatically persisted to a local SQLite database and restored on restart, but it does not warn users about privacy, retention, or storage location risks. In a memory-oriented agent skill, this can lead to unintentional long-term storage of sensitive personal data, increasing exposure if the host is shared, backed up, or compromised.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation describes an automated forgetting cycle that can delete stored memories, but it does not clearly warn users that data loss may occur or recommend backups, previews, or confirmation mechanisms. For a persistent memory system, undocumented automatic deletion can cause unintended loss of user state, preferences, or knowledge records.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly documents persistent SQLite storage of user memories across sessions but does not warn about privacy, retention duration, access controls, or how sensitive data should be handled. In a memory system, silent persistence materially increases the risk of collecting and retaining personal or confidential information longer than users expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The external embedding example shows integration with an OpenAI-based embedding wrapper but does not warn that memory or knowledge content may be transmitted to a third-party remote API. Because this skill handles user memories and knowledge entries, sending that content off-box without disclosure can expose sensitive or personal data to external processors.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The module docstring and user-facing quickstart content are entirely in Chinese, indicating an implicit language constraint for documentation and examples. Under the policy, forcing a specific language without offering user choice or documenting a justified locale scope is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The module title, docstrings, comments, and user-facing text are predominantly in Chinese, and the file provides no indication that users can opt into another language or that the skill is intentionally region-specific. This can conflict with organizational language/locale policy when a skill implicitly forces a specific language for interaction or maintenance.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

SQP-3 applies to all file types and covers language or locale policy violations. This module presents its title and descriptive text in Chinese alongside limited English, and the rest of the user-facing/documentation strings are predominantly Chinese, with no indication that the skill is intentionally region-specific or that users can opt into another language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The class docstrings, inline explanatory strings, suggested actions, and console output are largely Chinese-language text. Because the file does not provide a language choice or justify a Chinese-only locale constraint, this is a natural-language policy concern under SQP-3.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The module title, docstrings, comments, and user-facing demo strings are presented in Chinese, which effectively imposes a specific language on users and maintainers without any opt-in or explanation. Under the language/locale policy, forcing a specific language without choice or documented justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The forgetting manager permanently deletes stored memories automatically once their forgetting score exceeds a threshold, with no user notification, consent flow, audit trail, or recovery mechanism. In a memory/personalization component, silent deletion can cause loss of important user data, break user expectations around retention, and undermine safety or compliance requirements when users assume data persists until explicitly removed.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger system performs substring-based keyword matching on user input and automatically injects previously stored episodic memories or user-memory content into the returned context. This can disclose sensitive prior user data unexpectedly when a benign-looking prompt happens to match a topic, especially because there is no access control, sensitivity filtering, consent check, or scoping to the current request.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The class enables persistent storage by default and stores episodic memory and user preference data, which may contain sensitive personal or behavioral information, without any consent, notice, minimization, or protection controls visible here. In a memory system intended to capture user context, this increases privacy and data-retention risk, especially if the SQLite path is on shared or insufficiently protected storage.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

At L339-L340, run_forgetting_cycle is documented as merely running a forgetting cycle, which suggests memory lifecycle management rather than destructive deletion. In practice, L353-L355 deletes episodic memories from both persistent storage and in-memory state, a materially stronger side effect than the documentation implies.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code initializes a persistent SQLite database under the user's home directory and later stores episodic and user memory content there. Although the module docstrings describe persistence, there is no explicit user-facing warning or confirmation that potentially sensitive conversation or user-memory data will be written to disk.

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

python
# 情景记忆表
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS episodic_memory (
                id TEXT PRIMARY KEY,
                episode_type TEXT NOT NULL,
                context_summary TEXT NOT NULL,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The delete_episodic_memory method permanently removes stored memory records, but the code provides no confirmation prompt, warning log, or explanatory notice about this irreversible action. Similar silent deletion behavior appears in cleanup routines, increasing the risk of unnoticed data loss.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The cleanup_old_memories method deletes records matching age and priority criteria, which is a destructive operation affecting persisted data. The docstring describes cleanup behavior, but there is no user-facing warning, confirmation, or operational disclosure that data will be permanently removed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The JSON backend reads and writes category data to files in the user's home directory, and its delete method modifies stored files by removing entries. While function docstrings mention save/load/delete, there is no explicit user-facing warning that potentially sensitive memory data is being persisted and altered on disk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The OpenAIEmbeddingWrapper sends arbitrary provided text to an external API for embedding generation without any built-in disclosure, consent flow, or data-sensitivity guardrails. If callers pass secrets, personal data, or proprietary knowledge content, this can cause unintended data exfiltration to a third-party service and violate privacy or compliance requirements.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill documentation is predominantly in Chinese and does not indicate that language is selectable or that the skill is intended only for a Chinese-speaking audience. This can be a natural-language policy issue because it effectively forces a specific language without user opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The skill content consistently uses Chinese for headings, explanations, and examples, but does not indicate that language selection is optional or that the skill is intended only for a Chinese-speaking context. This may conflict with a language/locale policy requiring user choice or documented justification.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · conflict_resolver.py (reported line 202)May include surrounding context.

python
if fields:
            parts = []
            for field in fields:
                val = getattr(memory, field, '')
                parts.append(str(val))
            return ' '.join(parts)

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · conflict_resolver.py (reported line 209)May include surrounding context.

python
# 默认字段
        for attr in ['content', 'context_summary', 'conclusion', 'value']:
            if hasattr(memory, attr):
                return str(getattr(memory, attr))
        
        return str(memory)