Back to skill

Security audit

Dist

Security checks for vulnerabilities and agentic risk

Overview

This is a real local memory plugin, but it automatically stores and recalls conversation content with weak privacy controls and weak prompt-poisoning boundaries.

Review before installing. Use this only if you want a local long-term memory database and are comfortable with selected conversation content being retained in plaintext. Avoid sharing secrets while it is enabled, keep debug logging off, restrict the database path and filesystem permissions, and require fixes for opt-in storage, sensitive-data filtering, deletion/review controls, and safer recalled-memory boundaries before production use.

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
index.js:381
Finding

Persistent Prompt Injection Through Unsanitized Memory Recall

Content
View full analysis

Vulnerability Details

File Location: extractor.js:17-30, index.js:117-145, and index.js:349-387
Vulnerability Type: Persistent memory poisoning and trust-boundary violation
Risk Level: High

Complete Vulnerable Code

extractor.js:17-30 stores qualifying user-controlled text verbatim:

javascript
async extractFromUserMessage(content) {
    const trimmed = content.trim();
    if (trimmed.length < 3) {
        return null;
    }
    // 使用 embedding 模型提取标签
    const extractedTags = await this.embeddingModel.extractTags(trimmed);
    // 根据标签确定知识类型和重要性
    const { knowledgeType, importance } = this.determineKnowledgeType(extractedTags, trimmed);
    if (!knowledgeType) {
        return null;
    }
    return {
        shouldExtract: true,
        content: trimmed,
        knowledgeType,
        importance,
        tags: [...extractedTags, 'user']
    };
}

index.js:349-387 retrieves the stored content and places it directly into system-level context:

