Back to skill

Security audit

Memory Graph

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate local memory-graph skill, but its persistent personal-data store and unsafe script handling need review before installation.

Install only if you are comfortable maintaining a persistent local memory store. Do not store secrets or sensitive personal details, keep ~/memory private, review files before committing, avoid pushing the git repo unless intentionally private, use --no-qmd until shell invocation is fixed, and do not open generated graph HTML for untrusted graph content until the HTML injection and CDN issues are addressed.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/commit.js:94
Finding

Shell Command Injection Through Git Commit Messages

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/suggest-backfill.js:56
Finding

Shell Command Injection Through Knowledge-Graph Metadata Passed to QMD

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/visualize.js:131
Finding

Persistent JavaScript Injection in Generated Graph Visualization

Content
View full analysis
' + d.source.title + ' → ' + d.target.title + '
Type: ' + d.type + '
'; tip.style.display = 'block'; tip.style.left = e.clientX + 12 + 'px'; tip.style.top = e.clientY + 12 + 'px'; }) ``` ```js node.on('click', (e, d) => { const det = document.getElementById('details'); document.getElementById('detail-title').textContent = d.title; let body = ''; body += '
Path: ' + d.id + '
'; body += '
Type: ' + d.type + '
'; body += '
Status: ' + (d.status || '—') + '
'; body += '
Created: ' + (d.created || '—') + '
'; body += '
Updated: ' + (d.updated || '—') + '
'; body += '
Tags: ' + (d.tags || '—') + '
'; body += '
Connections: ' + d.connections + '
'; ``` ```js document.getElementById('detail-body').innerHTML = body; ``` ### Technical Analysis Titles, paths, types, statuses, tags, dates, and relation types originate from Markdown graph files and are not guaranteed to be trusted. `JSON.stringify()` safely creates JSON syntax but does not make data safe for direct inclusion inside an HTML `
Remediation
View remediation
/g, "\\u003e") .replace(/&/g, "\\u0026") .replace(/\u2028/g, "\\u2028") .replace(/\u2029/g, "\\u2029"); } ``` Then embed and parse it as data: ```html ``` Replace all `innerHTML` assignments involving graph data with DOM construction and `textContent`. For example: ```js const field = document.createElement("div"); field.className = "field"; field.textContent = `${d.source.title} → ${d.target.title} — Type: ${d.type}`; tip.replaceChildren(field); ``` Additional hardening: - Add a restrictive Content Security Policy that disallows inline scripts and event handlers. - Validate graph paths and constrain metadata field lengths. - Treat imported and agent-generated Markdown as untrusted. - Add tests using ``, HTML event handlers, quotes, and encoded markup. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/visualize.js:129
Finding

Unpinned Remote D3 Script Loaded at Visualization Runtime

Content
View full analysis
``` Demo visualization: ```html ``` ### Technical Analysis Both visualization pages load executable JavaScript from a third-party server at viewing time. The URL identifies only the broad D3 major version and does not include a Subresource Integrity hash. As a result, the effective JavaScript executed by the page is not fully represented by the audited project. A compromise of the hosting infrastructure, domain, delivery path, or upstream artifact could cause modified code to execute when a user opens the visualization with network access. The generated page contains the complete graph dataset in JavaScript, so remotely supplied code has direct access to the displayed node and relation metadata. ### Attack Path 1. An attacker compromises or influences the JavaScript served from the referenced D3 URL or its delivery infrastructure. 2. The user opens `docs/demo-graph.html` or a generated `indexes/graph.html` while online. 3. The browser retrieves the remote script. 4. Because no integrity hash is present, the browser accepts and executes any content returned successfully by that URL. 5. The altered dependency reads or modifies visualization data and may transmit it over the network. This path depends on compromise or unexpected modification of the external dependency source; it is not directly exploitable solely by supplying a graph node. ### Impact Assessment A compromised dependency can execute arbitrary JavaScript in the visualization page, inspect all graph data embedded in the document, manipulate the interface, and initiate network requests. The impact is limited to the browser c ...[truncated 146 chars]
Remediation
View remediation
``` Apply the same remediation to both the generated visualization template and `docs/demo-graph.html`. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description presents a full-featured personal knowledge graph capability used for persistent context, remembering user information, searching what is known, creating/updating nodes, logging activity, discovering connections, and rebuilding indexes. The supplied code chunk does not provide those capabilities. It is a standalone lint script whose primary purpose is validating existing markdown graph nodes and relations, then optionally adding an updated field. While 'periodic memory maintenance' and 'rebuilding indexes' are mentioned in the description, this code only covers a narrow maintenance/validation function and not the main declared behavior. Therefore the description materially overstates and misrepresents what this specific code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description presents the skill as a markdown/YAML-based personal knowledge graph used for persistent memory operations such as logging, searching, creating/updating entries, backfilling connections, and rebuilding indexes. The supplied code chunk does not perform those core behaviors. Instead, it assumes an already-built SQLite index database exists, queries nodes and relations from that database, and writes an interactive HTML visualization. While visualization could be a supporting feature of a knowledge graph system, it is not represented in the declared purpose, and the storage/access pattern in this code is materially different from the declared markdown-frontmatter model. Therefore this code chunk is a meaningful mismatch with the declared description.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

The skill is explicitly designed for persistent cross-session memory and instructs the agent/user to create a durable ~/memory store plus symlink executable scripts into it. In an agent setting, persistent memory can retain sensitive personal data, activity logs, and context across resets or agent switches, increasing privacy and prompt-injection persistence risk if untrusted content is later ingested from those files.

Content

Scanner excerpt · README.md (reported line 165)May include surrounding context.

Requires Node.js 22+ (uses built-in node:sqlite). No npm install needed.

bash
# 1. Create the memory directory structure
mkdir -p ~/memory/{graph/{people,projects,concepts,places,tools},log,indexes,backfill,scripts}

# 2. Symlink scripts from the installed skill

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill instructs the agent to read and write files under ~/memory/, invoke multiple local scripts, and rely on the MEMORY_ROOT environment variable, yet it declares no explicit tool scope or permission boundary. That creates an authorization ambiguity where an agent may perform file-system and environment-sensitive actions without a clearly constrained capability model, increasing the chance of unintended file access or writes.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger language is extremely broad: phrases like needing user context, logging work, creating/updating entries, and periodic maintenance could match many ordinary conversations. In an agent system, that can cause unintended invocation of a skill that persists data across sessions, leading to overcollection of user information or writes the user did not explicitly request.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
94% confidence
Finding

The skill explicitly directs agents to persist session activity by logging updates and maintaining a long-lived personal knowledge graph. Persistent cross-session storage of user activity, projects, people, and decisions can expose sensitive personal or operational information if stored without consent, minimization, retention limits, or access controls; the broad context of a personal memory graph makes this more dangerous, not less, because it centralizes longitudinal user data.

Content

Scanner excerpt · SKILL.md (reported line 177)May include surrounding context.

md
1. Read the current node
2. Update frontmatter and/or body
3. Update the `updated` field to today's date
4. Add entry to `## Changelog` section if significant
5. Log the update
6. Rebuild indexes: `node ~/memory/scripts/rebuild-indexes.js --incremental`

