Back to skill

Security audit

Model Advisor

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it advertises, but it reads recent private OpenClaw conversation history and local configuration in ways that need clearer consent and scoping.

Review this skill before installing if your OpenClaw history may contain secrets, proprietary code, personal data, or confidential work. Prefer manual recommend mode with a task description unless you are comfortable letting it inspect recent local sessions; security mode should be used only when you intend to inspect local OpenClaw configuration.

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/advisor.js:176
Finding
Unrestricted Access to Private Conversation History<![CDATA[ ## Vulnerability Details **File Location**: `scripts/advisor.js:18-19, 176-231` **Vulnerability Type**: Excessive access to sensitive local session data **Risk Level**: Medium ### Complete Code Snippet ```js const SESSIONS_DIR = join(HOME, '.openclaw', 'agents', 'main', 'sessions'); const SESSIONS_META = join(SESSIONS_DIR, 'sessions.json'); function loadHistoryMessages(maxSessions = 5, maxMsgsPerSession = 50) { if (!existsSync(SESSIONS_DIR)) return []; let activeIds = []; if (existsSync(SESSIONS_META)) { try { const meta = JSON.parse(readFileSync(SESSIONS_META, 'utf8')); activeIds = Object.values(meta) .filter(s => s.sessionId) .sort((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0)) .slice(0, maxSessions) .map(s => s.sessionId); } catch { /* ignore */ } } if (activeIds.length === 0) { try { const files = readdirSync(SESSIONS_DIR) .filter(f => f.endsWith('.jsonl') && !f.includes('.deleted')) .slice(0, maxSessions); activeIds = files.map(f => f.replace('.jsonl', '')); } catch { /* ignore */ } } const messages = []; for (const id of activeIds) { const filePath = join(SESSIONS_DIR, `${id}.jsonl`); if (!existsSync(filePath)) continue; try { const lines = readFileSync(filePath, 'utf8').split('\n'); let count = 0; for (const line of lines) { if (!line.trim()) continue; try { const event = JSON.parse(line); if ( event.type === 'message' && event.message?.role === 'user' && Array.isArray(event.message.content) ) { const text = event.message.content .filter(c => c.type === 'text') .map(c => c.text ?? '') .join(' '); if (text.trim()) { messages.push({ text, timestamp: event.timestamp, sessionId: id }); count++; if (count >= maxMsgsPerSes ...[truncated 2636 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require explicit, informed consent immediately before accessing historical sessions. 2. Make manual `recommend <task>` mode the default and keep history analysis strictly opt-in. 3. Allow users to select the sessions or time range that may be analyzed. 4. Process one message at a time and retain only aggregate keyword counts rather than complete message text. 5. Do not store timestamps or session identifiers unless they are essential to the recommendation. 6. Apply maximum file-size and message-length limits before parsing transcripts. 7. Exclude content likely to contain secrets, such as authorization headers, private keys, access tokens, and password-like values. 8. Run history analysis in a restricted process with read access only to explicitly approved transcript files. 9. Document exactly which files are read, how many messages are processed, and whether any derived information is retained. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/advisor.js:16
Finding
Sensitive Configuration Files Loaded for Commands That Do Not Require Them<![CDATA[ ## Vulnerability Details **File Location**: `scripts/advisor.js:16-34, 410-411` **Vulnerability Type**: Unnecessary loading of potentially credential-bearing configuration **Risk Level**: Low ### Complete Code Snippet ```js const CONFIG_PATH = join(HOME, '.openclaw', 'openclaw.json'); const MODELS_PATH = join(HOME, '.openclaw', 'agents', 'main', 'agent', 'models.json'); function loadConfig() { if (!existsSync(CONFIG_PATH)) { console.error(`配置文件不存在: ${CONFIG_PATH}`); process.exit(1); } return JSON.parse(readFileSync(CONFIG_PATH, 'utf8')); } function loadModels() { if (!existsSync(MODELS_PATH)) return null; return JSON.parse(readFileSync(MODELS_PATH, 'utf8')); } ``` The functions are invoked unconditionally before command dispatch: ```js const cfg = loadConfig(); const models = loadModels(); if (cmd === 'security') { printSecurity(calcSecurity(cfg), cfg); } else if (cmd === 'recommend' && task) { const rec = recommendModel(task, models); printRecommendation(rec, task); } else if (cmd === 'auto') { const ana = analyzeHistory(models); printAutoRecommendation(ana); } ``` ### Technical Analysis The script parses the complete gateway and model-provider configuration files before determining which command was requested. Consequently: - `recommend` and `auto` load the complete gateway configuration even though they do not use it. - `security` loads the model-provider configuration even though it does not use it. - Commands with invalid arguments also load both files before printing usage information. OpenClaw configuration files may contain authentication tokens, provider credentials, endpoint details, or other sensitive values. The current implementation only prints selected gateway fields and model identifiers, and no direct credential disclosure was observed. However, parsing complete configuration objects unnecessarily places all fields into process memory and increases exposure to debugging tools, crash handlers, mal ...[truncated 1563 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate the command before opening any configuration file. 2. Load only the resources required by each command: - Load `openclaw.json` only for `security` and `full`. - Load `models.json` only for `recommend`, `auto`, and `full`. 3. Extract only the required fields into sanitized objects rather than retaining complete parsed configuration structures. 4. Store model identifiers in a credential-free inventory separate from provider authentication data. 5. Apply file-size limits and explicit schema validation before parsing JSON. 6. Catch parsing errors and return sanitized error messages that do not expose configuration content. 7. Ensure secrets are never included in diagnostic output, exception serialization, telemetry, or crash reports. 8. Clear references to sensitive objects as soon as processing is complete where practical. 9. Restrict configuration-file permissions to the owning user and avoid storing reusable plaintext credentials when a secure credential store is available. ]]>
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 (8)

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are broad enough to match ordinary conversation such as generic requests for recommendations or references to past history, which can cause the skill to activate outside its intended scope. Because the skill then reads recent session content and local configuration data, accidental invocation could expose private context or perform analysis the user did not explicitly request.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The manifest description and operational instructions are entirely in Chinese, and the trigger phrases are defined only in Chinese, which implies a fixed language expectation. There is no indication that users may interact in other languages or that the Chinese-only scope is an intentional, justified regional limitation.

Ssd 3

Medium
Confidence
87% confidence
Finding
The history-analysis feature is designed to harvest prior user messages and derive summary signals such as high-frequency keywords for output. Even without printing full messages, surfacing derived content from previous conversations can leak sensitive topics or confidential work patterns across contexts.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The auto-analysis path reads raw local session files from ~/.openclaw/.../sessions and inspects prior user message text without any explicit consent, scope limitation, or disclosure at runtime. Even though the stated feature is model recommendation based on history, the implementation accesses underlying conversation content directly, which creates a privacy boundary violation and broadens the tool's effective data access.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
Historical user session content is accessed silently from local storage, with no user-facing warning that prior conversations will be parsed. This can expose sensitive prompts, secrets, or personal data from earlier sessions to later outputs or operators who did not expect that cross-session reuse.

Ssd 3

Medium
Confidence
90% confidence
Finding
The auto mode reuses content from previous user conversations to generate recommendations and display top keywords, creating a cross-session data exposure path. In the context of an advisor skill, this is more dangerous because users may expect model recommendation logic, not that prior conversation content will be mined and reflected in new output.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The natural-language usage text, comments, and output strings are entirely in Chinese, which effectively forces a single language experience for users. The file does not offer language selection or explain that the skill is intentionally limited to a Chinese-speaking context.

Context-Inappropriate Capability

Low
Confidence
72% confidence
Finding
Although the manifest mentions OpenClaw security scoring, the implemented capability performs detailed inspection of local gateway auth mode, bind mode, Tailscale settings, runtime mode, and denied commands. This is a configuration-auditing capability over sensitive local setup data, which is broader than ordinary model recommendation and should be treated as a separate privileged function.

Static analysis

No suspicious patterns detected.