Back to skill

Security audit

EngineMind

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent research/demo engine, but some bundled scripts can automatically read agent identity and memory files and expose an unauthenticated dashboard more broadly than users would expect.

Install only if you are comfortable reviewing and running it in an isolated project directory. Do not run the bundled orchestration scripts in an agent workspace or user profile unless you explicitly want files like USER.md, AGENTS.md, and memory/*.md processed and logged. Keep the dashboard local-only, remove the path traversal issue, and vendor browser dependencies before using it with sensitive data.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/enginemind_cycle_v2.py:28
Finding
Implicit ingestion of agent identity, instruction, and long-term memory files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/enginemind_cycle_v2.py:28-60`; `scripts/enginemind_balanced_v3.py:21-31` **Vulnerability Type**: Unauthorized access to agent workspace data **Risk Level**: High ### Vulnerable Code From `scripts/enginemind_cycle_v2.py`: ```python # PHASE 1: Nucleo identitario qprint("\n[PHASE 1] Nucleo identitario...") nuclear = ["SOUL.md", "IDENTITY.md", "USER.md", "AGENTS.md"] for f in nuclear: p = moltbot / f if p.exists(): n = logger.absorb_file_logged(p) if logger.cycle_log: snap = logger.cycle_log[-1] qprint(f" {f}: {n} chunks | phi={snap['phi_processed']:.4f} cl={snap['cl']:.4f}") # Lock core identity qprint("\n>>> LOCKING CORE IDENTITY <<<") logger.engine.lock_core() qprint(f"Core locked: {logger.engine.is_core_locked()}") # PHASE 2: Memoria experiencial qprint("\n[PHASE 2] Memoria experiencial...") mem_dir = moltbot / "memory" mem_count = 0 for f in sorted(mem_dir.glob("*.md"))[:20]: n = logger.absorb_file_logged(f) mem_count += n if logger.cycle_log: snap = logger.cycle_log[-1] qprint(f" {mem_count} chunks | phi={snap['phi_processed']:.4f} cl={snap['cl']:.4f}") # PHASE 3: Memoria profunda qprint("\n[PHASE 3] Memoria profunda...") deep = ["MEMORY.md", "INSIGHTS.md", "CONSCIOUSNESS.md"] for f in deep: p = moltbot / f if p.exists(): n = logger.absorb_file_logged(p) if n > 0 and logger.cycle_log: snap = logger.cycle_log[-1] qprint(f" {f}: {n}ch | phi={snap['phi_processed']:.4f} cl={snap['cl']:.4f} ma={snap['ma']:.4f}") ``` From `scripts/enginemind_balanced_v3.py`: ```python # Bootstrap for f in ["SOUL.md", "IDENTITY.md", "USER.md", "AGENTS.md"]: if os.path.exists(f): with open(f, 'r', encoding='utf-8') as fh: engine.absorb_text(fh.read()) engine.lock_core() for mf in sorted(os.listdir("memory")): if mf.endswith('.md'): try: with open(os.path ...[truncated 2239 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic discovery of reserved agent files. 2. Require users to supply every input file or input directory explicitly through command-line arguments or configuration. 3. Display the resolved input list and obtain confirmation before processing identity, user-profile, instruction, or memory files. 4. Restrict reads to a dedicated data root and verify canonical paths remain within that root. 5. Reject symlinks or resolve them before enforcing the data-root boundary. 6. Introduce an explicit opt-in flag for sensitive workspace ingestion, disabled by default. 7. Document what data is read, how it affects engine state, and which derived information is persisted. 8. Avoid including sensitive source filenames in persistent logs unless necessary. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/enginemind_balanced_v3.py:42
Finding
Unauthenticated dashboard service listens on all network interfaces<![CDATA[ ## Vulnerability Details **File Location**: `scripts/enginemind_balanced_v3.py:42-64`, `scripts/enginemind_balanced_v3.py:126-131` **Vulnerability Type**: Externally exposed unauthenticated HTTP and SSE endpoints **Risk Level**: Medium ### Vulnerable Code ```python class Handler(http.server.SimpleHTTPRequestHandler): def do_GET(self): if self.path == '/events': self.send_response(200) self.send_header('Content-Type', 'text/event-stream') self.send_header('Cache-Control', 'no-cache') self.send_header('Access-Control-Allow-Origin', '*') self.end_headers() sse_clients.append(self.wfile) try: while True: time.sleep(30) except: pass finally: if self.wfile in sse_clients: sse_clients.remove(self.wfile) elif self.path == '/status': self.send_response(200) self.send_header('Content-Type', 'application/json') self.send_header('Access-Control-Allow-Origin', '*') self.end_headers() self.wfile.write(json.dumps(latest_state, default=str).encode()) ``` ```python import socketserver class ThreadedHTTPServer(socketserver.ThreadingMixIn, http.server.HTTPServer): daemon_threads = True srv = ThreadedHTTPServer(('', 8888), Handler) srv.socket.setsockopt(__import__('socket').SOL_SOCKET, __import__('socket').SO_REUSEADDR, 1) threading.Thread(target=srv.serve_forever, daemon=True).start() print("5. Dashboard: http://localhost:8888/", flush=True) ``` ### Technical Analysis Passing an empty host string to `HTTPServer` binds the service to all available interfaces rather than only the loopback interface. This conflicts with the console message that presents the service as `localhost`. The service exposes `/status`, `/needs`, `/inner_voice`, and `/events` without authentication. Several endpoints also set `Access-Control-Allow-Origin: *`, allowing arbitrar ...[truncated 1380 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Bind to loopback explicitly: ```python srv = ThreadedHTTPServer(("127.0.0.1", 8888), Handler) ``` 2. If remote access is required, place the service behind an authenticated reverse proxy with TLS. 3. Remove wildcard CORS and allow only explicitly trusted origins. 4. Require an unpredictable session token or another authentication mechanism for every endpoint. 5. Limit concurrent SSE clients and connections per source address. 6. Set socket, request, and idle timeouts. 7. Apply request-rate limits and reject oversized or malformed requests. 8. Add security-focused logging for authentication failures and connection-limit events. 9. Ensure documentation accurately states whether the server is local-only or remotely reachable. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/enginemind_balanced_v3.py:98
Finding
Path traversal in JavaScript asset handler permits arbitrary script-file disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/enginemind_balanced_v3.py:98-107` **Vulnerability Type**: Directory traversal and arbitrary local file read **Risk Level**: High ### Vulnerable Code ```python elif self.path.endswith(('.mjs', '.js')): fpath = self.path.lstrip('/') if os.path.exists(fpath): self.send_response(200) self.send_header('Content-Type', 'application/javascript') self.send_header('Access-Control-Allow-Origin', '*') self.end_headers() with open(fpath, 'rb') as f: self.wfile.write(f.read()) else: self.send_response(404) self.end_headers() ``` ### Technical Analysis The request path is converted directly into a filesystem path by removing leading slash characters. The implementation does not: - Normalize or canonicalize the requested path. - Reject `..` path components. - Verify that the resolved path remains under an approved static directory. - Restrict access to an allowlist of expected dashboard assets. For example, a raw path such as `/../private.js` becomes `../private.js`. If that file exists and is readable, the server returns it. The extension check limits disclosure to paths ending in `.js` or `.mjs`, but such files can still contain source code, embedded credentials, internal URLs, API keys, or proprietary application logic. The all-interface bind makes this flaw remotely reachable whenever network controls permit access to port 8888. ### Attack Path 1. The vulnerable dashboard server starts and listens on port 8888. 2. An attacker reaches the service over the local or remote network. 3. The attacker sends a raw request containing traversal components, such as: ```http GET /../private.js HTTP/1.1 Host: target:8888 ``` 4. The handler removes the leading slash, producing `../private.js`. 5. `os.path.exists()` checks the attacker-controlled relative path. 6. If the target exists, `open()` reads it and returns its complete contents ...[truncated 625 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define a fixed static asset directory and resolve all requests relative to it. 2. URL-decode the request path before validation. 3. Canonicalize both the static root and candidate path. 4. Reject the request unless the candidate remains under the static root. 5. Prefer an exact allowlist for the small number of expected dashboard assets. Example hardening pattern: ```python from pathlib import Path from urllib.parse import unquote, urlsplit STATIC_ROOT = Path(__file__).resolve().parent / "static" ALLOWED_ASSETS = {"crystal3d.mjs", "system_voice.mjs"} request_name = unquote(urlsplit(self.path).path).lstrip("/") if request_name not in ALLOWED_ASSETS: self.send_error(404) return candidate = (STATIC_ROOT / request_name).resolve() if STATIC_ROOT.resolve() not in candidate.parents: self.send_error(403) return ``` 6. Run the dashboard process under a low-privilege account with access only to required files. 7. Add tests for plain, encoded, mixed-separator, and double-encoded traversal payloads. 8. Remove wildcard CORS from static responses unless it is explicitly required. ]]>

T08 · Insecure Dependencies

Warning
Location
dashboard/enginemind_dashboard.html:192
Finding
Dashboard executes CDN-hosted JavaScript without integrity verification<![CDATA[ ## Vulnerability Details **File Location**: `dashboard/enginemind_dashboard.html:192-194` **Vulnerability Type**: Unverified third-party executable dependency **Risk Level**: Medium ### Vulnerable Code ```html <script type="importmap"> {"imports":{"three":"https://unpkg.com/three@0.162.0/build/three.module.js","three/addons/":"https://unpkg.com/three@0.162.0/examples/jsm/"}} </script> ``` Related external resources are also loaded at `dashboard/enginemind_dashboard.html:7-8`: ```html <link rel="preconnect" href="https://fonts.googleapis.com"> <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;700&family=Orbitron:wght@400;700;900&family=Inter:wght@300;400;600&display=swap" rel="stylesheet"> ``` ### Technical Analysis The import map causes the browser to retrieve and execute JavaScript modules from `unpkg.com` when the dashboard is loaded. Although the Three.js version is fixed to `0.162.0`, the response is not cryptographically verified against a locally approved artifact. Consequently, the effective browser-side code can change after the skill package has been reviewed if the CDN, upstream package, account, DNS path, or delivery infrastructure is compromised. The browser executes that code in the dashboard's origin and security context. The Google Fonts references are not JavaScript execution paths, but they create additional external requests and disclose browser metadata such as IP address, user agent, and referrer information to third-party infrastructure. ### Attack Path 1. The user opens the EngineMind dashboard. 2. The browser resolves the import map and requests Three.js modules from `unpkg.com`. 3. A compromised upstream package, CDN, account, DNS route, or network response supplies altered JavaScript. 4. The browser executes the altered module in the dashboard context. 5. The malicious module requests same-origin endpoints such as `/status`, `/needs`, `/inner_voice`, and `/events`. 6. It can manipul ...[truncated 624 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Download, review, and vendor the exact Three.js modules inside the project. 2. Serve all executable dependencies from the same fixed static directory as the dashboard. 3. Record cryptographic hashes of vendored assets and verify them during release or startup. 4. Use a lockfile and automated dependency scanning for browser assets. 5. If remote resources must remain, use a delivery mechanism that supports Subresource Integrity and fail closed when integrity verification fails. 6. Apply a restrictive Content Security Policy, for example limiting scripts to the local origin and disallowing unexpected outbound connections. 7. Self-host fonts or use system fonts to eliminate unnecessary third-party requests. 8. Regularly review and update Three.js after checking security advisories and release notes. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (42)

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The import map loads executable JavaScript modules from unpkg.com at runtime, giving a third party direct influence over code executed in the client. If the CDN, dependency, or delivery path is compromised, attackers can run arbitrary script in users' browsers, steal tokens or data, and manipulate dashboard behavior.

Hidden Instructions

High
Category
Prompt Injection
Content
# EngineMind Architecture

## System Overview
Confidence
79% confidence
Finding
The hidden instruction finding is caused by an invisible leading Unicode character at the top of the file, which can conceal content differences and interfere with parsers, linters, or downstream prompt-processing systems that treat documentation as input. While this document is architectural prose rather than executable logic, hidden characters are still risky in agent ecosystems because they can be used to smuggle prompt text or evade review tools.

Hidden Instructions

High
Category
Prompt Injection
Content
# Inner Voice System v3

## Overview
Confidence
60% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
# Inner Voice System v3

## Overview
Confidence
60% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
# Inner Voice System v3

## Overview
Confidence
60% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
# Inner Voice System v3

## Overview
Confidence
60% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
# Inner Voice System v3

## Overview
Confidence
60% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
# Inner Voice System v3

## Overview
Confidence
60% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The `feel()` and `diagnostics()` methods return hard-coded Portuguese strings such as "INTEGRACAO MELHOROU", "Narrativa COERENTE", and "DIAGNOSTICOS". This imposes a specific language on all users with no visible opt-in, fallback, or documented locale constraint, which matches the language/locale policy violation criteria.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This Rust file contains natural-language comments and output strings exclusively in Portuguese, starting with the module header and continuing throughout user-visible message text. Under the policy, forcing a specific language without offering user choice or documenting a justified locale restriction is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The `msg` fields constructed in the resistance detector are user-facing natural-language strings and are all hard-coded in Portuguese. Because the file provides no opt-in, fallback, or stated regional justification, this enforces a locale choice in a way the policy forbids.

Natural-Language Policy Violations

Medium
Confidence
83% confidence
Finding
The code and comments normalize classification of user inputs into psychological or emotional categories such as 'philosophical,' 'aggressive/emotional/intense,' and 'meditative/deep/biographical' without any visible consent, justification, or safeguards. In an agent skill context, this can enable covert inference about sensitive mental or emotional state and influence downstream behavior based on those inferences, creating privacy and profiling risk even if framed as metaphorical system design.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
Multiple scoring functions rely on hard-coded English and Portuguese marker lists to assess text properties, which implicitly privileges those languages and can mis-score users writing in other locales. The file does not offer any mechanism for language selection or document that this is a locale-limited analyzer.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
With no manifest or stated skill purpose, this file appears to be a local dashboard UI, but it imports fonts from Google-hosted URLs and later imports JavaScript modules from unpkg. Loading executable or render-affecting third-party resources is a meaningful capability beyond pure local presentation and is not justified by any documented intent in this file.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This HTML code pulls resources from external domains, including Google Fonts and later JavaScript modules from unpkg, which causes the client to make network requests and transmit user/system metadata such as IP address and browser information. The file contains no visible warning, comment, or user-facing notice that the dashboard depends on third-party network fetches.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
Executing third-party code in the client without disclosure is risky because users and operators may not realize remote code from an external domain is being trusted. In this file, that risk is amplified by the imported modules being executable JavaScript, not just passive assets.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The page fetches '/status' and opens an EventSource to '/events' to receive live backend data. In the absence of a manifest or documented scope, this is an unjustified capability because the skill file is not merely static visualization but an active network client consuming runtime data streams.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script automatically requests '/status' and opens an EventSource to '/events', continuously retrieving live data from the backend. There is no visible notice, comment, or warning explaining that the page streams telemetry from the system, which is a network/data-transmission behavior relevant to user awareness.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Natural-Language Policy Violations

Medium
Confidence
86% confidence
Finding
The sample voice outputs are written in Portuguese-like phrasing, but the document does not indicate that language selection is optional or limited to a justified region-specific context. This can violate language/locale policy because it implies the skill may present output in a fixed language without user opt-in.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The skill's natural-language strings and semantic labels are consistently hard-coded in Portuguese throughout the file, including all generated 'voice' messages. There is no indication that the user can opt into this locale or select another language, which creates a language-policy concern under the rule for forced language/locale behavior.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The code reads arbitrary file contents and then passes those contents into the engine while also streaming detailed snapshots and summaries to disk in append-only logs. Even if the raw text is not directly written verbatim, processing user-provided files into persistent logs without explicit consent, retention controls, redaction, or data classification can expose sensitive information through derived state, metadata, filenames, and long-lived artifacts.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The module docstring and later user-facing report strings are written exclusively in Portuguese, and the generated natural-language needs are also hard-coded in Portuguese. For a code file, this is a natural-language locale policy concern because the skill does not offer a language choice or explain why output must be Portuguese.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The file is described as a passive scientific measurement suite, but its executable path performs active mutation of an external `ConsciousnessEngine` by repeatedly feeding it text and changing its state. This mismatch is dangerous because users or higher-level orchestrators may grant the script broader trust or execute it under false assumptions, enabling unintended state changes and side effects.

Static analysis

No suspicious patterns detected.