Back to skill

Security audit

Smart Scheduler

Security checks for vulnerabilities and agentic risk

Overview

The skill is a task scheduler, but it under-discloses local service calls, persistent logging of user request text, and unsafe or contradictory execution-related code.

Review before installing. This skill may automatically route tasks, contact localhost services, and persist part of your prompts to a local stats file. Avoid using it with secrets or sensitive business data unless the logging and local service behavior are removed or explicitly controlled.

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
scheduler.py:384
Finding
Plaintext Persistence of User Request Content## Vulnerability Details **File Location**: `scheduler.py:384-390` and `resource_locator.py:332-342` **Vulnerability Type**: Plaintext storage of potentially sensitive user input **Risk Level**: Medium ### Vulnerable Code `scheduler.py:384-390`: ```python self.stats_collector.record({ 'input': user_input[:100], 'complexity': complexity.value, 'latency_ms': result.latency_ms, 'success': result.success }) ``` `resource_locator.py:332-342`: ```python def __init__(self, db_path: str = "/home/admin/.openclaw/workspace/data/scheduler_stats.jsonl"): self.db_path = db_path os.makedirs(os.path.dirname(db_path), exist_ok=True) def record(self, stats: Dict): """记录统计""" import time stats['timestamp'] = time.time() with open(self.db_path, 'a') as f: f.write(json.dumps(stats, ensure_ascii=False) + '\n') ``` ### Technical Analysis Every request handled by `SmartScheduler.handle()` has its first 100 characters included in a statistics record. `StatsCollector.record()` then appends that record to a persistent JSONL file at a fixed local path. The request content is stored without secret detection, redaction, encryption, an explicit retention policy, or an opt-out mechanism. The file is also opened without explicitly enforcing a restrictive permission mode. Consequently, its effective access permissions depend on the process umask and existing file permissions. The stored prefix may contain passwords, API tokens, personal information, customer data, source code, or other confidential content. Although only the first 100 characters are retained, users commonly place credentials and essential context near the beginning of requests. ### Attack Path 1. A user submits a scheduler request whose first 100 characters contain sensitive information. 2. `SmartScheduler.handle()` copies that prefix into the `input` statistics field. 3. `StatsCollector.record()` appends the complete record to `scheduler_stats.jsonl`. 4. Records acc ...[truncated 980 chars]
Remediation
## Remediation Suggestions 1. Remove raw user input from telemetry by default. Store only non-content metrics such as complexity, latency, and success status. 2. If request correlation is necessary, use a random request identifier rather than the request text. 3. If content retention is a required feature, obtain explicit user or administrator consent and document what is collected, why it is collected, and how long it is retained. 4. Apply structured redaction before persistence. Detect and remove credentials, authorization headers, API keys, passwords, tokens, personal identifiers, and other sensitive fields. 5. Implement bounded retention through record limits, time-based expiration, and secure deletion or rotation. 6. Use a configurable data path instead of a hard-coded account-specific location. 7. Create the statistics file with owner-only permissions, such as mode `0600`, and verify that the containing directory is not accessible to unrelated users. 8. Encrypt retained sensitive data at rest using a properly managed key if storing request content is unavoidable. 9. Add tests confirming that representative passwords, tokens, and personal data never appear in telemetry files.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
This finding indicates broader undeclared behavior, including local resource inspection (`/proc/meminfo`, skill directories, statistics files), local HTTP service access, and code generation/execution fallback. Those capabilities materially expand the attack surface and can enable environment reconnaissance, abuse of local services, or execution of untrusted generated code without clear disclosure.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
This finding indicates broader undeclared behavior, including local resource inspection (`/proc/meminfo`, skill directories, statistics files), local HTTP service access, and code generation/execution fallback. Those capabilities materially expand the attack surface and can enable environment reconnaissance, abuse of local services, or execution of untrusted generated code without clear disclosure.

Description-Behavior Mismatch

High
Confidence
96% confidence
Finding
This scheduler/resource locator contains logic for dynamic code generation and execution, which exceeds a routing component's stated purpose and creates a latent arbitrary-code-execution capability. Even though the active duplicate method later simulates execution, the presence of dormant real-execution logic indicates unsafe design drift and makes future refactors or merges likely to re-enable dangerous behavior unintentionally.

Context-Inappropriate Capability

