Back to skill

Security audit

HedgehogMemory

Security checks for vulnerabilities and agentic risk

Overview

This is a real agent-memory library, but it permanently stores and re-injects full conversation and environment data without enough privacy, retention, or prompt-injection safeguards.

Install only if you are comfortable with long-lived local agent memory. Keep its storage directory outside source control, do not commit secrets or private transcripts, prefer the local keyword summarizer for sensitive projects, and treat all restored memory as untrusted historical data rather than instructions.

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
radial_memory/context_manager.py:316
Finding

Persistent Untrusted Memory Can Poison Future Agent Context

Content
View full analysis
str: """ 模拟「清空上下文窗口,仅注入原点」。 返回应注入 agent context window 的原点字符串。 token 消耗约 100~300,取决于任务线数量。 """ self.current_context_type = "origin" self.active_line_id = None self.active_node_position = None return self._build_reset_context() ``` `radial_memory/context_manager.py:316-326`: ```python def _build_reset_context(self) -> str: """清空后仅注入原点的上下文字符串。""" return ( "【上下文已重置:仅保留原点结构】\n" "当前上下文中没有任何任务节点的具体细节。\n" "调用 load(query) 按需载入目标任务状态。\n\n" + self.memory.get_origin_context() ) ``` `radial_memory/models.py:128-175`: ```python def get_origin_entry(self) -> str: """ 返回此线在原点上下文中的 L0 单行描述。 始终占用极少 token,确保原点紧凑。 """ if not self.nodes: return f"[{self.name}] {self.description} — 暂无任务" latest = self.nodes[0] l0 = latest.summaries.get(0, latest.task_label) return f"[{self.name}] {l0} (共{len(self.nodes)}个节点, 最新:{latest.created_at[:10]})" @dataclass class Origin: project_name: str created_at: str lines: Dict[str, Line] = field(default_factory=dict) def get_context(self) -> str: """ 生成始终注入上下文的原点概况字符串。 格式紧凑,agent 看到后能立刻感知全局结构。 """ if not self.lines: return ( f"【原点 ...[truncated 2888 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
radial_memory/storage.py:32
Finding

Verbatim Agent Context and Environment Metadata Are Stored Indefinitely in Plaintext

Content
View full analysis
Node: """ agent 判断当前任务阶段性完成后调用,触发节点生成和持久化。 这是整个循环的「写入」端点: 完整状态 → 生成多级摘要 → 写入 JSON 文件 → 旧节点推远 """ node = self.memory.complete_task( line_id=line_id, task_label=task_label, full_context=full_context, conversation_summary=conversation_summary, modified_files=modified_files, env_info=env_info, todos=todos, precomputed_summaries=precomputed_summaries, ) self.current_context_type = "node" self.active_line_id = line_id self.active_node_position = 1 return node ``` `radial_memory/storage.py:32-38`: ```python def save(self, origin: Origin) -> None: data = self._serialize_origin(origin) with open(self._origin_file, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2) def load(self) -> Optional[Origin]: if not self._origin_file.exists(): return None with open(self._origin_file, "r", encoding="utf-8") as f: data = json.load(f) return self. ...[truncated 2863 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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
Findings (29)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documents capabilities that imply filesystem access for persistent storage and optional network access via the OpenAI summarizer, but it does not declare an explicit tool/permission scope. That mismatch can cause an agent platform or user to underestimate what the skill may do, reducing informed consent and weakening enforcement of least privilege.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The workflow instructs agents to commit the full session log and emphasizes that memory is never deleted, but it does not prominently warn users that potentially sensitive conversation content will be retained persistently. In an agent context, this can capture credentials, personal data, internal documents, or regulated content and store them indefinitely, increasing breach and privacy risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill recommends an OpenAI-based summarizer for quality, but it does not clearly warn that memory content used for summarization may be transmitted to an external third-party service. Because the stored content can include verbatim session transcripts, this may lead to unintended disclosure of sensitive data outside the local environment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code file contains natural-language strings and module documentation entirely in Chinese, including the top-level docstring and user-facing runtime output, with no indication that language selection is configurable. That can violate a language/locale policy when users are not given a choice or informed that the skill is Chinese-only.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The demo unconditionally deletes the ./demo_memory_store directory with shutil.rmtree() at startup if it exists, without confirmation, safety checks, or isolation beyond a relative path constant. In an agent or automated execution context, destructive filesystem actions without user consent can cause unintended data loss, especially if the working directory differs from expectations or the demo path overlaps with real data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This Python file contains extensive natural-language documentation and user-facing status/context strings entirely in Chinese, including outputs returned to the agent. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The not-found response text is emitted in Chinese and will be shown to the consuming agent/user context. Because there is no apparent mechanism for language choice or opt-in, this hard-codes a locale in a way that violates the language policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The status report and reset context strings are user/agent-facing operational messages, but they are fixed to Chinese. The file does not offer a language option or explain a justified locale restriction, so this is a policy issue.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The API exposes load_full_state(), which returns the entire persisted full_context for direct injection into an agent context window. Because full_context is stored as unrestricted prior conversation/work state, this creates a replay channel for sensitive data and prompt-injection content from earlier sessions to be reintroduced into future model runs.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

complete_task() persistently stores arbitrary full_context and conversation_summary without retention limits, filtering, or sensitivity controls, and the design explicitly supports later semantic retrieval and replay. In an agent memory skill, that is more dangerous because user-provided content, secrets, and adversarial instructions can survive task boundaries and influence later sessions, expanding both privacy risk and prompt-injection persistence.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The task completion flow persists env_info into StateSnapshot and later renders it back into loaded context in NavigationSession._build_context() when current_level >= 3. Environment metadata often contains secrets, hostnames, tokens, paths, or other sensitive operational details, so storing and replaying it without redaction, classification, or user consent creates a confidentiality leak channel across future sessions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The storage layer persists the entire serialized origin object to disk, and the serialized state explicitly includes both env_info and full_context. In a memory skill whose purpose is long-lived agent persistence, this can capture secrets, prompts, filesystem details, tokens, or other sensitive runtime data without any consent, minimization, encryption, or redaction, creating a meaningful confidentiality risk if the file is accessed, exfiltrated, or checked into source control.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The OpenAI-backed summarizer sends memory contents, queries, and summaries to an external API provider. In a persistent-memory skill, those inputs may contain sensitive long-lived user data, so undisclosed off-device transmission materially increases privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Raw input text is forwarded for summarization, and summarization can preserve or restate sensitive data rather than eliminate it. In a persistent-memory context, users may assume compression is safer, but the summary can still contain secrets, personal data, or proprietary details and then be stored or transmitted onward.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This API call transmits user-provided text to an external LLM without any user-facing warning, consent flow, or clear notice in code behavior. If memory entries include personal, proprietary, or credential-like data, users may reasonably expect local persistence rather than remote processing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The match-verification path sends both the user's query and stored node summary to an external model. That creates a secondary leakage channel for both current user intent and historical memory contents without transparent notice or policy enforcement.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The LiteLLM summarizer can route memory data to arbitrary backends, including remote providers not specifically disclosed by the skill. Because the destination is configurable and broad, operators may unintentionally exfiltrate persistent memory contents to third parties with different retention or training policies.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The LiteLLM summarizer has the same issue: compressing arbitrary input does not prevent sensitive information from reappearing in the summary. Combined with potentially remote backends, this increases both storage and exfiltration risk for confidential memory contents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This LiteLLM call sends arbitrary input text to a configurable backend without any disclosure to the user about where the data is going. Because LiteLLM may target many external providers, the privacy and compliance risk is broader and less predictable than a single known API.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The verification call transmits query and summary data to whichever LiteLLM backend is configured, again without user-facing notice. In a memory system, summaries can encode sensitive historical context, so even lightweight classification calls can leak valuable information.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: setuptools has 10 known advisory(ies) (CVE-2013-1633 (Setuptools vulnerable to Man-in-the-middle attacks); CVE-2025-47273 (setuptools has a path traversal vulnerability in PackageIndex.download that lead); CVE-2024-6345 (setuptools vulnerable to Command Injection via package URL) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: wheel has 4 known advisory(ies) (CVE-2026-24049 (Wheel Affected by Arbitrary File Permission Modification via Path Traversal in w); CVE-2022-40898 (pypa/wheel vulnerable to Regular Expression denial of service (ReDoS)); CVE-2022-40898 (An issue discovered in Python Packaging Authority (PyPA) Wheel 0.37.1 and earlie) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: litellm has 16 known advisory(ies) (CVE-2024-4888 (Arbitrary file deletion in litellm); CVE-2024-2952 (LiteLLM has Server-Side Template Injection vulnerability in /completions endpoin); CVE-2026-59819 (LiteLLM: Local file read via request-supplied OIDC file references) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: pytest has 2 known advisory(ies) (CVE-2025-71176 (pytest has vulnerable tmpdir handling); CVE-2025-71176 (pytest has vulnerable tmpdir handling)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: black has 5 known advisory(ies) (CVE-2026-32274 (Black: Arbitrary file writes from unsanitized user input in cache file name); CVE-2024-21503 (Black vulnerable to Regular Expression Denial of Service (ReDoS)); CVE-2024-21503 (Versions of the package black before 24.3.0 are vulnerable to Regular Expression) +2 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.