Back to skill

Security audit

iClick Automation

Security checks for vulnerabilities and agentic risk

Overview

This skill matches its iOS automation purpose, but it exposes broad device-control and deletion authority through an under-scoped generic backend dispatcher.

Install only if you trust the local iClick service and intend to let agents control connected iOS devices. Before use, restrict who can invoke the skill, require explicit confirmation for screenshot capture and media deletion/clearing, and prefer an allowlist of approved backend methods instead of the generic dispatcher.

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

Error
Location
server.js:10
Finding
Unrestricted Backend RPC Method Dispatch## Vulnerability Details **File Location**: `server.js:10-31` **Vulnerability Type**: Unrestricted invocation of undocumented or privileged backend methods **Risk Level**: High ```js const _method = process.argv[2] const _paramsRaw = process.argv[3] if (!_method) { handleError(new Error('请传入方法名,例如: node server.js getDevices')) } if (!/^[a-zA-Z0-9_]+$/.test(_method)) { handleError(new Error('方法名只能包含字母、数字、下划线')) } try { await iclick.connect() const _params = _paramsRaw ? JSON.parse(_paramsRaw) : {} let _result = null try { const _cmd = require(path.join(__dirname, 'command', _method + '.js')) _result = await _cmd.run(_params) } catch (_error) { _result = await iclick.invoke(_method, _params) } ``` ### Technical Analysis The dispatcher verifies only that the supplied method consists of letters, numbers, and underscores. This prevents direct path traversal through the method name, but it does not restrict the operation to an approved set of documented commands. If loading or executing a local command handler throws any exception, the broad `catch` forwards the same attacker-controlled method and parameters directly to `iclick.invoke()`. Consequently, any method recognized by the underlying `iclick-auto` backend can potentially be invoked, including undocumented, future, administrative, or destructive methods that were not reviewed as part of the Skill interface. The exception handling also conflates two distinct conditions: 1. The requested local command module does not exist. 2. A legitimate local command module exists but fails during loading or execution. In the second case, the code can unexpectedly retry the operation through the generic backend interface. This may bypass validation or safety logic implemented by the local handler and could produce an unintended alternative operation. ### Attack Path 1. An attacker, untrusted c ...[truncated 1390 chars]
Remediation
## Remediation Suggestions 1. Define an explicit allowlist of supported method names and reject every method not present in that list. 2. Map method names to handlers directly rather than forwarding arbitrary strings to the backend. 3. If generic backend invocation is required, maintain a separate allowlist for approved backend methods. 4. Fall back to generic invocation only when module resolution specifically indicates that the requested command module is absent. 5. Propagate errors thrown while loading dependencies or executing an existing handler; do not reinterpret them as a missing command. 6. Add schema validation for parameters accepted by every operation. 7. Require explicit authorization or user confirmation for destructive actions such as deleting media, clearing files, terminating applications, or controlling input. 8. Add tests confirming that undocumented method names are rejected and that handler failures never trigger generic backend invocation.

T09 · Insecure Skill Coding Practices

