T09 · Insecure Skill Coding Practices
Warning
- Location
- memory.js:223
- Finding
- Persistent memories are stored in plaintext without explicit access restrictions<![CDATA[ ## Vulnerability Details **File Location**: `memory.js:15`, `memory.js:38-53`, `memory.js:223-230` **Vulnerability Type**: Insecure storage of potentially sensitive data **Risk Level**: Medium ### Vulnerable Code ```javascript const DEFAULT_STORE_PATH = join(__dirname, 'MEMORY_STORE.json'); ``` ```javascript add(content, importance, metadata = {}) { if (!content || typeof content !== 'string') throw new Error('Content must be non-empty string'); const trimmed = content.trim(); if (trimmed.length < 1 || trimmed.length > 5000) throw new Error('Content must be between 1 and 5000 characters'); const item = { id: randomUUID(), content: trimmed, timestamp: Date.now(), importance: importance ?? this.#config.defaultImportance, metadata, }; this.#memories.push(item); this.#dirty = true; this.#autoCleanup(); this.#save(); return item; } ``` ```javascript #save() { if (!this.#dirty) return; try { writeFileSync(this.#storePath, JSON.stringify(this.toJSON(), null, 2), 'utf-8'); this.#dirty = false; } catch (err) { console.error(`[memory] Error saving store: ${err.message}`); } } ``` ### Technical Analysis The engine accepts arbitrary memory content and metadata and serializes the complete store to a predictable plaintext JSON file. The write operation does not specify a restrictive file mode, does not encrypt sensitive values, and does not apply any secret-detection or data-classification controls. For a newly created file, Node.js uses the platform default creation mode subject to the process umask. Consequently, confidentiality depends on the runtime environment rather than an explicit security guarantee from the application. If the process has a permissive umask, the store may be readable by unintended local users. If the file already exists, writing it does not correct previously unsafe permissions. Because an AI memory store can contain user preferences, conversation-derived facts, internal ...[truncated 1223 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Store memory files in an operating-system-appropriate, user-private data directory rather than the package directory. 2. Create new store files with an explicit restrictive mode such as `0o600`: ```javascript writeFileSync(this.#storePath, serializedData, { encoding: 'utf8', mode: 0o600, }); ``` 3. Validate and repair the permissions of existing store files before reading or writing them. 4. Document that credentials, authentication tokens, private keys, and other secrets must not be stored unless encryption is enabled. 5. Add optional authenticated encryption for sensitive deployments. Obtain encryption keys from an environment-specific secret manager rather than embedding them in the project. 6. Use atomic writes through a securely created temporary file in the same private directory, then rename it into place. 7. Add automated tests that verify restrictive permissions on supported platforms. ]]>
