Back to skill

Security audit

安卓手机自动化,类似豆包手机

Security checks for vulnerabilities and agentic risk

Overview

This phone-automation skill is useful but needs Review because it can install and update code, remember and reconnect to devices, expose model keys, and carry out phone actions with limited confirmation.

Install only if you are comfortable with a skill that can change local tooling, download and run upstream code, control a connected phone, remember device connection details, and perform the phone task you requested without a final confirmation. Use a dedicated test phone/account where possible, prefer HTTPS model endpoints, avoid shared machines, rotate any exposed model key, and clear ~/.openclaw/workspace/.device-memory/zhiyierxing-auto-phone.json if you do not want device reuse.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T03 · Remote Payload Retrieval and Execution

Warning
Location
scripts/deploy_open_autoglm.py:47
Finding
Automatic Retrieval and Execution of Unpinned Upstream Code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/clone_or_update_open_autoglm.py:7, 27-42`; `scripts/deploy_open_autoglm.py:47-50, 94-101` **Vulnerability Type**: Unpinned remote payload retrieval and execution **Risk Level**: Medium ### Vulnerable Code ```python # scripts/clone_or_update_open_autoglm.py REPO_URL = 'https://github.com/zai-org/Open-AutoGLM.git' if (target_dir / '.git').exists(): print(f'[info] repo already exists, updating: {target_dir}') pull = run([ 'git', '-C', str(target_dir), '-c', 'http.version=HTTP/1.1', 'pull', '--ff-only' ]) if pull.returncode == 0: return 0 print('[warn] git pull failed, trying git fetch --all --prune as fallback') fetch = run([ 'git', '-C', str(target_dir), '-c', 'http.version=HTTP/1.1', 'fetch', '--all', '--prune' ]) print(f'[info] cloning repo to: {target_dir}') clone = run([ 'git', '-c', 'http.version=HTTP/1.1', 'clone', REPO_URL, str(target_dir) ]) ``` ```python # scripts/deploy_open_autoglm.py clone_script = root_dir / 'scripts' / 'clone_or_update_open_autoglm.py' clone = run([sys.executable, str(clone_script), str(repo_dir)]) if clone.returncode != 0: return clone.returncode upgrade_pip = run([ str(py), '-m', 'pip', 'install', '--upgrade', 'pip' ], cwd=str(repo_dir)) if upgrade_pip.returncode != 0: return upgrade_pip.returncode install_req = run([ str(py), '-m', 'pip', 'install', '-r', 'requirements.txt' ], cwd=str(repo_dir)) if install_req.returncode != 0: return install_req.returncode install_editable = run([ str(py), '-m', 'pip', 'install', '-e', '.' ], cwd=str(repo_dir)) if install_editable.returncode != 0: return install_editable.returncode ``` ### Technical Analysis The deployment flow clones or updates the current branch of an external GitHub repository without pinning it to a reviewed commit hash or verifying a signed release. It then immediately trusts the retri ...[truncated 1942 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the upstream repository to a reviewed commit hash or immutable signed release tag. 2. After fetching, verify that `HEAD` matches the expected commit before installing or executing anything. 3. Prefer signed releases and validate Git signatures against an allowlisted maintainer key. 4. Replace unconstrained requirements with a lock file containing exact versions and cryptographic hashes. 5. Use `pip install --require-hashes` where supported. 6. Do not automatically update an existing deployment immediately before execution. Present the proposed revision and require explicit approval for revision changes. 7. Run build and installation operations in an isolated environment without model credentials or unnecessary device access. 8. Review packaging metadata and dependency changes before allowing a newly retrieved revision to execute. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run_phone_task.py:34
Finding
Model API Key Exposed in Child-Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run_phone_task.py:34-36, 58-62`; `scripts/ensure_and_run_task.py:128-134`; `scripts/run_phone_task.sh:38` **Vulnerability Type**: Sensitive information exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```python # scripts/run_phone_task.py base_url = os.environ.get('MODEL_BASE_URL', '') model_name = os.environ.get('MODEL_NAME', '') api_key = os.environ.get('MODEL_API_KEY', '') cmd = [ str(py), str(main_py), '--base-url', base_url, '--model', model_name, '--apikey', api_key ] if preferred_device: cmd.extend(['--device-id', preferred_device]) cmd.append(task) return subprocess.call( cmd, cwd=str(repo_dir), env=os.environ.copy() ) ``` ```python # scripts/ensure_and_run_task.py verify = subprocess.run([ str(py), str(root_dir / 'scripts' / 'verify_open_autoglm.py'), '--base-url', os.environ.get('MODEL_BASE_URL', ''), '--model', os.environ.get('MODEL_NAME', ''), '--apikey', os.environ.get('MODEL_API_KEY', ''), '--task', '请输出一个最简单的 do(action="Wait", duration="1 seconds") 来验证动作格式' ], cwd=str(repo_dir), env=os.environ.copy()) ``` ```bash # scripts/run_phone_task.sh python main.py \ --base-url "$BASE_URL" \ --model "$MODEL_NAME_VALUE" \ --apikey "$API_KEY" \ "$TASK" ``` ### Technical Analysis The API key is initially obtained from `MODEL_API_KEY`, but the workflow copies it into the argument vector of child processes through the `--apikey` option. Command-line arguments can be exposed through operating-system process inspection, endpoint monitoring tools, crash diagnostics, CI telemetry, audit logs, shell tracing, and process-creation event collection. On systems where process arguments are visible to other local users or monitoring services, the key may be captured while the verification or task process is running. Sending the key to the configured model provider is required for authenticated operatio ...[truncated 997 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Modify `verify_open_autoglm.py` and the upstream runner to read the API key directly from `MODEL_API_KEY` rather than accepting it through `--apikey`. 2. Remove the key from all subprocess argument arrays and shell command lines. 3. If environment-based transfer is unavailable, pass the secret through a protected standard-input channel or an operating-system credential store. 4. Ensure application logs, exception messages, and diagnostic output redact authorization values. 5. Avoid enabling shell tracing around commands that consume secrets. 6. Rotate any API key that may already have appeared in process telemetry or logs. 7. Limit the API key's permissions, quota, and lifetime at the provider. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/verify_open_autoglm.py:7
Finding
Bearer Credential Can Be Transmitted over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `scripts/verify_open_autoglm.py:7-10, 20-29` **Vulnerability Type**: Plaintext transmission of sensitive credentials **Risk Level**: Medium ### Vulnerable Code ```python def post_json(url, payload, headers): req = urllib.request.Request( url, data=json.dumps(payload).encode('utf-8'), headers=headers, method='POST' ) with urllib.request.urlopen(req, timeout=30) as resp: body = resp.read().decode('utf-8', errors='replace') return resp.status, body p.add_argument('--base-url', required=True) p.add_argument('--model', required=True) p.add_argument('--apikey', default='') p.add_argument('--task', default='打开美团搜索附近的火锅店') args = p.parse_args() base = args.base_url.rstrip('/') url = base + '/chat/completions' headers = {'Content-Type': 'application/json'} if args.apikey: headers['Authorization'] = f'Bearer {args.apikey}' payload = { 'model': args.model, 'messages': [ {'role': 'user', 'content': args.task} ], 'temperature': 0.1, 'max_tokens': 1024 } ``` ### Technical Analysis The verifier accepts an arbitrary base URL and sends an authorization bearer token and task content to the resulting `/chat/completions` endpoint. It does not validate the URL scheme or restrict plaintext HTTP to loopback destinations. Using HTTP for a local self-hosted endpoint can be reasonable when traffic remains entirely on the loopback interface. For a remote or LAN endpoint, however, plaintext HTTP provides no transport confidentiality or server authentication. A network intermediary may observe or modify the bearer credential, model name, task prompt, and response. The network request itself is necessary for the declared model-verification functionality, and no hard-coded exfiltration destination was identified. The security issue is the lack of transport-policy enforcement when sensitive authorization data is present. ### Attack Path 1 ...[truncated 938 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse `base-url` with a standard URL parser before constructing the request. 2. Require `https://` for every non-loopback destination. 3. Permit `http://` only when the normalized host is explicitly `localhost`, `127.0.0.1`, or `::1`. 4. Reject missing schemes, unsupported schemes, embedded credentials, and malformed hostnames. 5. Preserve normal TLS certificate and hostname verification; do not add insecure certificate-bypass options. 6. Display the normalized destination host before sending credentials when a custom provider is configured. 7. Consider maintaining an allowlist of approved production model-provider domains. 8. Rotate credentials if they have previously been sent to a remote plaintext endpoint. ]]>
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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (52)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
Unlike the other mismatch findings, this one notes persistent local device-memory behavior that is not clearly surfaced in the declaration. Persisting device identifiers and Wi‑Fi targets can create privacy and targeting risks, especially on shared hosts, because future runs may silently reconnect to or act on a remembered phone.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Unlike the other mismatch findings, this one notes persistent local device-memory behavior that is not clearly surfaced in the declaration. Persisting device identifiers and Wi‑Fi targets can create privacy and targeting risks, especially on shared hosts, because future runs may silently reconnect to or act on a remembered phone.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Unlike the other mismatch findings, this one notes persistent local device-memory behavior that is not clearly surfaced in the declaration. Persisting device identifiers and Wi‑Fi targets can create privacy and targeting risks, especially on shared hosts, because future runs may silently reconnect to or act on a remembered phone.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
Unlike the other mismatch findings, this one notes persistent local device-memory behavior that is not clearly surfaced in the declaration. Persisting device identifiers and Wi‑Fi targets can create privacy and targeting risks, especially on shared hosts, because future runs may silently reconnect to or act on a remembered phone.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Unlike the other mismatch findings, this one notes persistent local device-memory behavior that is not clearly surfaced in the declaration. Persisting device identifiers and Wi‑Fi targets can create privacy and targeting risks, especially on shared hosts, because future runs may silently reconnect to or act on a remembered phone.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Unlike the other mismatch findings, this one notes persistent local device-memory behavior that is not clearly surfaced in the declaration. Persisting device identifiers and Wi‑Fi targets can create privacy and targeting risks, especially on shared hosts, because future runs may silently reconnect to or act on a remembered phone.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Unlike the other mismatch findings, this one notes persistent local device-memory behavior that is not clearly surfaced in the declaration. Persisting device identifiers and Wi‑Fi targets can create privacy and targeting risks, especially on shared hosts, because future runs may silently reconnect to or act on a remembered phone.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
Unlike the other mismatch findings, this one notes persistent local device-memory behavior that is not clearly surfaced in the declaration. Persisting device identifiers and Wi‑Fi targets can create privacy and targeting risks, especially on shared hosts, because future runs may silently reconnect to or act on a remembered phone.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Unlike the other mismatch findings, this one notes persistent local device-memory behavior that is not clearly surfaced in the declaration. Persisting device identifiers and Wi‑Fi targets can create privacy and targeting risks, especially on shared hosts, because future runs may silently reconnect to or act on a remembered phone.

