Back to skill

Security audit

Muninn Memory

Security checks for vulnerabilities and agentic risk

Overview

This is a memory skill that stores and retrieves agent memories, with disclosed local/cloud model integrations that need privacy-aware configuration.

Install only if you are comfortable with an agent memory database. Use local mode for private data, verify which environment variables are set, avoid storing secrets, and understand that cloud/OpenAI/Gemini modes or local Ollama processing can receive memory content or queries.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (12)

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill advertises executable behavior that uses environment variables and network access, but the metadata declares no permissions. This creates a transparency and trust problem: users or hosting platforms may authorize or sandbox the skill incorrectly, while the skill can still handle secrets and transmit data externally.

Tp4

High
Category
MCP Tool Poisoning
Confidence
79% confidence
Finding
The skill description materially understates the breadth of behavior, including external services, audit/access tracking, integrity tooling, procedure evolution, and other advanced operations beyond a simple memory system. This mismatch can mislead users into granting trust or deploying the skill without understanding its real attack surface and data-handling behavior.

External Transmission

Medium
Category
Data Exfiltration
Content
_b.label = 1;
                case 1:
                    _b.trys.push([1, 4, , 5]);
                    return [4 /*yield*/, fetch('http://localhost:11434/api/generate', {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify({
Confidence
91% confidence
Finding
The code sends raw input text to a local Ollama HTTP endpoint for LLM-based coreference resolution before memory storage. Because this text may contain sensitive user notes, PII, credentials, or internal business data, it constitutes an external transmission to another service boundary without any consent, minimization, sanitization, or security controls. In an agent memory skill, this is more dangerous because the processed content is explicitly likely to be long-lived, user-derived, and privacy-sensitive.

Context Leakage

High
Category
Data Exfiltration
Content
// HELPER FUNCTIONS
// ============================================
function createEntity(text, type, confidence, fullText) {
    // Extract context (surrounding words)
    var index = fullText.toLowerCase().indexOf(text.toLowerCase());
    var start = Math.max(0, index - 20);
    var end = Math.min(fullText.length, index + text.length + 20);
Confidence
91% confidence
Finding
The extractor stores a snippet of the original input around each matched entity, which can unintentionally retain sensitive nearby data such as emails, secrets, personal identifiers, or confidential conversational content. In a memory-oriented skill, these context snippets are likely to be persisted, indexed, or returned later, increasing the chance of privacy leakage beyond the minimally necessary entity text.

External Transmission

Medium
Category
Data Exfiltration
Content
_a.label = 1;
                case 1:
                    _a.trys.push([1, 4, , 5]);
                    return [4 /*yield*/, fetch('http://localhost:11434/api/generate', {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify({
Confidence
95% confidence
Finding
This code sends arbitrary memory content to an external HTTP service for entity extraction, which is a real data-exfiltration/privacy risk if memories contain sensitive user data. Although the destination is localhost, it still crosses a trust boundary into another process/service, uses plaintext HTTP, and performs no consent, sanitization, classification, or access control checks before transmission.

External Transmission

Medium
Category
Data Exfiltration
Content
Entities (JSON array):`;

  try {
    const response = await fetch('http://localhost:11434/api/generate', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
Confidence
89% confidence
Finding
The function sends raw memory text to an external HTTP service on localhost for LLM-based entity extraction. Even though the destination is local, this is still a trust-boundary crossing: sensitive memory contents may be exposed to another process, and the use of plaintext HTTP with no authentication means any local or container-adjacent service bound to that port could receive or spoof the data.

External Transmission

Medium
Category
Data Exfiltration
Content
_a.label = 1;
                case 1:
                    _a.trys.push([1, 4, , 5]);
                    return [4 /*yield*/, fetch('http://localhost:11434/api/generate', {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify({
Confidence
89% confidence
Finding
The code sends procedure content, step descriptions, and failure context to an external HTTP service on localhost for LLM analysis. Even though the destination is local, this is still an external transmission boundary: sensitive workflow data may be exposed to another process, and the use of plain HTTP with no authentication or origin validation increases the risk of unintended disclosure or abuse if a different service is bound to that port.

External Transmission

Medium
Category
Data Exfiltration
Content
}`;

  try {
    const response = await fetch('http://localhost:11434/api/generate', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
Confidence
94% confidence
Finding
The code sends procedure titles, descriptions, steps, and failure context to a local Ollama HTTP endpoint without any sanitization, minimization, authentication, or transport protection. Even though the destination is localhost, this is still an external transmission boundary: sensitive workflow data may be exposed to an unintended local service, intercepted by other local processes, or forwarded by the model backend, and untrusted LLM output is then trusted for procedure evolution.

External Transmission

Medium
Category
Data Exfiltration
Content
const maxTokens = options?.maxTokens || 100;

  try {
    const response = await fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
Confidence
90% confidence
Finding
The hardcoded external endpoint confirms outbound transmission to OpenAI infrastructure from the answer-generation path. In the context of a memory system, this materially increases risk because the feature is specifically designed to process stored memories, making third-party disclosure of potentially personal or confidential information likely rather than hypothetical.

External Transmission

Medium
Category
Data Exfiltration
Content
const model = options?.model || OPENAI_MODEL;

  try {
    const response = await fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
Confidence
83% confidence
Finding
The hardcoded OpenAI endpoint in the answer-checking path indicates remote disclosure of answer content to a third party. Even though this is an evaluation workflow, the transmitted strings may still include sensitive or proprietary information, and the code provides no boundary checks or privacy controls.

External Transmission

Medium
Category
Data Exfiltration
Content
const maxTokens = options?.maxTokens || 100;

  try {
    const response = await fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
Confidence
90% confidence
Finding
The hardcoded external endpoint confirms outbound transmission to OpenAI infrastructure from the answer-generation path. In the context of a memory system, this materially increases risk because the feature is specifically designed to process stored memories, making third-party disclosure of potentially personal or confidential information likely rather than hypothetical.

External Transmission

Medium
Category
Data Exfiltration
Content
const model = options?.model || OPENAI_MODEL;

  try {
    const response = await fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
Confidence
83% confidence
Finding
The hardcoded OpenAI endpoint in the answer-checking path indicates remote disclosure of answer content to a third party. Even though this is an evaluation workflow, the transmitted strings may still include sensitive or proprietary information, and the code provides no boundary checks or privacy controls.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/storage/turboquant-client.ts:38

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/retrieval/answer-generator.ts:11

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/storage/embeddings.ts:18

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/storage/index.ts:185