Warning
Location
command/getScreenShot.js:10
Finding
Unsafe Temporary Storage of Sensitive Screenshots## Vulnerability Details **File Location**: `command/getScreenShot.js:10-14` **Vulnerability Type**: Weak temporary-file generation, insufficient access control, and missing cleanup **Risk Level**: Medium ```js const _data = await invoke('getScreenShot', _params) const _file = path.join(os.tmpdir(), `${Math.random().toString(36).substring(2, 15)}.jpg`) await fs.writeFile(_file, _data) return { status: true, message: `已保存`, file: _file } ``` ### Technical Analysis Device screenshots are sensitive data and are written directly into the operating system's shared temporary directory. The filename is generated with `Math.random()`, which is not a cryptographically secure random-number generator and should not be used to protect sensitive temporary resources. The file is created using `fs.writeFile()` without explicit restrictive permissions or exclusive-creation semantics. Its resulting permissions depend on the process umask and platform defaults. The implementation also does not create a private per-process directory and does not enforce deletion after the screenshot is consumed. Although `SKILL.md` instructs the agent to delete a copied screenshot after sending it, documentation is not an enforceable lifecycle control. The original temporary file can remain on disk if execution fails, the agent omits cleanup, or the process terminates unexpectedly. ### Attack Path 1. A user or agent requests a screenshot from a connected device. 2. The backend returns the screenshot bytes. 3. The Skill generates a non-cryptographic filename in the shared temporary directory. 4. The screenshot is written with permissions determined by the environment rather than explicit least-privilege settings. 5. The command returns the path but establishes no guaranteed cleanup mechanism. 6. Another local process or user may locate or access the retained file where system permissions permit, or the sensitive image may remain recoverable after th ...[truncated 610 chars]
Remediation
## Remediation Suggestions 1. Create a private temporary directory with `fs.mkdtemp()` and set directory permissions to `0o700`. 2. Generate filenames with `crypto.randomBytes()` or use a secure temporary-file library. 3. Create screenshot files with mode `0o600` and an exclusive-creation flag such as `wx` to prevent overwriting an existing path. 4. Validate that the generated path remains inside the private temporary directory. 5. Delete the screenshot in a `finally` block immediately after its intended consumer finishes. 6. Where immediate cleanup is not possible, implement a short expiration period and a reliable cleanup process covering normal completion, errors, and process termination. 7. Prefer returning screenshot data through a controlled in-memory channel when a persistent filesystem path is unnecessary. 8. Document the sensitivity of screenshot data and avoid logging the image contents or retaining paths longer than required.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (10)

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The skill description is presented entirely in Chinese and the examples expose a fixed Chinese device locale (`zh-Hans-CN`) without any indication that users may choose another language or that the skill is intentionally restricted to a Chinese-speaking context. Under the policy, forcing a specific language or locale without opt-in is a natural-language policy concern.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The screenshot workflow instructs the agent to capture a device screenshot, copy it into the workspace, send it onward, and then delete it, but it does not clearly warn that screenshots may contain sensitive personal or corporate information. Because this skill is designed for remote control of iOS devices, screenshot extraction materially increases privacy and data exposure risk.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill documents destructive media operations such as deleting specific media files and clearing the entire media directory, but it does not require explicit confirmation or warn about irreversible data loss. In an automation context, an agent could execute these commands at scale on connected devices, making accidental or unauthorized deletion materially harmful.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This code captures screenshot data from a device and writes it to a local file in the system temporary directory without any notice, consent check, retention control, or access restriction visible in this function. Screenshots can contain highly sensitive information such as credentials, messages, or personal data, so silently persisting them increases privacy and data-exposure risk, especially on shared systems or when temp directories are monitored or backed up.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The device listing example exposes fields such as IP address, device name, model, language, and other metadata without a clear disclosure warning. While this is normal for device management tooling, these identifiers can still reveal network topology or user/device identity and should be treated as sensitive operational data.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"license": "ISC",
  "description": "iClick OpenClaw Skill",
  "dependencies": {
    "iclick-auto": "^1.0.5",
    "ws": "^8.19.0"
  }
}
Confidence
95% confidence
Finding
The dependency iclick-auto is specified with a caret range (^1.0.5), which allows newer minor and patch releases to be installed without explicit review. This weakens supply-chain integrity and can introduce unexpected vulnerable or malicious code into a skill that performs device automation and monitoring, increasing sensitivity of any dependency compromise.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"description": "iClick OpenClaw Skill",
  "dependencies": {
    "iclick-auto": "^1.0.5",
    "ws": "^8.19.0"
  }
}
Confidence
98% confidence
Finding
The ws package is also specified with a caret range (^8.19.0), so different installations may resolve to different releases over time. Because ws is a network-facing WebSocket library and this skill appears to support device monitoring/RPA features, an unsafe or newly introduced package version could expose remote attack surface or instability.

Unverifiable Dependency: ws has 7 known advisory(ies) (CVE-2016-10518 (Remote Memory Disclosure in ws); CVE-2024-37890 (ws affected by a DoS when handling a request with many HTTP headers); CVE-2026-45736 (ws: Uninitialized memory disclosure) +4 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding
The manifest includes ws without an exact pinned version, while the package has multiple known advisories across versions. Since the resolved installed version is not verifiable from this manifest alone, there is a credible risk that deployments could consume an affected release, which is more concerning here because WebSocket handling is likely exposed to external input.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The user-facing error messages are hard-coded in Chinese, and the file does not provide any opt-in or alternative locale handling. This can violate a language/locale policy when users are not explicitly given a choice of language.

Natural-Language Policy Violations

Low
Confidence
96% confidence
Finding
The thrown error string is written only in Chinese: 'iclick 未连接,请先调用 connect()'. For a general-purpose utility file, this imposes a specific language on users without any visible locale selection or opt-in, which matches the language-policy concern for natural-language content.

Static analysis

Detected: suspicious.install_untrusted_source

Install source points to URL shortener or raw IP.

Warn
Code
suspicious.install_untrusted_source
Location
node_modules/.pnpm/yargs-parser@22.0.0/node_modules/yargs-parser/package.json:24