Missing User Warnings

High
Confidence
96% confidence
Finding
The skill instructs automatic cloning, installation, environment repair, device connection changes, and task execution on a connected phone, yet it lacks a clear user-facing warning that these actions will modify the host and device. That is dangerous because users may believe they are only asking a question while the skill is authorized to make persistent system changes and perform external actions in apps.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
def run(cmd, cwd=None):
    return subprocess.run(cmd, cwd=cwd, env=os.environ.copy())


def venv_matches_selected(repo_dir: Path, selected_path: str) -> bool:
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
def run(cmd, cwd=None):
    return subprocess.run(cmd, cwd=cwd, env=os.environ.copy())


def venv_matches_selected(repo_dir: Path, selected_path: str) -> bool:
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
def run(cmd, cwd=None, check=False, capture=False):
    if capture:
        return subprocess.run(cmd, cwd=cwd, env=os.environ.copy(), check=check, capture_output=True, text=True)
    return subprocess.run(cmd, cwd=cwd, env=os.environ.copy(), check=check)
Confidence
93% confidence
Finding
This helper forwards the entire environment to every captured subprocess execution. That pattern can unnecessarily expose secrets to downstream scripts and tools that have no need for them, increasing accidental disclosure risk.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
def run(cmd, cwd=None, check=False, capture=False):
    if capture:
        return subprocess.run(cmd, cwd=cwd, env=os.environ.copy(), check=check, capture_output=True, text=True)
    return subprocess.run(cmd, cwd=cwd, env=os.environ.copy(), check=check)