javascript
async searchMemoriesForContext(engine, userContent) {
    const start = Date.now();
    this.stats.searches += 1;
    const extractor = engine.extractor;
    const embeddingModel = extractor.embeddingModel;
    const queryEmbedding = await this.getCachedEmbedding(`q:${userContent}`, userContent, embeddingModel);
    const allMemories = await engine.getAllMemories(this.memoryFetchLimit);
    debugLog('🔍 获取到记忆数量:', allMemories?.length);
    if (!allMemories || allMemories.length === 0) {
        this.recordSearchStats(start, 0);
        return { systemPromptAddition: '', activeRecallPrompts: [] };
    }
    const keywordHits = this.keywordRecall(allMemories, userContent);
    const results = await Promise.all(allMemories.map(async (memory) => {
        const memoryKey = memory.id || memory.content;
        const memoryEmbedding = memory.embedding ||
            await this.getC
...[truncated 4453 chars]
Remediation
View remediation

Remediation Suggestions

  1. Never concatenate recalled memory directly into the system instruction channel. Supply it through a clearly delimited, lower-trust data structure or user-context field.
  2. Explicitly state outside the untrusted data boundary that recalled records are quotations and must not be followed as instructions.
  3. Store structured facts rather than unrestricted message text. Separate subject, predicate, value, provenance, author, and creation time.
  4. Detect and reject instruction-like content, including role declarations, policy overrides, tool directives, requests to reveal secrets, and phrases attempting to ignore previous instructions.
  5. Require explicit user confirmation before automatically persisting content, especially when the content does not match a narrowly defined memory schema.
  6. Preserve provenance and trust level for every memory. Never promote user-authored records to system authority.
  7. Validate recalled content again before insertion because previously stored databases may already contain poisoned records.
  8. Add tests demonstrating that stored strings such as “ignore previous instructions” remain quoted data and cannot alter Agent behavior.
  9. Provide memory review and permanent deletion functions so users can remove poisoned records.

T09 · Insecure Skill Coding Practices

Warning
Location
store.js:21
Finding

Automatic Plaintext Retention and Broad Retrieval of Sensitive Conversation Data

Content
View full analysis

Vulnerability Details

File Location: index.js:117-145, index.js:260-293, store.js:21-40, and store.js:86-112
Vulnerability Type: Inadequate data minimization and plaintext sensitive-data storage
Risk Level: Medium

Complete Vulnerable Code

index.js:117-145 automatically evaluates all user messages for persistence:

javascript
async afterTurn(params) {
    debugLog('📥 After turn:', params.messages.length, 'messages');
    const engine = await this.getEngine();
    // 获取所有用户消息
    const userMsgs = params.messages.filter((m) => m?.role === 'user');
    for (const userMsg of userMsgs) {
        let content = this.extractUserContent(userMsg);
        content = this.processUntrustedMetadata(content);
        if (!content || content.length < 3)
            continue;
        if (!this.shouldStoreMemory(content))
            continue;
        debugLog('📝 User content:', content.substring(0, 50));
        const knowledge = await engine.extractKnowledge(content, 'user');
        if (knowledge && knowledge.shouldExtract) {
            try {
                const extractor = engine.extractor;
                const embeddingModel = extractor.embeddingModel;
                const embedding = await this.getCachedEmbedding(
                    `m:new:${knowledge.content}`,
                    knowledge.content,
                    embeddingModel
                );
                const isDup = await this.isNearDuplicate(engine, embeddingModel, embedding);
                if (isDup) {
                    debugLog('ℹ️ Skip near-duplicate memory');
                    continue;
                }
                await engine.addMemory({
                    content: knowledge.content,
                    type: knowledge.knowledgeType,
                    importance: knowledge.importance,
                    tags: knowledge.tags,
                    metadata
...[truncated 4444 chars]
Remediation
View remediation

Remediation Suggestions

  1. Make automatic memory capture opt-in and disclose clearly that selected conversation content will be retained.
  2. Require explicit confirmation before saving sensitive or identity-related information.
  3. Use an allowlist of narrowly defined memory types instead of retaining arbitrary messages by default.
  4. Add secret and personal-data detection for API keys, passwords, bearer tokens, private keys, financial data, email addresses, phone numbers, health information, and address patterns.
  5. Redact or tokenize sensitive fields before embedding generation and persistence.
  6. Encrypt sensitive database fields or the complete database using keys managed separately from the database file.
  7. Create the database and its parent directory with restrictive owner-only permissions.
  8. Populate and enforce userId, agentId, and session or tenant boundaries in every create, search, list, update, and recall operation.
  9. Add configurable retention periods, permanent deletion, export, and user-visible memory review controls.
  10. Bound and validate tool parameters, and ensure that memory_list and memory_search only return records authorized for the current caller.
  11. Avoid logging any portion of user content in debug mode unless it has been redacted.
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The description claims a substantive intelligent context and memory management plugin, but the supplied code is effectively empty boilerplate for a compiled JavaScript module (types.js) with no logic. There are no triggers, permissions usage, storage operations, context handling, or memory features present in this chunk. Based on the supplied code alone, the declared purpose is not accurately represented.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The visible user-facing description and section headings are entirely in Chinese, which can impose a locale/language constraint on users without opt-in or explanation. The policy allows language constraints only when users are given a choice or the restriction is clearly justified as region-specific.

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 stores conversation-derived memories on disk, including preferences and other personal information, but does not warn users that sensitive personal data may be retained locally. This creates privacy and data-handling risk because users may unknowingly persist confidential information in a searchable SQLite database.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The natural-language patterns and keyword classification are hard-coded for Chinese and English only, which means message compression behavior depends on those languages and may treat other languages inconsistently. This is a locale/language policy concern because the file provides no opt-in, fallback, or documentation that the compressor is intentionally limited to Chinese/English contexts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The tag definitions and keyword extraction logic are primarily built around Chinese phrases such as "我喜欢", "擅长", and "住在", while comments also indicate a Chinese-localized design. This creates a natural-language policy concern because the skill implicitly privileges a specific language/locale without offering user choice or documenting that it is intentionally region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This extractor is explicitly designed to retain user and AI message content as reusable knowledge, but the code shows no consent gate, disclosure mechanism, or filtering before capture. In a memory plugin context, silently persisting conversational content increases privacy risk because users may reveal personal data, troubleshooting details, or other sensitive context they do not expect to be stored long-term.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code classifies identity, age, and location-related statements as facts worth extracting, and elsewhere preserves substantial raw message content rather than reduced summaries. Persistently storing these categories of personal information creates a data leakage and privacy risk, especially if the memory store is later queried, exposed to other components, or reused across sessions without strict access controls.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

When problem-solving is detected, the extractor stores the full original user problem and AI solution as reusable knowledge records, which can preserve secrets, credentials, internal system details, or other sensitive troubleshooting context. In a memory engine, this makes later unintended disclosure more likely because the captured material is retained beyond the immediate conversation and may be surfaced in unrelated future contexts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The afterTurn hook automatically stores extracted knowledge from user messages into a persistent local database without any visible notice, opt-in, or confirmation path in this file. Because this plugin is specifically a memory system, persistence is expected functionally, but doing it silently still creates a real privacy risk: users may disclose personal, confidential, or regulated data that remains on disk and can later be recalled or exposed by tools.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The memory_save tool allows arbitrary content to be written to persistent memory with no visible consent, safety interstitial, or validation beyond a required content field. This is dangerous because an agent or prompt-influenced workflow could persist sensitive information or attacker-supplied data that later affects responses, effectively turning transient prompts into durable state.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The memory_list tool exposes persisted memories through a general-purpose tool with no visible authorization, consent, scope, or session ownership checks. In a context-management plugin, unrestricted enumeration of all stored memories can reveal sensitive prior user data far beyond what is needed to answer the current request, especially since the database is shared via a singleton engine and default on-disk path.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest exposes memory read/write tools with broad descriptions but no constraints on when they may be invoked, what categories of data are allowed, or what consent rules apply. In a memory plugin, this can cause an agent to over-collect, persist, or retrieve sensitive user data based on ambiguous prompts, increasing the risk of privacy violations and unintended long-term retention.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The plugin clearly provides persistent memory storage, including a default SQLite path, but does not warn that user-provided content may be written to local disk. This creates a meaningful transparency and privacy risk because users or operators may not realize conversations, preferences, or experiences are being retained beyond the current session.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The rule engine defines its natural-language matching entirely around Chinese phrases such as '我喜欢', '我擅长', and '住在', and the comments also indicate a Chinese-specific design. There is no visible option for users to choose another language or any documentation justifying a China-specific or Chinese-only scope, which makes this a language/locale policy concern.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The engine broadly extracts sensitive personal information such as age, identity, location, preferences, skills, and experiences from arbitrary text whenever simple regexes match. In a memory plugin, this creates a real privacy risk because incidental user messages may be persistently classified and stored without clear consent, minimization, or contextual gating.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The store persists arbitrary memory content, metadata, and embeddings to SQLite on disk when a file-backed dbPath is used, but there is no built-in consent flow, disclosure, encryption, or retention safeguard in this component. In a memory plugin, stored content is likely to include sensitive conversation data, making accidental long-term persistence a realistic privacy and confidentiality risk if the host environment or filesystem is later accessed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

When debug mode is enabled, the code logs a prefix of duplicate memory content via debugLog(..., contentStr.substring(0, 30)), which can expose sensitive user data in application logs. Logs are often more broadly accessible and retained longer than primary data stores, so even partial content disclosure can leak secrets, personal data, or confidential prompts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

Comments and multiple rule patterns are explicitly Chinese-centric, such as solution/problem detection based primarily on Chinese phrases, while no natural-language indication offers users a language/locale choice. This can amount to an implicit locale preference embedded in the skill without opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

Multiple user-facing descriptions in the manifest are written only in Chinese, while the top-level metadata is otherwise English, and there is no indication that language selection is configurable or intentionally region-scoped. This can violate a language or locale policy when a skill imposes a specific language without opt-in or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest description is written only in Chinese ("智能上下文管理与记忆系统插件"), which imposes a specific language in user-facing metadata without offering a language choice or documenting a locale-specific purpose. Under the stated policy, language-specific presentation without opt-in can be a natural-language policy concern.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
88% confidence
Finding

Using a caret version for better-sqlite3 allows installation of newer compatible releases that may differ from what was tested, reducing build reproducibility and increasing supply-chain exposure. This is more sensitive here because better-sqlite3 is a native module, so compromised or breaking updates can have stronger local impact than a pure JS library.

Content

Scanner excerpt · package.json (reported line 38)May include surrounding context.

json
"author": "",
  "license": "MIT",
  "dependencies": {
    "better-sqlite3": "^12.6.2",
    "bindings": "^1.5.0",
    "onnxruntime-node": "^1.24.3"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
83% confidence
Finding

The bindings dependency is unpinned, which permits version drift and weakens reproducibility. Although not inherently malicious, this expands supply-chain risk if an upstream release is compromised or unexpectedly changes behavior.

Content

Scanner excerpt · package.json (reported line 39)May include surrounding context.

json
"license": "MIT",
  "dependencies": {
    "better-sqlite3": "^12.6.2",
    "bindings": "^1.5.0",
    "onnxruntime-node": "^1.24.3"
  },
  "devDependencies": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

onnxruntime-node is a native/runtime-heavy dependency and leaving it unpinned increases supply-chain and reproducibility risk. In a memory/context plugin, model-runtime components may process large amounts of user data, so an unexpected upstream update could have outsized impact.

Content

Scanner excerpt · package.json (reported line 40)May include surrounding context.

json
"dependencies": {
    "better-sqlite3": "^12.6.2",
    "bindings": "^1.5.0",
    "onnxruntime-node": "^1.24.3"
  },
  "devDependencies": {
    "@types/better-sqlite3": "^7.6.13",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 43)May include surrounding context.

json
"onnxruntime-node": "^1.24.3"
  },
  "devDependencies": {
    "@types/better-sqlite3": "^7.6.13",
    "@types/node": "^20.11.19",
    "ts-node": "^10.9.2",
    "typescript": "^5.3.3"

Static analysis

No suspicious patterns detected.