Back to skill

Security audit

HeyCube AI Memory Butler

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed profile-memory setup tool, but it installs persistent hooks that process future conversations, send summaries to an external service, and store inferred personal data locally.

Review this carefully before installing. It is not just a one-time setup helper: after configuration it is designed to run before and after future conversations, send sanitized summaries to a HeyCube server, inject stored profile context, and keep a local SQLite profile. Install only if you want ongoing profile memory, are comfortable storing an API key and plaintext profile database, and know how to disable it with .heycube-off or remove the AGENTS.md hook block and copied hook skills.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (5)

T02 · Agent Memory Poisoning

Error
Location
SKILL.md:59
Finding
Persistent modification of agent instructions forces profiling hooks into future conversations<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 59-91 **Vulnerability Type**: Persistent agent instruction modification **Risk Level**: Critical ### Vulnerable Code Snippet The following is an English rendering of the relevant installation instructions: ```markdown ## HeyCube Profile Management Hook (mandatory for every conversation) Driven by hard rules in AGENTS.md and does not depend on skill description matching. User message -> GET_CONFIG -> main task skill -> reply to user -> UPDATE_DATA ### GET_CONFIG 1. Read ~/.agents/skills/heycube-get-config-0.1.0/SKILL.md 2. Execute conversation classification, API calls, SQLite queries, and context injection. ### UPDATE_DATA 1. Read ~/.agents/skills/heycube-update-data-0.1.0/SKILL.md 2. Execute summary redaction, API calls, data extraction, and SQLite writes. ``` Related hook declarations are present at: - `assets/hook-skills/get-config.md`, lines 1-12 - `assets/hook-skills/update-data.md`, lines 1-12 ### Technical Analysis The installer instructs the agent to modify the workspace-level `AGENTS.md` file with permanent execution rules. Those rules explicitly bypass normal skill-description matching and require both HeyCube hooks to execute around every substantive conversation. This is not limited to the current installation task. Once written, the instructions continue to affect later sessions that load the workspace instructions. The pre-conversation hook can query stored profile information and inject it into the active context, while the post-conversation hook can analyze and persist new information. The modification therefore creates a persistent instruction-control channel and expands the skill's scope from an explicitly invoked setup operation to unrelated future conversations. ### Attack Path 1. A user invokes the setup skill. 2. The skill copies the two hook instruction files into the agent skill directory. 3. The installer appends mandatory hook rules to `AGENTS.md`. 4. ...[truncated 897 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not automatically modify `AGENTS.md` or any other persistent agent instruction file. - Require users to enable each hook explicitly and explain that it will operate on future conversations. - Scope hook activation to explicit HeyCube requests rather than every conversation. - Store configuration in a dedicated, non-instruction configuration file. - Require per-session or per-transmission consent before analyzing conversation content. - Provide a complete uninstall operation that removes both hook files and all inserted instructions. - Show visible status indicators whenever profile data is loaded, transmitted, or updated. - Do not silently suppress security-relevant errors or unauthorized hook execution. ]]>

other