High
Confidence
94% confidence
Finding
The code path builds Python source from task content and runs it via a Python interpreter, which is a powerful execution primitive not justified by a scheduler's role. In the context of an agent skill, task descriptions are often influenced by untrusted user input, so this design can turn normal task routing into code-execution if the dormant implementation is restored or copied elsewhere.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The code states that complex-task output must pass debate verification, but on any verifier exception it marks the result as passed and returns unverified content. This is a fail-open security/control bypass: an attacker who can trigger verifier errors can systematically skip the intended validation layer and obtain unchecked outputs.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill advertises capabilities that imply file, network, and shell access, but it does not declare any explicit tool scope or permission boundaries. This creates an authorization gap where the runtime may grant broader access than reviewers or users expect, increasing the risk of unintended filesystem access, command execution, or outbound requests.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
The manifest description and title are written entirely in Chinese, presenting the skill as Chinese-language by default. There is no indication that users may choose another language or that the locale restriction is intentional for a region-specific use case, which creates a natural-language policy concern.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The verifier sends task_result and optional context to another service for analysis, but there is no consent, disclosure, redaction, or data-classification check before transmission. Even though the endpoint is localhost, it is still a separate service boundary and may process sensitive prompts, business data, or personal information unexpectedly.

Internal Network Request

Medium
Category
Server-Side Request Forgery
Content
def _check_service(self) -> bool:
        """检查服务是否可用"""
        try:
            resp = requests.get("http://127.0.0.1:8002/health", timeout=5)
            return resp.status_code == 200
        except:
            return False
Confidence
70% confidence
Finding
Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

External Transmission

Medium
Category
Data Exfiltration
Content
"max_rounds": self.MAX_ROUNDS
        }
        
        resp = requests.post(
            self.DEBATE_URL,
            json=payload,
            timeout=self.timeout
Confidence
92% confidence
Finding
The code performs an HTTP POST to a separate debate service and includes user-derived content in the JSON payload. This creates a data exfiltration/privacy boundary and uses cleartext local HTTP, so any sensitive task output or context may be exposed to another component without strong transport assurances or explicit trust controls.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The comments claim isolated or sandboxed execution, but the implementation only runs python3.8 on a temporary file with a different cwd and a timeout. That provides no meaningful containment against filesystem access, environment access, network use, or subprocess spawning, so operators may falsely trust it as safe and expose themselves to broader compromise.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
temp_file = f.name
            
            # 3. 执行(隔离环境)
            result = subprocess.run(
                ['python3.8', temp_file],
                capture_output=True,
                text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The execute path forwards the entire task object to local HTTP services automatically, without validation, minimization, or user confirmation. In an agent environment, task payloads can contain sensitive prompts, secrets, file content, or personal data, so automatic transmission to sidecar services broadens data exposure and trust boundaries.

External Transmission

Medium
Category
Data Exfiltration
Content
"""执行本地程序"""
        import requests
        try:
            resp = requests.post(f"{url}/api/execute", json=task, timeout=30)
            return resp.json()
        except Exception as e:
            return {"success": False, "error": str(e)}
Confidence
85% confidence
Finding
The code transmits task data over HTTP to a local service endpoint, creating an external transmission boundary from this skill to another process. Although the destination is localhost, that still expands exposure to any local service bound there, and the scheduler context makes this more dangerous because it may automatically relay arbitrary task content as part of routine execution.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
There are two definitions of _run_self_generated; the later one overrides the earlier implementation in Python. As a result, despite earlier comments/docstrings claiming a '真实实现' that generates and executes code, the effective method only returns a mock success response, creating a direct contradiction between the documented intent and actual runtime behavior.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest and module docstring describe an intelligent scheduler that automatically routes tasks and integrates Socratic probing, task decomposition, resource location, and debate-based validation. In code, probing is a fixed stub (L228-L235), subtask execution is simulated with hardcoded completion messages (L281-L295), and simple-task skill invocation also returns placeholder responses rather than real routing or execution (L170-L177), so the described behavior materially overstates what the skill actually does.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The primary natural-language description and inline user-facing behavior are presented in Chinese, and the file contains no indication that users may choose another language or locale. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.

Ssd 3

Medium
Confidence
93% confidence
Finding
The scheduler persists slices of raw user input into stats/history, creating a built-in data retention path for potentially sensitive user content. In a task-routing skill, users may submit operational details, personal data, or secrets, so retaining plaintext inputs increases exposure in logs, memory, and any downstream persistence used by StatsCollector.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The top-level docstring presents the skill description entirely in Chinese and does not indicate that other languages are supported or that the locale restriction is intentional. Under the stated policy, forcing a specific language without opt-in can be a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The prominent natural-language documentation and labels are written in Chinese, and the skill does not indicate any option for language selection or explain a region-specific requirement. This can conflict with language/locale policy when users are not explicitly opted into that locale.

Static analysis

No suspicious patterns detected.