def classify_recheck(repo_dir: Path, device_type: str) -> str:
Confidence
93% confidence
Finding
Passing os.environ.copy() to child processes indiscriminately forwards all parent environment variables, which may include API keys, tokens, proxy credentials, CI secrets, or other sensitive values unrelated to the task. In a deployment/orchestration skill that launches multiple helper scripts, this broad propagation expands the blast radius if any child process logs, leaks, or misuses inherited secrets.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
return 'config'

    if device_type == 'android':
        adb = subprocess.run(['adb', 'devices'], capture_output=True, text=True, env=os.environ.copy())
        lines = [line.strip() for line in adb.stdout.splitlines()[1:] if line.strip()]
        authorized = [line.split()[0] for line in lines if len(line.split()) >= 2 and line.split()[1] == 'device']
        if not authorized:
Confidence
88% confidence
Finding
The 'adb devices' call does not need access to model credentials or most ambient environment variables, yet it inherits them all. While the command itself is harmless, broad secret propagation to unnecessary child processes is still a real exposure and poor secret-handling practice.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
print('[phase] install host tools if needed')
        install_script = root_dir / 'scripts' / 'install_host_tools.py'
        if install_script.exists():
            install = subprocess.run([sys.executable, str(install_script), device_type], env=os.environ.copy())
            if install.returncode == 0:
                print('[auto-fixed] host tools step completed without fatal errors')
            else:
