Back to skill

Security audit

Model Fallback Retry

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its retry purpose, but it broadly stores full conversation outputs and queued user messages for automatic replay without enough disclosure or controls.

Install only if you are comfortable with this plugin observing all agent completions, storing full AI replies and failed user messages locally, and using a recurring retry job to resend queued content. Review file permissions, retention, cron entries, and whether sensitive conversations should be excluded before enabling it.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
plugin/index.mjs:157
Finding

Unnecessary Plaintext Storage of Complete AI Responses and Session Identifiers

Content
View full analysis

Vulnerability Details

File Location: plugin/index.mjs, lines 157-178; invoked at line 339
Vulnerability Type: Plaintext storage of sensitive conversation data
Risk Level: Medium

Vulnerable Code

js
function logAIReply(sessionKey, output, success, messages) {
  try {
    let logs = [];
    if (fs.existsSync(DATA_FILE)) {
      logs = JSON.parse(fs.readFileSync(DATA_FILE, "utf-8"));
    }

    const entry = {
      timestamp: new Date().toISOString(),
      sessionKey,
      outputLength: output.length,
      outputPreview: output.substring(0, 200),
      fullOutput: output,
      success,
      isQuotaError: isQuotaError(output),
    };

    logs.push(entry);

    // 保留最近 200 条
    if (logs.length > 200) {
      logs = logs.slice(-200);
    }

    fs.writeFileSync(DATA_FILE, JSON.stringify(logs, null, 2), "utf-8");

The function is called for every completed agent interaction:

js
// 记录所有 AI 回复
logAIReply(sessionKey, lastOutput, success, messages);

Technical Analysis

The plugin writes the complete output of every AI response to ~/.openclaw/skills/model-fallback-retry/ai_replies_log.json. Each record includes the full response, a preview, the session identifier, and interaction metadata.

Full response storage is not required for the plugin's core retry function. Retryable conditions can be recorded using an error classification, timestamp, and queue identifier without retaining complete conversation content. Because fs.writeFileSync() is called without an explicit restrictive mode, the code relies on ambient process and directory permissions. It also provides no content redaction, encryption, diagnostic-logging opt-in, or immediate deletion policy.

The file retains up to 200 complete responses. These responses may contain credentials, personal data, internal business information, source code, system details, or other confidential material returne ...[truncated 1788 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove fullOutput and outputPreview from persistent logs by default.
  2. Record only the minimum metadata required for retry diagnostics, such as timestamp, generated queue ID, normalized error category, HTTP status, and retry count.
  3. Make detailed diagnostic logging explicitly opt-in and display a warning that conversation content may be stored.
  4. Apply redaction before persistence, including removal of access tokens, API keys, passwords, cookies, personal identifiers, and other configurable sensitive patterns.
  5. Create log and queue files with owner-only permissions, such as mode 0600, and ensure the containing directory is mode 0700.
  6. Use atomic file creation and replacement so existing file permissions are not unintentionally widened.
  7. Define a short, configurable retention period based on time rather than retaining a fixed number of complete responses.
  8. Delete retry records immediately after completion unless minimal audit metadata is explicitly required.
  9. Consider encryption at rest when original user messages must be retained for delayed replay.
  10. Avoid storing raw session identifiers when a one-way hash or random internal correlation identifier is sufficient.
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (23)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README emphasizes zero message loss, queueing to retry_queue.json, and automatic resend behavior, but does not prominently warn that user messages will be persisted and retransmitted later. This creates privacy and consent risks because potentially sensitive message contents may be stored on disk and resent automatically without the user's informed approval.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The README states the skill will automatically detect the tenant_id and create a cron job during installation, which expands behavior beyond simple retry logic into environment discovery and system-level persistence. Even if intended for convenience, undocumented auto-discovery and scheduler modification increase privilege scope and can surprise users, making misuse or unintended persistence harder to detect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The installation instructions say the skill will automatically create a cron task, but do not explicitly warn that it modifies the user's system scheduler. Silent persistence through scheduler changes is security-relevant because it introduces ongoing background execution that users may not expect or know how to audit or remove.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly promises 'zero message loss' via automatic retry, and the architecture describes writing original messages and error details into a local JSON retry queue and resending them later, but the top-level description does not clearly warn users that their content will be persisted and replayed automatically. This creates a privacy and consent problem because sensitive prompts, identifiers, or regulated data may be stored and retransmitted without the user's awareness, increasing the exposure window and risk of unintended disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documented queue format stores sessionKey, originalMessage, and errorOutput in plain JSON, which can contain sensitive user content and identifiers, yet the documentation does not warn about confidentiality risks or storage protections. In the context of a retry system that persists and later replays messages across chat channels, plaintext local storage meaningfully increases the chance of data leakage through host compromise, backups, logs, or overly broad file permissions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The natural-language text in the file, including the top-level comment and multiple runtime log messages, is written in Chinese, which indicates the skill is oriented to a specific language/locale without offering user choice or documenting a justified region-specific constraint. The policy requires avoiding language/locale forcing unless the user can opt in or the locale limitation is clearly justified.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The retry queue persists the full original user message to disk for every intercepted failure. This exceeds what is required for duplicate detection and retry scheduling, and it can expose sensitive user inputs such as credentials, personal information, or confidential business data to anyone or anything that can read the local files.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The combined design stores both original user messages and full model outputs in persistent queue and log files, creating a broad data-retention surface for natural-language secrets and personal data. Because these files live in a predictable path in the user's home directory, they become a durable target for local attackers, malware, backup leakage, or unintended access by other tools.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The plugin writes full AI outputs, including a 200-character preview and complete response body, to a persistent file under the user's home directory. For a retry-focused plugin, retaining full model outputs is unnecessary and increases the risk of leaking sensitive prompts, secrets, personal data, or proprietary content through local compromise, backup systems, or other plugins/processes with filesystem access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The plugin persistently logs full AI replies to disk and also prints user-derived message snippets and error data to the console without any user-facing disclosure or consent mechanism. This creates a privacy and data-handling risk because sensitive conversational content may be exposed through logs, terminal history, process supervisors, or shared development environments.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The description states that the plugin captures LLM output for quota or limit analysis, but it does not define what data is captured, under what conditions, or what safeguards apply. For a component handling model outputs, missing scope and operational constraints can mask overcollection of sensitive prompts, responses, or derived metadata.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The plugin is configured to activate on every startup while also declaring hooks that can observe model lifecycle events. In the context of a plugin described as capturing LLM output, broad startup activation increases the chance of unnecessary data collection, expands exposure surface across all sessions, and makes the behavior harder to constrain or audit.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The parser is explicitly designed around Chinese-only command forms such as "#清空" and "#队列状态", and the surrounding natural-language documentation presents these as the expected commands without offering a language choice. This creates a locale/language policy concern because the skill appears to enforce a specific language rather than allowing user opt-in or documenting a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code file contains natural-language documentation that fixes the skill's explanatory text to Chinese, and similar Chinese-only docstrings continue throughout the file. The policy allows locale constraints only when users are given a choice or when the constraint is clearly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module persists queue data to a local JSON file, including sender identifiers, session keys, original message content, and error details, without any evident minimization, encryption, permission hardening, or retention control for pending items. If the host is shared, backups are exposed, or local files are readable by unintended users or processes, sensitive user data can be disclosed.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstring says the exponential backoff uses "initial_wait_minutes * 2^(retry_count)" and gives examples in minutes, but earlier enqueue logic stores the first retry using config field "initial_wait_hours" and this function reads "initial_wait_minutes" from the message with a default of 30. This is an active contradiction in intent/documentation because the codebase documents one retry policy while implementing another unit/configuration scheme.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

The function sends message content and a session identifier to the external openclaw sessions send command, which is a network or inter-process transmission of user/system data. Although the module docstring mentions retry behavior, there is no explicit user-facing warning, confirmation, or disclosure here that queued original message content will be resent automatically by a cron job.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/retry_worker.py (reported line 81)May include surrounding context.

python
session_key,
            "--message", message
        ]
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file contains multiple natural-language entries solely in Chinese, which can amount to a language/locale policy issue when no user opt-in or justification is provided. The file does not indicate that the project is intentionally region-specific or that alternate language support is available.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The natural-language instructions, commands, and operational guidance are presented entirely in Chinese, which effectively forces a specific language for users reading and operating the skill. Under the stated policy, language constraints should either be optional for the user or explicitly documented as justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The plugin description implies automatic capture of LLM output without mentioning user choice, consent, or privacy controls. While the manifest alone does not prove exfiltration, silent collection of model outputs can expose sensitive user data and is especially concerning because outputs may contain secrets, personal information, or proprietary content.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The top-level documentation describes this as a retry-logic module invoked by cron to inspect the queue and execute retries. In addition to retrying sends, the implementation mutates persistent queue state by moving items from pending to completed and saving updated status metadata, which is a broader behavior than the docstring states.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code file includes its primary human-readable description entirely in Chinese, including the module docstring describing purpose and invocation. Under the policy, forcing a specific language without user opt-in or documented regional justification is a natural-language locale violation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.