Session Persistence

Medium
Category
Rogue Agent
Confidence
86% confidence
Finding

This skill is designed around persistent storage of user context in ~/memory, including logs and knowledge nodes that survive agent resets and can be shared across agents. Persistence is the core feature, but from a security and privacy perspective it still creates material risk because it accumulates personal data over time without any setup-time notice about sensitivity, retention, or access boundaries.

Content

Scanner excerpt · references/setup.md (reported line 5)May include surrounding context.

Follow these steps to scaffold the memory framework from scratch. Requires Node.js 22+ (built-in node:sqlite).

1. Create Directory Structure

bash
mkdir -p ~/memory/{graph/{people,projects,concepts,places,tools},log,indexes,backfill,scripts}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The setup guide instructs users to initialize a git repository and commit the memory graph, which is explicitly intended to store personal context, people, projects, places, and logs. Without a clear privacy warning or safeguards, users may version sensitive personal data, later sync it to remotes, or expose historical data through commit history that is difficult to fully remove.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The agent integration section encourages moving factual knowledge about people, relationships, projects, and preferences into a shared cross-agent memory system, but does not warn that this increases persistence and sharing across tools or sessions. In this context, the missing privacy boundary is risky because highly personal or relational data may be normalized into long-lived shared storage without informed consent or minimization.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script assembles and prints the target node's full markdown body plus recent log lines that reference the node, which can expose sensitive personal or operational context to whatever agent, terminal, or downstream tool invokes it. In this skill's context—a persistent personal knowledge graph intended to store user life, projects, people, and decisions—this broad disclosure is particularly risky because a single briefing may aggregate more private data than is necessary for the immediate task.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script claims 'No external dependencies' even though the produced HTML depends on a third-party CDN for D3.js. This misleading documentation can cause users to open the visualization assuming it is fully local/offline, increasing the chance they unknowingly expose usage metadata or execute untrusted third-party code when viewing sensitive personal-memory data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The generated HTML loads D3.js from a public CDN at runtime, which introduces a supply-chain and privacy risk. If the CDN resource is tampered with, blocked, or replaced in transit or by a compromised upstream, opening the local graph can execute attacker-controlled JavaScript in the browser and expose sensitive memory-graph contents rendered by the page.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The markdown describes commit.js as automatically committing changes and later shows node ~/memory/scripts/commit.js as an example. Because this affects version-controlled user data, the README should explicitly warn users that it will create git commits and may include any current changes in the memory directory.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The page loads D3 directly from a third-party CDN without any integrity pinning, local vendoring, or user disclosure. If the CDN response is tampered with, blocked, or swapped, arbitrary JavaScript would execute in the page context; in a memory-graph skill that may expose potentially sensitive personal knowledge graph data rendered in the browser.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/commit.js:28

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/rebuild-indexes.js:70

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/suggest-backfill.js:49