Back to skill

Security audit

daily-report-bian

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its daily-report purpose, but it reads sensitive Feishu session history and memory with weak scoping and can persist or route summaries in ways users should review carefully.

Review this skill before installing in any shared or multi-user OpenClaw environment. It should be limited to a specific Feishu user or conversation, show a report preview before sending, and make memory writes optional or clearly confirmed, especially if chats or memory files may contain confidential business or personal information.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
generate.js:37
Finding
Cross-User Disclosure Through Global Feishu Session Selection<![CDATA[ ## Vulnerability Details **File Location**: `generate.js:37-88` **Vulnerability Type**: Missing user-to-session authorization binding **Risk Level**: High ### Vulnerable Code ```js const SESSIONS_DIR = '/root/.openclaw/agents/main/sessions'; const SESSIONS_FILE = path.join(SESSIONS_DIR, 'sessions.json'); // Read sessions.json and locate the latest Feishu session const sessionsData = JSON.parse(fs.readFileSync(SESSIONS_FILE, 'utf-8')); // Find the latest Feishu session file let latestFeishuSession = null; let latestTime = 0; for (const [key, session] of Object.entries(sessionsData)) { if (key.includes('feishu:direct') && session.updatedAt) { if (session.updatedAt > latestTime) { latestTime = session.updatedAt; latestFeishuSession = session; } } } if (!latestFeishuSession || !latestFeishuSession.sessionFile) { console.log('⚠️ No Feishu session found; skipping session history'); return ''; } const sessionFile = latestFeishuSession.sessionFile; if (!fs.existsSync(sessionFile)) { console.log('⚠️ Session file does not exist:', sessionFile); return ''; } // Read the JSONL file const lines = fs.readFileSync(sessionFile, 'utf-8').split('\n'); const messages = []; const today = new Date(); const todayStr = today.toISOString().split('T')[0]; lines.forEach(line => { if (!line.trim()) return; try { const entry = JSON.parse(line); if (entry.type === 'message' && entry.message) { const timestamp = new Date(entry.timestamp).toISOString().split('T')[0]; if (timestamp >= todayStr) { messages.push({ role: entry.message.role, content: entry.message.content?.[0]?.text || '' }); } } } catch (e) { // Skip lines that cannot be parsed } }); ``` ### Technical Analysis The report generator does not bind session selection to an explicitly authorized Feishu user, conversation identifier, or report recipient. Instead, it iterates over every entry whose key contai ...[truncated 1706 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add an explicit authorized Feishu user ID, conversation ID, or session key to the configuration. 2. Resolve only the session associated with that configured identity; do not select a direct-message session globally by timestamp. 3. Verify that the source-session owner matches the intended report recipient before reading the session file. 4. Reject ambiguous, missing, or mismatched identity information and fail closed rather than falling back to another recent session. 5. Validate that `sessionFile` resolves beneath the expected sessions directory before reading it. 6. Apply least-privilege filesystem permissions so the report process can access only the intended session and memory files. 7. Record source and destination identity metadata in audit logs without logging message content. 8. Add automated tests involving multiple simultaneous Feishu users to ensure that content cannot cross conversation boundaries. ]]>

T02 · Agent Memory Poisoning

Warning
Location
generate.js:412
Finding
Persistent Memory Poisoning Through Untrusted Conversation Content<![CDATA[ ## Vulnerability Details **File Location**: `generate.js:65-88, 136-162, 238-268, 412-423` **Vulnerability Type**: Unsanitized persistence of attacker-controlled conversation text **Risk Level**: Medium ### Vulnerable Code The session reader obtains user-controlled message text: ```js lines.forEach(line => { if (!line.trim()) return; try { const entry = JSON.parse(line); if (entry.type === 'message' && entry.message) { const timestamp = new Date(entry.timestamp).toISOString().split('T')[0]; if (timestamp >= todayStr) { messages.push({ role: entry.message.role, content: entry.message.content?.[0]?.text || '' }); } } } catch (e) { // Skip lines that cannot be parsed } }); ``` Broad regular expressions extract fragments from that text: ```js function extractProgressFromSession(sessionText) { if (!sessionText) return []; const projects = []; const patterns = [ /(?:准备 | 正在 | 完成 | 搞定|done)\s*(?:的 | 了)?\s*[\u4e00-\u9fa5A-Za-z]{3,20}/g, /(?:研究 | 开发 | 配置 | 设置 | 创建|安装)\s*[\u4e00-\u9fa5A-Za-z\-]{3,30}/g, ]; patterns.forEach(pattern => { const matches = sessionText.match(pattern); if (matches) { matches.forEach(match => { const name = match.replace(/(?:准备 | 正在 | 完成 | 搞定|done|的 | 了|研究 | 开发 | 配置 | 设置 | 创建 | 安装)/g, '').trim(); if (name.length >= 2 && name.length <= 20) { projects.push({ name: name, progress: match }); } }); } }); return projects.slice(0, 5); } ``` The extracted data is rendered as prose: ```js function generateTodayProgress(sessionText, todayMemory) { const allProjects = []; if (sessionText) { const sessionProjects = extractProgressFromSession(sessionText); sessionProjects.forEach(p => { allProjects.push({ name: p.name, progress: p.progress }); }); } if (todayMemory) { let content = todayMemory.content; const report ...[truncated 3572 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat all conversation-derived content as untrusted data and label it with source identity and provenance. 2. Store extracted projects in a structured format with a strict schema rather than appending free-form Markdown prose to Agent memory. 3. Allow only expected project-name and status fields, with conservative character, length, and semantic validation. 4. Detect and reject instruction-like phrases or control text before persistence. 5. Require explicit user confirmation before adding conversation-derived information to long-term memory. 6. Separate generated reports from trusted Agent memory so later models cannot confuse report content with system instructions. 7. Replace the existing generated report section instead of appending another copy on each execution. 8. Use stable record identifiers or content hashes to prevent duplicate and recursive propagation. 9. When memory is supplied to a model, wrap it as quoted untrusted data and explicitly instruct the model not to follow directives found inside it. 10. Add tests for malicious project names, prompt-like text, duplicate generation, and propagation across the configured lookback period. ]]>
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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (10)

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill explicitly states it reads same-day Feishu conversation JSONL files and the last 7 days of memory files, but it does not warn the user that private conversation history and stored memory will be accessed. This creates a meaningful privacy and consent risk because the skill processes potentially sensitive personal or business data without clear upfront disclosure or opt-in.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill says it appends the generated report into the current day's memory file but does not warn the user that it performs persistent writes to memory. This is dangerous because generated summaries may contain inaccuracies, sensitive content, or duplicated/private material that then becomes part of future context and can propagate across later tasks.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill describes automatic pushing of reports via Feishu private chat, including a default scheduled delivery time, without clearly warning the user that summaries derived from conversations and memory will be transmitted externally. This increases the risk of unintended disclosure of confidential information through an automated outbound channel.

Ssd 3

Medium
Confidence
90% confidence
Finding
The documented behavior explicitly includes reading current session records, reading recent memory files, generating a report, and updating memory. In this context, the feature design itself creates a data-retention and secondary-use channel where conversational and memory content can be consolidated and persisted beyond its original context.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill reads session history and memory files that may contain user prompts, assistant replies, and other sensitive workspace data without any consent gate, notice, or scope restriction. This creates a privacy issue because data collected for one purpose is silently repurposed into a generated report and persisted again.

Ssd 3

Medium
Confidence
95% confidence
Finding
The code converts session messages into plain report text and later appends generated output into a persistent memory file. That creates a straightforward leakage path: sensitive user inputs present in session history can be transformed into durable natural-language summaries and retained in locations the user may not expect.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The script invokes an external CLI via execSync to gather context usage. Even though the command string is constant and not directly attacker-controlled, spawning a shell-capable subprocess adds unnecessary execution capability for a reporting tool and expands the attack surface through PATH hijacking, unexpected CLI behavior, or environment manipulation.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The skill sets a default timezone of Asia/Shanghai without indicating user choice or opt-in. While lower severity than the privacy issues, this can cause reports or scheduled pushes to occur at unexpected times, which may indirectly increase the chance of accidental disclosure if messages are sent when the user does not expect them.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The timestamp is explicitly formatted with the zh-CN locale and Asia/Shanghai timezone, and the surrounding output/comments are also Chinese-specific. This imposes a specific language/locale choice without offering the user an option or documenting a justified region-specific constraint.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The entire template is written in Chinese, which implies the skill will generate reports in a specific language by default. Under the policy criteria, forcing a specific language without offering user choice or documenting a justified locale constraint is a natural-language policy violation.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
generate.js:186