Confidence
90% confidence
Finding
The host-tools installer is given the full parent environment even though most secrets are unrelated to package installation. This creates unnecessary exposure to helper tools and installers, which may generate logs or invoke further subprocesses.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
print('[phase] deployment / repair')
        deploy_script = root_dir / 'scripts' / 'deploy_open_autoglm.py'
        deploy = subprocess.run([sys.executable, str(deploy_script), device_type, model_mode, str(repo_dir)], env=os.environ.copy())
        if deploy.returncode != 0:
            print('[runtime-failed] deployment / repair exited with a non-zero code')
            return deploy.returncode
Confidence
91% confidence
Finding
The deployment script inherits the full environment, which likely includes model credentials and other secrets. Because deployment/repair scripts are often verbose and complex, the chance of accidental logging or downstream propagation is elevated in this skill context.

Direct flow: os.environ.get (credential/environment) → subprocess.run (code execution)

High
Category
Data Flow
Content
print('[phase] model verification')
    py = venv_python(repo_dir)
    verify = subprocess.run([
        str(py), str(root_dir / 'scripts' / 'verify_open_autoglm.py'),
        '--base-url', os.environ.get('MODEL_BASE_URL', ''),
        '--model', os.environ.get('MODEL_NAME', ''),
Confidence
97% confidence
Finding
The code takes credential-bearing environment values and feeds them directly into a subprocess invocation, including exposing the API key as a command-line flag. In a product-grade deployment skill that automates local setup and execution, this is more dangerous because it normalizes handling secrets in ways that can leak them through process listings, crash reports, telemetry, or debug output.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
'--model', os.environ.get('MODEL_NAME', ''),
        '--apikey', os.environ.get('MODEL_API_KEY', ''),
        '--task', '请输出一个最简单的 do(action="Wait", duration="1 seconds") 来验证动作格式'
    ], cwd=str(repo_dir), env=os.environ.copy())
    if verify.returncode != 0:
        print('[runtime-failed] model verification failed')
        print('[safe-to-retry] verify model endpoint settings or service health, then rerun the workflow')
Confidence
98% confidence
Finding
This call both forwards the full environment and passes an API key explicitly on the command line, creating two avenues for secret exposure. In local automation contexts, child processes and support tooling may emit diagnostics or be inspectable by other local users, making credential leakage realistically exploitable.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill declares broad operational behavior that implies shell, network, environment, and filesystem access, but it does not declare an explicit tool/permission scope. That makes the execution boundary unclear to users and reviewers, increasing the chance of over-privileged execution and unsafe side effects such as cloning repos, modifying local environments, and interacting with connected phones without a narrowly constrained allowlist.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- automatically reuse any existing repo, `.venv`, installed dependencies, device connection, and model env vars
- only ask the user to do something after a real runtime blocker is observed
- do not front-load setup instructions "just in case"
- do not ask the user to install ADB Keyboard, enable debugging, or configure env vars unless the workflow actually proves that those are the blockers

## Environment variables
This skill expects the following variables when applicable:
Confidence
92% confidence
Finding
The skill repeatedly instructs the agent not to ask the user before proceeding and to push setup and execution forward automatically until blocked. In the context of shell, network, filesystem, environment-variable use, and phone control, that autonomy can lead to unapproved installs, repo modifications, endpoint usage, and actions on the user's mobile apps before meaningful informed consent is obtained.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The activation guidance is intentionally broad enough to trigger on ordinary 'use my phone to do X' requests, which can cause the skill to initiate repo changes, device interactions, and external actions without a clear boundary or explicit opt-in. In a skill that can automate actions on real mobile apps and connected devices, ambiguous invocation materially increases the risk of unintended or unsafe execution.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- existing model environment variables
- remembered Android device identity and remembered ADB Wi‑Fi target

Do not ask the user to reinstall or reconfigure something that may already be present.

For Android:
- if a previously authorized USB device is connected, try enabling TCP/IP and connecting over Wi‑Fi automatically
Confidence
93% confidence
Finding
This section expands autonomous behavior to include automatic reuse of remembered device identity and ADB Wi‑Fi targets, plus automatic enabling of TCP/IP connectivity for previously authorized devices. In practice, that can silently reconnect to and operate the wrong phone, broaden device exposure over the network, and reduce user awareness of which device is being controlled.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill instructs users to enable Developer Options, USB debugging, security-related debugging settings, and alternate device-connection mechanisms, but it does not warn about the increased attack surface or advise disabling them after setup. These settings can allow unauthorized device control, data access, or broader local compromise if the connected computer, cable path, or network environment is untrusted. In this deployment-focused skill, the risk is contextually relevant because the instructions are likely to be followed verbatim by non-expert users.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
return 1

    print('[step] checking adb devices')
    subprocess.run(['adb', 'devices'])
    devices = run(['adb', 'devices'])
    lines = [line.strip() for line in devices.stdout.splitlines()[1:] if line.strip()]
    authorized = [line.split()[0] for line in lines if len(line.split()) >= 2 and line.split()[1] == 'device']
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.