Back to skill

Security audit

Hermes Memory Sync

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says, but it broadly reads private chat logs and stores excerpts as persistent plaintext memory without redaction, retention controls, or strong trust boundaries.

Review this before installing if Hermes session logs may contain secrets, personal data, customer data, or sensitive operational details. Use a private output directory, avoid broad backfill or cron until you understand what will be written, keep generated memory out of source control and sync tools, and treat copied Q&A/tool text as untrusted historical content 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

Error
Location
hermes-memory-sync.py:229
Finding

Untrusted Session Content Is Written Verbatim into Persistent Agent Memory

Content
View full analysis
= 5: break if msg['role'] == 'user': content = extract_text_from_content(msg['content'])[:300] lines.append(f"**Q:** {content}") # Find the next assistant response for j in range(i + 1, min(i + 5, len(messages))): if messages[j]['role'] == 'assistant': resp = extract_text_from_content(messages[j]['content'])[:400] lines.append(f"> **A:** {resp}\n") exchange_count += 1 break # Decisions if summary['decisions']: lines.append("## ⚡ 决策/方案") for d in summary['decisions']: lines.append(f"- {d}") lines.append("") # Tool actions summary if summary['tool_actions']: lines.append("## 🛠️ 工具使用") for t in summary['tool_actions'][:5]: lines.append(f"- {t}") lines.append("") ``` ### Technical Analysis The memory generator copies user messages, assistant responses, inferred decisions, and tool outputs directly into Markdown memory files. The content is truncated, but it is not sanitized, escaped, classified by trust level, or separated from operational instructions using a machine-enforced data format. Session content is attacker-controllable when an attacker can communicate with the agent, influence an external source quoted in a conversation, or control output returned by a tool. An attacker can therefore insert instruction-like text into a session log. The `backfill` operation subsequently preserves that t ...[truncated 1918 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
hermes-memory-sync.py:258
Finding

Sensitive Session History Is Broadly Collected and Duplicated into Plaintext Files

Content
View full analysis
dict[date, list[dict]]: """Load all messages from all session files, grouped by date.""" grouped: dict[date, list[dict]] = defaultdict(list) # 1. Parse session_*.json files (full session records) for f in sorted(HERMES_SESSIONS_DIR.glob('session_*.json')): try: msgs = parse_session_json(f) for msg in msgs: msg_date = msg['timestamp'].date() grouped[msg_date].append(msg) except (json.JSONDecodeError, KeyError) as e: print(f" [warn] Skipping {f.name}: {e}", file=sys.stderr) # 2. Parse YYYYMMDD_*.jsonl files (detailed per-message logs) for f in sorted(HERMES_SESSIONS_DIR.glob('[0-9]*.jsonl')): try: msgs = parse_session_jsonl(f) for msg in msgs: msg_date = msg['timestamp'].date() grouped[msg_date].append(msg) except (json.JSONDecodeError, KeyError) as e: print(f" [warn] Skipping {f.name}: {e}", file=sys.stderr) return dict(grouped) ``` ```python output_dir.mkdir(parents=True, exist_ok=True) output_path.write_text('\n'.join(lines), encoding='utf-8') ``` ### Technical Analysis Every supported command calls `load_all_messages()`, which reads all matching session JSON and JSONL files into memory. This also occurs when the requested operation concerns only one date. The generated summaries can contain portions of user messages, assistant responses, decisions, tool output, model names, and session metadata. The selected data is written as unencrypted, human-readable Markdown using the platform's default file-creation permissions. The implementation does not: - Redact credentials, authenticati ...[truncated 2024 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill documents actions that read local session logs and create persistent files, but it does not declare any tool scope or permissions boundary. That omission can mislead users and review systems about the skill's actual capabilities, increasing the chance that sensitive conversation data is processed or written without informed approval.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill encourages backfill and scheduled cron execution over session logs but does not clearly warn that this will generate durable memory files containing conversation-derived content. Users may unknowingly persist sensitive prompts, responses, tool usage, or decisions into a new location, expanding data exposure and retention risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script persists conversation-derived content into markdown files without any consent, notice, retention control, or redaction boundary. Because it includes extracted topics, user questions, assistant replies, and tool-derived preference signals, it can create a secondary long-lived store of potentially sensitive personal or operational data beyond the original session logs.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The summarizer republishes raw or lightly truncated user prompts, assistant responses, detected decisions, and tool activity into plain-text memory files. This increases exposure of sensitive data by duplicating it into a new, human-readable artifact that may be easier to browse, sync, back up, or exfiltrate than the original logs.

Content

No source excerpt is available for this finding.

Context Window Stuffing

Medium
Category
Memory Poisoning
Confidence
85% 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.

Content

Scanner excerpt · hermes-memory-sync.py (reported line 329)May include surrounding context.

python
def cmd_backfill(target: str):
    """Backfill memory files for specific dates."""
    grouped = load_all_messages()
    dates = sorted(grouped.keys())

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The output format section specifies memory files using Chinese labels such as 会话数, 用户提问, and 自动生成于, which indicates a fixed language choice. The document does not offer locale selection or explain that the skill is intentionally region-specific, so this is a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The generated markdown headings and metadata labels are hardcoded in Chinese, such as 会话数, 讨论主题, and 自动生成于. The file does not indicate that Chinese output is optional or region-specific, so this imposes a fixed locale without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

Console output and argument help strings are consistently presented in Chinese, including status messages and usage guidance. Because no locale selection mechanism is provided, the tool enforces a specific language rather than offering a user choice.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.