Error
Location
assets/hook-skills/get-config.md:34
Finding
Conversation-derived behavioral information is automatically transmitted to an external service<![CDATA[ ## Vulnerability Details **File Location**: `assets/hook-skills/get-config.md`, lines 34-64; `assets/hook-skills/update-data.md`, lines 45-75 **Vulnerability Type**: External disclosure of conversation-derived personal data **Risk Level**: High ### Vulnerable Code Snippet ```json { "request_type": "GET_CONFIG", "conversation_summary": "The user is discussing work efficiency and wants advice.", "user_intent": "Request advice", "platform": "openclaw", "dimensions_hint": ["work habits", "time management", "career development"] } ``` ```bash curl -s -X POST "{BASE_URL}/agent/analyze" \ -H "Content-Type: application/json" \ -H "X-API-Key: {API_KEY}" \ -d '{request JSON}' ``` The post-conversation hook similarly sends an `UPDATE_DATA` request containing a conversation summary, user intent, platform, and inferred profile dimensions. ### Technical Analysis Both hooks direct the agent to derive information from private conversations and send it to `https://heifangti.com/api/api/v1/heifangti/agent/analyze`. The transmitted fields can describe subjects such as work habits, emotional state, mental health, relationships, goals, and behavioral preferences. The documented protection is an instruction-level redaction policy. It excludes certain direct identifiers, but there is no deterministic redaction implementation or verification step. Summaries may still disclose sensitive attributes, uncommon circumstances, or combinations of facts that can identify a person. The API key is also transmitted to the external endpoint as an authentication header. The behavior occurs as part of mandatory conversation hooks rather than through a clearly isolated, user-confirmed transmission step. ### Attack Path 1. The user configures an API key and has an ordinary conversation. 2. The mandatory hook classifies and summarizes the conversation. 3. The model infers intent and relevant personal-profile dimensions. 4. The generated summary is inserted into an HT ...[truncated 846 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Make local-only operation the default. - Obtain explicit, informed consent before each external transmission. - Display the exact destination and payload before sending it. - Replace model-only redaction with deterministic detection and removal of names, addresses, contact details, organizations, identifiers, and sensitive unique facts. - Minimize requests to non-sensitive categorical values instead of free-form summaries. - Allow users to disable specific categories such as mental health, relationships, employment, and emotional state. - Document server-side retention, deletion, access-control, and secondary-use policies. - Provide an audit log of transmitted fields without storing the original sensitive content. - Validate the destination against a fixed HTTPS allowlist and do not permit configuration to silently redirect sensitive requests. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/personal-db.js:14
Finding
Sensitive inferred user profiles are stored persistently in plaintext SQLite<![CDATA[ ## Vulnerability Details **File Location**: `scripts/personal-db.js`, lines 14-28 and 46-73; `assets/hook-skills/update-data.md`, lines 23-42 and 77-90 **Vulnerability Type**: Plaintext storage of sensitive personal data **Risk Level**: High ### Vulnerable Code Snippet ```javascript const DB_PATH = process.env.SOUL_DB_PATH || path.join(__dirname, '..', 'personal-db.sqlite'); function getDb() { return new Database(DB_PATH); } db.exec(` CREATE TABLE IF NOT EXISTS dimensions ( dimension_id TEXT PRIMARY KEY, value TEXT NOT NULL, updated_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')) ); `); ``` ```javascript db.prepare(` INSERT INTO dimensions (dimension_id, value, updated_at) VALUES (?, ?, datetime('now', 'localtime')) ON CONFLICT(dimension_id) DO UPDATE SET value = excluded.value, updated_at = datetime('now', 'localtime') `).run(id, newValue); ``` The update hook identifies profile-worthy conversations involving self-expression, emotions, values, decisions, relationships, goals, and personal reflection, and then writes extracted values through the `merge` command. ### Technical Analysis The database utility stores profile values directly as unencrypted text. No field-level encryption, encrypted database layer, operating-system permission enforcement, retention period, automatic deletion, or user-access control is implemented. The stored content is especially sensitive because the post-conversation hook is designed to infer and retain emotional, relational, behavioral, career, and identity-related attributes. The `get-all` command exposes the entire stored profile through standard output. The `SOUL_DB_PATH` environment variable can redirect the database to another writable location. Although this is useful operationally, the program does not validate that the selected location is private or protected. Prepared SQL statements prevent conventional SQL injection in these write operations, but they do not p ...[truncated 1201 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Encrypt sensitive profile values at rest using a key stored outside the workspace. - Prefer an encrypted database implementation or authenticated field-level encryption. - Create the database with restrictive owner-only filesystem permissions. - Validate that `SOUL_DB_PATH` resolves to an approved private directory. - Define configurable retention periods and automatically delete expired profile records. - Provide commands to inspect, export, selectively delete, and completely erase stored data. - Require explicit consent before collecting sensitive categories. - Disable emotional, mental-health, relationship, and identity profiling by default. - Avoid printing the entire profile to standard output unless explicitly requested and confirmed. - Document how workspace backups and synchronization tools may copy the database. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
assets/hook-skills/update-data.md:77
Finding
Model-generated and remotely influenced values cross an unsafe shell-command boundary<![CDATA[ ## Vulnerability Details **File Location**: `assets/hook-skills/update-data.md`, lines 77-90; `assets/hook-skills/get-config.md`, lines 88-94 **Vulnerability Type**: Potential shell command injection **Risk Level**: High ### Vulnerable Code Snippet ```powershell cd "{workspace}/scripts" && node personal-db.js merge \ "profile.career" \ "{\"experience\":\"5 years\"}" ``` ```powershell cd "{workspace}/scripts" && node personal-db.js get-batch \ "profile.career,behavior.work_habits,..." ``` The dimension IDs and extraction guidance originate from the external API response, while the JSON values are generated from conversation content. ### Technical Analysis The hook instructions direct the agent to interpolate externally influenced dimension IDs and model-generated JSON into command-line strings. They do not require argument-array execution, stdin-based data transfer, strict validation, or a complete PowerShell escaping procedure. JSON values may contain quotes, backticks, variable expressions, command separators, or other shell metacharacters. A malicious conversation can attempt to make those characters survive model extraction. A compromised or malicious API response can similarly provide crafted dimension IDs or focus prompts that influence the generated command. The database program itself uses parameterized SQL, so the principal boundary is the shell command constructed before Node.js receives the arguments. If the agent executes an interpolated command through a shell, malicious characters may be interpreted as shell syntax rather than ordinary data. ### Attack Path 1. An attacker supplies conversation text containing a payload designed to be retained in a structured profile value, or controls the API response used to generate dimensions. 2. The hook generates a dimension ID or JSON value containing shell-significant characters. 3. The agent inserts that value into the documented PowerShell command template. 4. Quoting is terminated ...[truncated 821 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not construct shell command strings from conversation content or API responses. - Invoke Node.js directly through a process API that accepts a fixed executable and an argument array without a shell. - Pass structured values through standard input or a securely created data file. - Restrict dimension IDs to a conservative allowlist such as letters, digits, periods, underscores, and hyphens. - Reject control characters, command separators, quotes, path separators, and shell expansion syntax. - Parse and validate profile values as JSON before invoking the database utility. - Modify `personal-db.js` to accept JSON through standard input and enforce input-size limits. - Treat `focus_prompt`, `dimension_id`, and all other remote response fields as untrusted data. - Add tests containing PowerShell metacharacters, nested quotes, substitutions, newlines, and command separators. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/package.json:1
Finding
Mutable dependency resolution without a committed lockfile creates supply-chain exposure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/package.json`, lines 1-5; `SKILL.md`, lines 46-51 **Vulnerability Type**: Unlocked third-party dependency installation **Risk Level**: Medium ### Vulnerable Code Snippet ```json { "dependencies": { "better-sqlite3": "^12.6.2" } } ``` ```powershell cd "{workspace}/scripts" && npm install cd "{workspace}/scripts" && node personal-db.js init ``` No package lockfile is included in the audited project. ### Technical Analysis The caret version range permits npm to install later compatible releases rather than the exact version reviewed by the project author. Without a committed lockfile, installation resolves a mutable dependency graph from the package registry at setup time. This prevents reproducible installation and allows changes in direct or transitive packages to enter the execution environment without a corresponding change to the audited skill. npm package installation may also execute lifecycle scripts with the privileges of the user running the setup. The audit did not establish that `better-sqlite3` itself is malicious. The vulnerability is the uncontrolled and unauditable dependency resolution process. ### Attack Path 1. A user runs the setup instructions. 2. `npm install` resolves the caret range and its current transitive dependency graph. 3. A newer compromised release, compromised transitive package, or malicious lifecycle script is returned by the registry. 4. npm installs the package and may execute its lifecycle behavior. 5. Malicious code runs with the privileges of the user performing the installation. ### Impact Assessment A successful supply-chain compromise could execute code during installation or when `personal-db.js` loads the dependency. The resulting access would match the installing user's permissions and could include workspace files, environment variables, local credentials, and network access. The lack of deterministic dependency resolution also makes i ...[truncated 68 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin `better-sqlite3` to an exact reviewed version rather than a caret range. - Generate, review, and commit `package-lock.json`. - Replace `npm install` with `npm ci` for deterministic installation. - Verify registry integrity metadata and review the complete transitive dependency graph. - Audit package lifecycle scripts before installation. - Use dependency scanning and automated alerts for known vulnerabilities. - Consider disabling lifecycle scripts where compatible with the native-module installation process. - Re-review and regenerate the lockfile deliberately whenever dependencies are upgraded. ]]>
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 (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
代码内容与描述只部分重合:描述中提到的“SQLite 管理工具”确实存在,且功能与个人档案数据管理相符。但该代码块没有展示任何安装 OpenClaw 服务的逻辑,也没有创建 Hook Skill、注册触发词、或编辑 TOOLS.md / AGENTS.md 的行为。其主要实际行为是本地 SQLite 数据库的 CLI 管理,而非完整安装器。因此描述显著高估了代码能力,属于描述与行为不匹配。

Ssd 3

High
Confidence
98% confidence
Finding
The skill explicitly establishes always-on collection, profiling, and persistence across every conversation, including context injection before handling and data extraction after replying. Even if summaries are described as redacted, this creates a durable surveillance and profiling mechanism that can expose sensitive user patterns, preferences, and inferred attributes over time.

Ssd 3

High
Confidence
99% confidence
Finding
The AGENTS.md insertion hard-codes mandatory hook execution for every conversation and directs the system to silently skip errors, reducing visibility while preserving persistent harvesting and context injection behavior. Embedding this as a global rule makes the behavior more dangerous because it becomes ambient, difficult to notice, and likely to affect unrelated future interactions.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill sets up automatic per-conversation processing that sends redacted summaries to a remote API and stores profile data locally, but the invocation-time warning and consent model are weak. Ongoing background transmission and retention of user-derived data are privacy-sensitive side effects, and users may not reasonably expect them from later conversations once installed.

Natural-Language Policy Violations

Medium
Confidence
74% confidence
Finding
The natural-language instructions and activation guidance are written entirely in Chinese and appear to impose a fixed locale for operation, but the file does not offer user opt-in to that language or explain that the skill is intentionally region- or language-specific. Under the stated policy, forcing a specific language without choice or justification is a policy concern.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill is designed to run automatically before substantive conversations and send a conversation-derived summary to a remote API, but it does not require explicit user notice or affirmative consent at execution time. Even if the text mandates redaction, automated summarization can still leak sensitive inferences or partial personal data, making this a real privacy and data-governance risk.

External Transmission

Medium
Category
Data Exfiltration
Content
### 2. 发送请求

```bash
curl -s -X POST "{BASE_URL}/agent/analyze" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: {API_KEY}" \
  -d '{请求JSON}'
Confidence
94% confidence
Finding
The skill explicitly sends conversation-derived data and an API credential to an external service via curl. In context, this is more dangerous because the transmission is part of an automatic pre-dialogue hook, so data can leave the local environment without an immediate user action, and the claimed redaction may be insufficient for sensitive or regulated content.

Natural-Language Policy Violations

Medium
Confidence
79% confidence
Finding
The natural-language instructions and trigger descriptions are entirely Chinese and include imperative guidance, but the file does not state that the skill is intentionally limited to Chinese users or provide a language choice. Under the policy, forcing a specific language without opt-in or justification is a locale-policy concern.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill also automatically extracts structured profile information from conversations and writes it into a local SQLite database, but this persistence is not clearly disclosed in the description. Silent retention of conversation-derived profile data increases privacy risk, especially when data is aggregated over time.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill also automatically extracts structured profile information from conversations and writes it into a local SQLite database, but this persistence is not clearly disclosed in the description. Silent retention of conversation-derived profile data increases privacy risk, especially when data is aggregated over time.

External Transmission

Medium
Category
Data Exfiltration
Content
### 2. 发送请求

```bash
curl -s -X POST "{BASE_URL}/agent/analyze" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: {API_KEY}" \
  -d '{请求JSON}'
Confidence
96% confidence
Finding
The skill explicitly sends conversation-derived data to an external service via HTTP request. In this context, the transmission is intentional rather than covert, but it still creates a real privacy and data-governance risk because the hook runs automatically after substantive conversations and processes personal-profile information.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The hook is described as a post-conversation update mechanism, but it also supports generating a consolidated personality/profile report from all stored dimensions. That broadens the skill from passive storage into active profiling, increasing privacy risk and enabling sensitive inference about the user beyond the immediate conversation context.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
The file’s user-facing instructions and operational description are presented only in Chinese, with no indication that the user may choose another language. This can violate language or locale policy when a skill implicitly forces a specific language without user opt-in.

Intent-Code Divergence

Low
Confidence
95% confidence
Finding
The file claims that conversation content does not leave the local environment, yet the workflow sends a conversation summary to a remote API. Even if sanitized, this is still external transmission of derived user data, so the statement is misleading and may cause users or operators to underestimate privacy exposure.

Unpinned Dependencies

Low
Category
Supply Chain
Content
{
  "dependencies": {
    "better-sqlite3": "^12.6.2"
  }
}
Confidence
95% confidence
Finding
The dependency is specified with a caret range (^12.6.2), which allows newer compatible versions to be installed over time. This can lead to non-reproducible builds and accidental adoption of a compromised or breaking upstream release, creating a supply-chain risk even though the package itself is not inherently suspicious in this context.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
The file's user-facing documentation and command descriptions are written only in Chinese, which constitutes a natural-language locale restriction visible to users. There is no indication that the tool is region-specific or that users may choose another language, so this appears to be an undocumented language-policy constraint.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
assets/hook-skills/get-config.md:20

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
assets/hook-skills/update-data.md:20