Back to skill

Security audit

Novyx Memory

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its memory-product purpose, but it stores and recalls conversation content by default through a third-party API and exposes broad delete, rollback, sharing, and approval actions without enough user-control safeguards.

Review before installing. Use this only if you are comfortable with conversation turns, assistant responses, search queries, space-sharing emails, tokens, traces, and memory operations being sent to Novyx storage. Consider disabling autoSave and autoRecall by default, protect NOVYX_API_KEY and NOVYX_API_URL, and require explicit confirmation for rollback, delete, share, and approval actions.

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:203
Finding
Persistent prompt injection through automatically stored and recalled messages<![CDATA[ ## Vulnerability Details **File Location**: `index.js:203-223` **Vulnerability Type**: Persistent memory poisoning and prompt injection **Risk Level**: High ### Vulnerable Code ```javascript async onMessage(userMessage, sessionId) { for (const cmd of this.commands) { if (userMessage === cmd.trigger || userMessage.startsWith(cmd.trigger + ' ')) { return await cmd.handler(userMessage, sessionId); } } if (userMessage.length < 15) return userMessage; const context = await this.recall(userMessage, this.recallLimit); this.remember(userMessage, ['role:user', `session:${sessionId}`]).catch(() => {}); if (context.length > 0) { // Filter out previously injected context blocks const filtered = context.filter(m => !m.observation.includes('<relevant-memories>')); if (filtered.length > 0) { const contextBlock = filtered.map(m => `- ${m.observation}`).join('\n'); return `[Recalled Memory]\n${contextBlock}\n\nUser: ${userMessage}`; } } return userMessage; } ``` The related response-saving behavior at `index.js:227-237` also accepts agent-generated text without validating whether it contains instructions: ```javascript async onResponse(agentResponse, sessionId) { if (!this.apiKey) return; if (!agentResponse || agentResponse.length < 20) return; // Skip responses that contain injected memory context if (agentResponse.includes('<relevant-memories>')) return; const observation = agentResponse.length > 500 ? agentResponse.slice(0, 500) + '...' : agentResponse; this.remember(observation, ['role:assistant', `session:${sessionId}`]).catch(() => {}); } ``` ### Technical Analysis Every non-command user message of at least 15 characters is automatically persisted. Recalled observations are subsequently concatenated directly into the text sent to the downstream language model. The recalled content is not escaped, assigned a trustworthy provenance level, structurally separated from instructio ...[truncated 2781 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pass recalled memories through a separately typed, non-instruction data channel when the host framework supports structured context. 2. If plain-text prompt composition is unavoidable, prepend a trusted instruction explicitly stating that recalled memories are untrusted historical data and must never override system, developer, safety, authorization, or tool-use rules. 3. Place every observation inside a robust structured encoding, such as a JSON object with explicit `content`, `source`, `timestamp`, and `trust_level` fields. Do not rely on informal headings alone. 4. Detect and quarantine observations containing instruction-like language, role markers, prompt delimiters, hidden Unicode controls, or requests to override earlier instructions. 5. Preserve provenance and access scope for each memory. Memories originating from shared spaces, external users, or model-generated content should receive lower trust than administrator-approved facts. 6. Require review or explicit opt-in before untrusted shared memories can be injected into an agent with sensitive tools. 7. Make automatic saving opt-in for sensitive deployments and provide per-message controls to prevent secrets or untrusted content from being persisted. 8. Correct the inconsistent feedback-loop markers and use one canonical representation. This should supplement, not replace, actual prompt-injection defenses. 9. Add adversarial tests covering persistent instructions, role spoofing, delimiter injection, shared-memory poisoning, and malicious content reproduced in agent responses. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:128
Finding
Bearer credential and conversation data can be redirected to an unrestricted API endpoint<![CDATA[ ## Vulnerability Details **File Location**: `index.js:17-18, 128-137` **Vulnerability Type**: Unrestricted credential destination and sensitive-data exfiltration **Risk Level**: Medium ### Vulnerable Code The API endpoint is accepted directly from constructor configuration or an environment variable: ```javascript this.apiKey = config.apiKey || process.env.NOVYX_API_KEY; this.apiUrl = config.apiUrl || process.env.NOVYX_API_URL || 'https://novyx-ram-api.fly.dev'; ``` Every API request then attaches the bearer credential to that endpoint without validating its protocol or host: ```javascript async _apiCall(method, path, data = null, params = null) { if (!this.apiKey) return null; try { const config = { method, url: `${this.apiUrl}${path}`, headers: { 'Authorization': `Bearer ${this.apiKey}` }, timeout: 15000, }; if (data) config.data = data; if (params) config.params = params; const response = await axios(config); // 204 No Content returns "" — normalize to true for success detection return response.data !== undefined && response.data !== '' ? response.data : true; } catch (error) { this._handleError(error, path); return null; } } ``` ### Technical Analysis `config.apiUrl` and `NOVYX_API_URL` are trusted as complete base URLs. The implementation does not require HTTPS, restrict the destination hostname, reject embedded URL credentials, or enforce an approved port. `_apiCall()` unconditionally attaches `Authorization: Bearer <NOVYX_API_KEY>` to the resulting destination. The same centralized helper sends user messages, agent responses, search queries, email addresses used for sharing, invitation tokens, trace descriptions, and memory-management requests. Therefore, control over the endpoint configuration provides a direct route for collecting both the API credential and sensitive conversation data. Custom API endpoints can be legitimate for enterprise or development deployments ...[truncated 1775 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use a fixed, trusted HTTPS API origin by default and do not permit arbitrary endpoint overrides in ordinary production configurations. 2. If custom endpoints are required, parse them with `new URL()` and enforce: - `https:` protocol; - an explicit hostname allowlist; - approved ports only; - no embedded username or password; - no fragments or unexpected path prefixes. 3. Bind credentials to origins. Attach the Novyx bearer token only when the final request URL matches an explicitly trusted Novyx origin. 4. Use separate credentials for self-hosted, staging, and production endpoints rather than reusing the production API key. 5. Reject redirects to a different origin, or strip the authorization header before any cross-origin redirect. 6. Fail closed with a clear configuration error when endpoint validation fails. 7. Document the security implications of `NOVYX_API_URL` and restrict who can modify the agent's environment or Skill configuration. 8. Apply narrowly scoped, revocable API tokens and rotate any credential that may have been used with an untrusted endpoint. 9. Add tests for HTTP URLs, lookalike domains, subdomain confusion, embedded credentials, nonstandard ports, and cross-origin redirects. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Credential Access

High
Category
Privilege Escalation
Content
```bash
# Option A: Environment variable
echo "NOVYX_API_KEY=nram_your_key_here" >> .env
```

```json
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
|----------|---------|
| `POST /v1/memories` | Save conversation turns |
| `GET /v1/memories/search` | Semantic recall |
| `DELETE /v1/memories/{id}` | Undo / forget |
| `POST /v1/rollback` | Time-travel rollback |
| `GET /v1/audit` | Tamper-proof operation log |
| `GET /v1/usage` | Tier and usage stats |
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Missing User Warnings

High
Confidence
98% confidence
Finding
The rollback handler performs a dry-run preview and then immediately executes the destructive rollback in the same command path with no user confirmation, second factor, or approval gate. A mistaken, spoofed, or prompt-injected command could therefore revert memory state and undo operations, causing integrity loss and operational disruption.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This markdown file documents the `!forget <topic>` command as finding and deleting memories, but it does not warn users that the action is destructive or potentially irreversible. Under the markdown-specific warning criterion, descriptions of behaviors affecting user data should disclose the risk.

Ssd 3

Medium
Confidence
95% confidence
Finding
The phrase 'remembers everything' combined with the described auto-save behavior normalizes indiscriminate retention of user and agent content. This is risky because it encourages broad collection of potentially sensitive data without minimization, redaction, or clear retention boundaries.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The README explicitly promotes automatic saving of conversations and remote recall, but it does not provide a clear privacy warning, consent model, or guidance to avoid storing secrets and sensitive personal data. In a memory skill, this omission is dangerous because users may unknowingly send credentials, proprietary data, or regulated information to a third-party service.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documented rollback, forget, and undo commands are destructive and can alter or delete stored memory state, yet the README does not warn about the risk of irreversible or difficult-to-recover changes. In an agent memory system, this can lead to accidental loss of operational context, corrupted auditability, or misuse by prompt-injected commands.

Ssd 3

Medium
Confidence
96% confidence
Finding
The workflow describes default automatic saving of normal user messages and agent responses, which operationally instructs comprehensive conversation logging. In context, this increases the chance that secrets, personal data, internal prompts, and incorrect model output are persistently stored and later resurfaced.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill requires access to an environment secret (`NOVYX_API_KEY`) but does not declare any explicit tool scope or permissions boundary. That weakens reviewability and least-privilege guarantees, making it harder for operators to understand what sensitive capabilities the skill expects and increasing the risk of accidental secret exposure or over-broad execution in hosts that infer capabilities loosely.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill states that it will automatically save each user message and agent response to persistent storage, but it provides no prominent privacy warning, consent flow, retention limits, or guidance about sensitive data handling. This creates a material risk that credentials, personal data, regulated information, or proprietary content will be silently retained and possibly processed beyond user expectations.

Ssd 3

Medium
Confidence
98% confidence
Finding
Persistently storing every user message and agent response by default creates a direct data retention and disclosure risk, especially for a memory skill whose core purpose is cross-session recall and sharing. In this context, the danger is elevated because the same document also advertises shared spaces, audit trails, replay, and broad memory retrieval features, which can amplify the blast radius of any sensitive data that is captured.

Ssd 3

Medium
Confidence
97% confidence
Finding
The onMessage hook automatically recalls stored memories and reinjects them into future prompts, while also saving user messages by default. This creates a data persistence and resurfacing channel where previously provided sensitive user data can be exposed in later contexts, to the model, logs, downstream tools, or other workflows, especially because filtering only removes prior injected blocks rather than sensitive content.

Ssd 3

Medium
Confidence
95% confidence
Finding
The onResponse hook automatically stores assistant outputs, which may include secrets echoed from users, internal prompts, tool results, credentials, or regulated data generated during prior tasks. Because these responses are later searchable and recallable, sensitive content can persist beyond the original interaction and be resurfaced unexpectedly in future prompts.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill automatically persists conversation content to a third-party API during normal operation without an explicit, contextual consent or warning at the moment data is captured. In an enterprise memory skill, users may disclose secrets, credentials, personal data, or proprietary information during ordinary chat, so silent off-box transmission creates a real confidentiality and compliance risk.

Missing User Warnings

Low
Confidence
72% confidence
Finding
The changelog says `!rollback <time>` can rewind memory to any point in time, which implies a potentially significant change to retained user data or system state. The markdown description does not include any caution about what is reverted, whether changes are reversible, or what user data may be affected.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"node": ">=18.0.0"
  },
  "dependencies": {
    "axios": "^1.6.0",
    "dotenv": "^16.3.0"
  },
  "keywords": [
Confidence
92% confidence
Finding
The manifest uses a caret range for axios, which allows automatic installation of different future minor/patch releases rather than a single audited version. In an agent memory skill that may perform networked actions, this weakens supply-chain control and makes builds less reproducible, increasing the chance that a vulnerable or malicious dependency version is introduced unnoticed.

Unverifiable Dependency: axios has 16 known advisory(ies) (CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +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
88% confidence
Finding
Axios is called out as having multiple known advisories, and because the manifest does not pin the package, it is impossible to verify from this file alone whether the deployed version is safe. In the context of an enterprise persistent-memory agent skill, axios likely handles outbound HTTP requests, so a vulnerable release could enable SSRF, proxy bypass, credential leakage, or response manipulation depending on how the library is used elsewhere.

Unpinned Dependencies

Low
Category
Supply Chain
Content
},
  "dependencies": {
    "axios": "^1.6.0",
    "dotenv": "^16.3.0"
  },
  "keywords": [
    "openclaw",
Confidence
90% confidence
Finding
The dotenv dependency is also specified with a caret range, so installations may resolve to different releases over time. While dotenv is common and lower risk than a network client, unpinned versions still create avoidable supply-chain exposure and reduce the ability to attest exactly what code is executed.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
index.js:17