Back to skill

Security audit

ZworkerAgentSkillOpenClaw

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its stated zworker-control purpose, but it can run automations, change schedules, sync user identifiers, and forward messages through an unauthenticated local API.

Install only if you intentionally use zworker locally and trust the service on localhost:18803. Review message-forwarding behavior, avoid ambiguous/default recipients, and be cautious because the skill can trigger tasks and change schedules without an authentication layer shown in the artifact.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/zworker_api.py:22
Finding
Unauthenticated Localhost API Used for Privileged Automation Control<![CDATA[ ## Vulnerability Details **File Location**: `scripts/zworker_api.py:22, 29-90`; related security assumptions in `SKILL.md:126-132` **Vulnerability Type**: Unauthenticated plaintext control channel **Risk Level**: Medium ### Complete Code Snippet ```python BASE_URL = "http://localhost:18803" TIMEOUT = 10 # seconds def _make_request(method: str, endpoint: str, params: Optional[Dict] = None, data: Optional[Dict] = None) -> Dict[str, Any]: """ Send an HTTP request to the zworker API. """ url = f"{BASE_URL}{endpoint}" if HAS_REQUESTS: try: if method.upper() == 'GET': response = requests.get(url, params=params, timeout=TIMEOUT) else: headers = {'Content-Type': 'application/json'} response = requests.post( url, params=params, json=data, headers=headers, timeout=TIMEOUT ) response.raise_for_status() result = response.json() except requests.exceptions.RequestException as e: raise ZworkerAPIError(f"HTTP request failed: {e}") except json.JSONDecodeError as e: raise ZworkerAPIError(f"Response JSON parsing failed: {e}") else: try: if params: from urllib.parse import urlencode url = f"{url}?{urlencode(params)}" req_data = None headers = {} if method.upper() == 'POST' and data: req_data = json.dumps(data).encode('utf-8') headers = {'Content-Type': 'application/json'} req = urllib.request.Request( url, data=req_data, headers=headers, method=method.upper() ) with urllib.request.urlopen(req, timeout=TIMEOUT) as response: response_data ...[truncated 3234 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require a cryptographically random, per-installation API credential and send it in an authorization header. 2. Store the credential using an operating-system credential manager rather than in source code or command-line arguments. 3. Prefer an authenticated Unix-domain socket with restrictive filesystem permissions where platform support permits it. 4. If TCP must be used, bind explicitly to the loopback interface and verify that the zworker service never listens on external interfaces. 5. Consider TLS with certificate pinning or another server-authentication mechanism when the API crosses a meaningful process or container boundary. 6. Validate responses against endpoint-specific schemas, including expected types, permitted fields, size limits, and bounded list lengths. 7. Apply maximum response-body limits before JSON parsing. 8. Run the zworker service and Skill with the minimum permissions required. 9. Reject operations when authentication or service identity verification fails rather than falling back to unauthenticated behavior. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch_notifications.py:21
Finding
Unvalidated Service-Controlled Notification Routing and Content<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch_notifications.py:21-41`; forwarding workflow defined in `SKILL.md:40-52` **Vulnerability Type**: Confused-deputy message forwarding **Risk Level**: Medium ### Complete Code Snippet ```python try: result = get_claw_message(args.claw_type) # Validate required fields channel = result.get('channel', '') message = result.get('message', '') if not channel or not message: print( f"Error: Invalid notification data; channel or message is empty: {result}", file=sys.stderr ) sys.exit(1) userid = result.get('userid', '') if args.output_format == 'json': output = { 'channel': channel, 'userid': userid, 'message': message, 'raw': result } print(json.dumps(output, ensure_ascii=False, indent=2)) ``` ### Technical Analysis Notification data is obtained from the unauthenticated localhost API and validated only for the presence of nonempty `channel` and `message` values. The implementation does not enforce: - An allowlist of permitted channels. - An allowlist or authorization check for recipient identifiers. - A maximum message size. - A permitted content type or character policy. - A requirement that the recipient correspond to the user who initiated the operation. - Confirmation before using a default or recently active recipient. - A rule that returned message content must be treated exclusively as opaque data. The script itself prints the retrieved notification rather than directly invoking an outbound messaging API. However, the workflow in `SKILL.md:40-52` instructs the Agent to use its message tool to forward these service-provided fields. Consequently, the security boundary includes both the script output and the documented Agent workflow. Because the source service is unauthenticated, a malicious or impersonated local service can control the destin ...[truncated 1636 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Authenticate the zworker API before trusting any notification data. 2. Restrict `channel` to an explicit allowlist derived from trusted local configuration. 3. Verify that `userid` belongs to an approved recipient set and is authorized for the selected channel. 4. Do not automatically select a default or recently active recipient when `userid` is empty; require an explicit trusted mapping or user confirmation. 5. Enforce message-size and response-size limits. 6. Treat returned message content strictly as opaque text and never as Agent instructions, tool directives, markup requiring execution, or confirmation of privileged actions. 7. Require user confirmation before forwarding to a new recipient or before sending sensitive, unusually large, or high-volume content. 8. Add rate limiting, replay protection, deduplication, and auditable message identifiers. 9. Return only normalized fields from the script; avoid including the unrestricted raw API response unless required. 10. Log the authenticated source, selected destination, and delivery result without logging secrets or unnecessary personal data. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (22)

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill declares capabilities to read local configuration and make HTTP requests to a localhost service, but it does not declare any explicit tool scope or permission boundary. This weakens reviewability and least-privilege controls, making it easier for the skill to access sensitive local data or invoke local services without clear user-visible authorization.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The activation condition says to use the skill whenever the user mentions the keyword 'zworker', which is overly broad and can trigger privileged actions outside clear user intent. In a skill that can sync user identities, forward messages, and execute tasks, accidental invocation materially increases the chance of privacy or integrity-impacting actions.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill processes potentially sensitive identifiers and message content, but it does not provide clear user-facing disclosure or consent language about what data is collected, where it is sent, and how notifications may be forwarded. This creates privacy risk because users may not realize channel/user mappings and message contents are being transmitted to another application.

Ssd 3

Medium
Confidence
96% confidence
Finding
These instructions direct the agent to read platform channel/user identifiers from local configuration and transmit them to another application over an unauthenticated local HTTP interface. Even though the destination is localhost, this is still cross-component data exfiltration of identity metadata and could be abused by a malicious or compromised local service.

Ssd 3

Medium
Confidence
97% confidence
Finding
The notification forwarding flow retrieves message content from zworker and forwards it to a specified channel/user, with fallback delivery to a default or recent user when userid is empty. This can misroute sensitive content to unintended recipients, and the fallback behavior removes an important safety check on destination accuracy.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documented /control/runTask endpoint triggers state-changing behavior but the documentation does not warn users that invoking it will execute automation actions immediately and may have side effects beyond the local API call. In this skill context, an LLM or user could call it based on ambiguous input, causing unintended task execution on the local zworker instance.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The /control/setSchedule endpoint enables or disables schedules, which can alter ongoing automation behavior, but the documentation lacks a warning about operational impact. In an agent-integrated skill, this increases the risk of accidental service disruption, repeated job execution, or disabling important scheduled actions.

External Transmission

Medium
Category
Data Exfiltration
Content
## 使用示例

### cURL 示例

**获取任务列表**:
```bash
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
This is a code file, so SQP-2 applies to safety-critical operations. The call to disable the schedule changes system behavior and may be hard to notice or reverse, yet there is no confirmation prompt before execution and no inline comment/docstring specifically warning that it will disable a live schedule.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script retrieves notification content from a local automation service and prints the channel, optional user ID, message body, and the full raw payload to stdout. If this output is consumed by logs, other tools, or untrusted users, it can expose personal data and potentially sensitive notification contents without minimization or redaction; the inclusion of the entire raw result increases the chance of accidental over-disclosure.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This Python file contains user-facing natural-language text entirely in Chinese, including the module docstring, CLI description, and argument help strings. Under the policy, forcing a specific language without user opt-in or a documented region-specific justification is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This code's user-facing natural language is entirely in Chinese, including the module description, CLI help text, and status/error messages. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly documented and justified, which is not present here.

External Transmission

Medium
Category
Data Exfiltration
Content
response = requests.get(url, params=params, timeout=TIMEOUT)
            else:  # POST
                headers = {'Content-Type': 'application/json'}
                response = requests.post(url, params=params, json=data, 
                                        headers=headers, timeout=TIMEOUT)
            response.raise_for_status()
            result = response.json()
Confidence
81% confidence
Finding
This code performs external transmission of potentially sensitive control and user data to an HTTP service without any visible authentication or transport protection. In the context of an automation-control skill, that increases the risk of unauthorized task execution, schedule manipulation, or leakage of synced user information if the local service is exposed or another local process can interfere.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The run_task function triggers execution of a task via a POST request to /control/runTask, which is an action with potentially system-affecting side effects. Although the docstring describes the parameters, there is no confirmation prompt, user-facing log/print, or explicit warning in this file that invoking it will execute a task.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The set_schedule function changes scheduler state remotely by enabling or disabling a plan through /control/setSchedule. This can materially affect automated behavior, but the code provides no confirmation, user-facing notice, or explicit warning that calling the function changes active scheduling state.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The code sends user identifiers to a local service over plain HTTP with no authentication, integrity protection, or explicit minimization controls. Although localhost reduces exposure, local malware, malicious containers, browser-assisted localhost abuse, or a non-local binding on port 18803 could allow interception or unauthorized collection/modification of user data.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
The file presents all instructional content in Chinese and does not indicate that language selection is optional or that the documentation is intended for a specifically justified Chinese-language context. Per SQP-3, forcing a specific language without user opt-in can be a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
This code uses Chinese-only natural-language text in the module docstring, argument descriptions, and runtime messages, with no indication that users can opt into another language. The policy explicitly flags language or locale constraints when a skill forces a specific language without user choice.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The file's docstring, CLI description, help text, and runtime messages are written only in Chinese, which imposes a specific language/locale on users. There is no opt-in, language selection, or documentation indicating that this skill is intentionally limited to a Chinese-speaking context.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The script's description, argument help text, and runtime messages are all written in Chinese, which imposes a specific language on users without any opt-in or alternative locale support. The policy explicitly flags language or locale constraints when the skill does not offer a user choice or document a justified region-specific limitation.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
The docstring and all CLI-facing output are written in Chinese, which imposes a specific language on users. The file does not indicate that this skill is intended only for a Chinese-speaking or region-specific environment, nor does it provide any opt-in or alternative locale behavior.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
The module documentation and all user-facing descriptions in this file are written only in Chinese, which imposes a specific language choice without any opt-in or documented regional constraint. Under the stated policy, language constraints should be optional or explicitly justified.

Static analysis

No suspicious patterns detected.