Back to skill

Security audit

Huahua Dream

Security checks for vulnerabilities and agentic risk

Overview

The skill has a legitimate memory-maintenance purpose, but it enables recurring access to private session logs and persistent memory changes with weak consent controls and overbroad session discovery.

Review before installing. Only enable it if you want an unattended agent to read conversation logs and modify long-term memory files. Before using cron, verify dream-config.json points to the intended workspace and agent sessions, change the timezone, keep backups of MEMORY.md, and prefer manual review or explicit opt-in instead of autoApprove.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/setup.js:64
Finding

Cross-Workspace Agent Session Discovery Can Expose Unrelated Conversation Logs

Content
View full analysis
{ const sessDir = path.join(agentsDir, d, 'sessions'); return fs.existsSync(sessDir) && fs.statSync(sessDir).isDirectory(); }); if (agents.length > 0) { // Pick the agent with the most session files (likely the primary agent) let best = null; let bestCount = 0; for (const agent of agents) { const sessDir = path.join(agentsDir, agent, 'sessions'); const files = fs.readdirSync(sessDir).filter(f => f.endsWith('.jsonl')); if (files.length > bestCount) { bestCount = files.length; best = { agentId: agent, sessionsPath: sessDir }; } } if (best) return best; } } const parent = path.dirname(dir); if (parent === dir) break; // reached filesystem root dir = parent; } return null; } ``` ### Technical Analysis The setup process walks upward from the selected workspace to the filesystem root while searching for an `.openclaw/agents` directory. Once one is found, it enumerates every agent beneath that directory and automatically chooses the agent with the largest number of `.jsonl` session files. No check establishes that the selected agent belongs to the requested workspace, is owned by the current user, or was explicitly selected for memory processing. The generated configuration records the selected session directory, and the documented dream workflow subse ...[truncated 1541 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/setup.js:179
Finding

Memory-Modification Consent Defaults to Approval and Is Not Enforced at Runtime

Content
View full analysis
{ const autoApprove = answer.toLowerCase() !== 'n'; config.autoApprove = autoApprove; // 重新写入配置 fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2)); ``` The runtime configuration loader does not return the stored `autoApprove` value: ```js function loadConfig(workspace) { const baseDir = path.dirname(path.dirname(__filename)); const configPath = path.join(baseDir, 'assets', 'dream-config.json'); if (!fs.existsSync(configPath)) { console.error(JSON.stringify({ error: 'Config not found', path: configPath })); process.exit(1); } const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); // Use workspace argument if provided, otherwise use config const ws = workspace || config.workspace; return { workspace: ws, sessionsPath: config.sessionsPath, dreamsDir: config.dreamsDir || path.join(ws, 'memory', 'dreams'), dreamLock: config.dreamLock || path.join(ws, 'memory', 'dreams', '.dream-lock'), baseDir }; } ``` The mutating finalization operation writes files without checking authorization: ```js function doFinalize(workspace) { const config = loadConfig(workspace); // Ensure dreamsDir exists const dreamsDir = path.dirname(config.dreamLock); if (!fs.existsSync(dreamsDir)) { fs.mkdirSync(dreamsDir, { recursive: true }); } // Save previous value const prevPath = config.dreamLock + '.prev'; if (fs.existsSync(config.dreamLock)) { const prev = fs.readFileSync(config.dreamLock, 'utf8'); fs.writeFile ...[truncated 2169 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (20)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README hard-codes the cron timezone to "Asia/Shanghai" in the example configuration without any indication that this should be adapted to the user's locale or confirmed during setup. In an agent skill that performs autonomous nighttime memory maintenance, an incorrect timezone can cause the job to run at unintended hours, potentially processing data while the user is active or outside expected maintenance windows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs the agent to read, summarize, and persist user conversation content but does not present a clear privacy notice, consent model, retention policy, or data-scope limitation. In this context, that omission is dangerous because the skill is expressly designed for long-term memory formation and self-reflection about the human, increasing the chance of collecting and retaining sensitive personal data without informed consent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases are broad enough to activate during ordinary conversation, which can cause the agent to invoke memory-consolidation behavior without clear, context-specific user intent. In this skill, accidental invocation is more dangerous because the action reads prior conversations and writes persistent memory, creating privacy and integrity risks from an ambiguous prompt.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill tells the agent to elevate repeated user-provided information or explicit cues like 'remember this' into persistent memory, without requiring sensitivity screening, minimization, or a consent boundary. This is dangerous because users may reveal personal, confidential, or regulated data in conversation, and repetition-based promotion can silently convert transient chat into durable profiling data.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The self-reflection section directs the agent to infer and record the human's feelings, relationship evolution, and contextual dynamics from conversation tone and corrections. That creates behavioral profiling and sentiment inference about a person, which is particularly risky because the resulting judgments may be inaccurate, sensitive, and stored persistently as part of long-term memory.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Persisting an authorization result in an 'autoApprove' field enables future memory-management actions to proceed without renewed user confirmation. In a skill that reads conversations and writes or prunes long-term memory, this increases the risk of overbroad autonomous data handling if the original consent was uninformed, stale, or too general.

Content

Scanner excerpt · SKILL.md (reported line 204)May include surrounding context.

md
## 5. Edge cases

- **首次运行**:setup.js 会询问授权,结果保存到 `dream-config.json` 的 `autoApprove` 字段。未授权时仅预览变更,不写入文件。
- **执行后通知**:每次梦境完成后发送报告,包含记忆变化摘要。支持 `/dream-rollback` 回滚。
- **变化超过50%**:不写入 MEMORY.md,保存为 `MEMORY.md.proposed`,通知用户审核
- **连续梦境跳过**:如果多次门控检查失败,发送通知让用户知道 AI 在等待新会话

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script presents itself as simple setup that generates runtime config, but it additionally asks for authorization for recurring automated maintenance and references cron-based execution. Bundling setup with operational consent can mislead users into granting broader authority than expected during installation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The header claims the script only reads filesystem structure and writes a config, but later it also solicits consent for future automated processing of session records and memory files and persists that authorization. This is a misleading security disclosure: users and reviewers may underestimate the script's role in enabling later sensitive actions, which weakens informed consent and safe review.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script discovers agent/session locations by traversing parent directories and then writes those sensitive paths and agent IDs into a config file before any user-facing notice or confirmation. Persisting session metadata can expose where potentially sensitive conversation logs live and broaden access by downstream components that read the config.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
92% confidence
Finding

This section introduces an 'auto-approve' authorization flow for later autonomous behavior during a setup script, expanding the script from configuration discovery into delegation of future decision-making. In the context of a skill that may later read and rewrite memory artifacts, enabling autonomy at setup time raises the risk of overbroad authorization.

Content

Scanner excerpt · scripts/setup.js (reported line 172)May include surrounding context.

js
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
console.log(`✅ Config saved: ${CONFIG_FILE}`);

// === Auto-approve prompt ===
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The interactive authorization flow is presented in Chinese only, even though the rest of the script and usage text are in English. This imposes a specific language on users without opt-in or justification, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The prompt requests broad authorization to read session records and notes, update MEMORY.md, and mark or delete entries, enabling future automated modification of sensitive user memory data. Because the consent is broad and paired with a default-yes behavior, users may unknowingly authorize destructive or privacy-invasive actions beyond basic setup.

Content

No source excerpt is available for this finding.

Ssd 4

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The consent text combines reassuring maintenance language, rollback claims, and reports with escalating permission for autonomous recurring actions over sensitive memory data. This trust-building framing can manipulate users into approving broader autonomy than they intended, especially when tied to scheduled execution and deletion capability.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
98% confidence
Finding

The prompt interprets anything other than 'n' as approval, making the default effectively yes for autonomous execution over sensitive data. This is dangerous because accidental input, misunderstanding, or simply pressing Enter grants ongoing authority for future automated actions.

Content

Scanner excerpt · scripts/setup.js (reported line 187)May include surrounding context.

js
console.log('每次执行后会发送报告,支持回滚。');

rl.question('\n是否授权自动执行?(y/n,默认y): ', (answer) => {
  const autoApprove = answer.toLowerCase() !== 'n';
  config.autoApprove = autoApprove;

  // 重新写入配置

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
97% confidence
Finding

Persisting config.autoApprove records ongoing authorization for future autonomous behavior, creating a durable capability flag that downstream components may trust without renewed consent. In this skill context, that authorization can enable repeated access to and modification of memory/session data without fresh user review.

Content

Scanner excerpt · scripts/setup.js (reported line 188)May include surrounding context.

js
rl.question('\n是否授权自动执行?(y/n,默认y): ', (answer) => {
  const autoApprove = answer.toLowerCase() !== 'n';
  config.autoApprove = autoApprove;

  // 重新写入配置
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
96% confidence
Finding

The success message states that authorized automatic execution will begin on the next cron trigger, normalizing recurring autonomous action immediately after a weak-consent prompt. This increases the likelihood users believe scheduled destructive or privacy-sensitive behavior is routine and already safely configured.

Content

Scanner excerpt · scripts/setup.js (reported line 193)May include surrounding context.

js
// 重新写入配置
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));

  console.log(autoApprove
    ? '✅ 已授权自动执行。首次执行将在下次 cron 触发时开始。'
    : '⏸️ 未授权自动执行。你可以手动运行或稍后在 dream-config.json 中设置 autoApprove: true。');

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
95% confidence
Finding

Directing the user to configure a cron job immediately after setting autoApprove operationalizes persistent autonomous behavior over sensitive files. In this context, the setup script is not merely informational; it steers the user toward installing unattended execution of a component that may later alter or delete memory data.

Content

Scanner excerpt · scripts/setup.js (reported line 195)May include surrounding context.

js
console.log(autoApprove
    ? '✅ 已授权自动执行。首次执行将在下次 cron 触发时开始。'
    : '⏸️ 未授权自动执行。你可以手动运行或稍后在 dream-config.json 中设置 autoApprove: true。');

  console.log('\nNext: configure a cron job to run the dream. See SKILL.md for details.');
  rl.close();

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest advertises a gate of '24小时+5次会话才触发', implying at least 5 sessions are required before a dream run. But the operational steps later state '< 1 次会话 → 跳过', which means 1 or more sessions is sufficient. This is an active contradiction in the skill's own intent/documentation about when execution should occur.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The architecture table says the components are dream.js and setup.js, suggesting those files exist at the skill root. Later usage examples invoke scripts/setup.js, and the tool table shows node dream.js while earlier installation text uses {baseDir}/scripts/setup.js; this creates contradictory documentation about where the implementation actually lives. While not a code-behavior issue, it is a direct intent/documentation inconsistency that can mislead execution and auditing.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The cron example specifies tz: "Asia/Shanghai", which imposes a locale-specific setting in the natural-language guidance. There is no indication that the timezone is optional, configurable, or justified as region-specific behavior, so it can violate language/locale neutrality expectations.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.