Back to skill

Security audit

MoreLogin

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its MoreLogin management purpose, but it needs review because sensitive profile, proxy, and ADB data can be sent or printed more broadly than the localhost-only documentation implies.

Review before installing. Use it only with a running local MoreLogin desktop app, do not set MORELOGIN_LOCAL_API_URL to a remote host, avoid putting tokens or profile/IP mappings in shared files, and assume command output may contain sensitive proxy or ADB data until the tool adds redaction. Upgrade the Playwright/Puppeteer dependency chain before using browser tooling in sensitive environments.

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

T09 · Insecure Skill Coding Practices

Error
Location
bin/common.js:3
Finding
Configurable API Base URL Breaks the Declared Localhost Trust Boundary<![CDATA[ ## Vulnerability Details **File Location**: `bin/common.js:3-4, 57-105` **Vulnerability Type**: Arbitrary cleartext API destination and sensitive request disclosure **Risk Level**: High ### Vulnerable Code ```javascript const DEFAULT_BASE_URL = process.env.MORELOGIN_LOCAL_API_URL || 'http://127.0.0.1:40000'; const DEFAULT_TIMEOUT_MS = Number.parseInt(process.env.MORELOGIN_LOCAL_API_TIMEOUT_MS || '10000', 10); function requestApi(endpoint, { method = 'POST', body, baseUrl = DEFAULT_BASE_URL, timeoutMs = DEFAULT_TIMEOUT_MS } = {}) { return new Promise((resolve, reject) => { const url = new URL(endpoint, baseUrl); const payload = body === undefined ? undefined : JSON.stringify(body); const options = { hostname: url.hostname, port: url.port || 80, path: `${url.pathname}${url.search}`, method, headers: { 'Content-Type': 'application/json', }, timeout: timeoutMs, }; if (payload) { options.headers['Content-Length'] = Buffer.byteLength(payload); } const req = http.request(options, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { let parsed; try { parsed = JSON.parse(data); } catch (error) { parsed = { raw: data }; } resolve({ statusCode: res.statusCode, ok: res.statusCode >= 200 && res.statusCode < 300, body: parsed, }); }); }); req.on('timeout', () => { req.destroy(); reject(new Error(`Request timeout after ${timeoutMs}ms`)); }); req.on('error', reject); if (payload) { req.write(payload); } req.end(); }); } ``` ### Technical Analysis The Skill declares that it communicates only with the MoreLogin Local API at `http://127.0.0.1:40000`. However, `MORELOGIN_LOCAL_API_URL` can replace that destination with an arbitrary hostname, and `request ...[truncated 1918 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce a strict loopback destination policy before issuing a request: ```javascript function validateLocalApiUrl(baseUrl) { const url = new URL(baseUrl); const allowedHosts = new Set(['127.0.0.1', 'localhost', '::1']); if (url.protocol !== 'http:' || !allowedHosts.has(url.hostname)) { throw new Error('MoreLogin Local API URL must use a loopback address'); } return url; } ``` 2. Remove `MORELOGIN_LOCAL_API_URL` entirely if endpoint customization is not required by the declared functionality. 3. If customization is retained, require explicit user confirmation before accepting any non-default port. 4. Reject credentials embedded in a URL and reject redirects to non-loopback destinations. 5. Use a dedicated local socket or authenticated local transport if supported by MoreLogin. 6. Add tests confirming that public IP addresses, wildcard addresses, encoded loopback bypasses, and remote DNS names are rejected. 7. Document the exact supported environment variable; current documentation also refers to the inconsistent name `MORELOGIN_API_URL`. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
bin/cloudphone-commands.js:112
Finding
Cloud-Phone ADB Credentials Are Printed to Standard Output Without Redaction<![CDATA[ ## Vulnerability Details **File Location**: `bin/cloudphone-commands.js:112-133` **Vulnerability Type**: Plaintext disclosure of sensitive API response fields **Risk Level**: Medium ### Vulnerable Code ```javascript case 'info': { const body = payload || { id: options.id }; requirePlainObject(body, 'info payload'); body.id = requireNonEmptyString(body.id, 'id'); const data = await callApi('/api/cloudphone/info', { body }); printObject(data); return; } case 'adb-info': { const cloudphoneId = payload?.id || options.id; requireNonEmptyString(cloudphoneId, 'id'); const phone = await findCloudPhoneById(cloudphoneId); const info = await getCloudPhoneInfoById(cloudphoneId); printObject({ id: String(phone.id), osVersion: info?.device?.osVersion || phone.osVersion || '', supportAdb: phone.supportAdb, enableAdb: phone.enableAdb, adbInfo: phone.adbInfo || null, }); return; } ``` The bundled API schema confirms that `adbInfo` can contain a password: ```yaml AdbInfo: properties: adbIp: type: string description: adb ip adbPassword: type: string description: adb connection password adbPort: type: integer description: adb port ``` ### Technical Analysis Both `cloudphone info` and `cloudphone adb-info` serialize API responses directly to stdout. The `adb-info` command explicitly includes the entire `phone.adbInfo` object. According to `local-api.yaml`, that object can contain `adbPassword`. Standard output is commonly captured by Agent transcripts, CI systems, terminal recorders, job logs, and monitoring platforms. Consequently, a credential intended only for an ADB connection can be copied into systems with broader access and longer retention. This contradicts the security instruction in `SKILL.md` that ADB keys and other sensitive data must not be exposed in logs. ### Attack Path 1. A cloud phone has ADB enabled and the MoreLogin API returns an `adbInfo` object c ...[truncated 1126 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Recursively redact sensitive response keys before serialization: ```javascript const SENSITIVE_KEYS = /^(password|adbPassword|token|secret|apiKey|privateKey)$/i; function redactSensitive(value) { if (Array.isArray(value)) { return value.map(redactSensitive); } if (value && typeof value === 'object') { return Object.fromEntries( Object.entries(value).map(([key, item]) => [ key, SENSITIVE_KEYS.test(key) ? '[REDACTED]' : redactSensitive(item), ]) ); } return value; } ``` 2. Make redaction the default behavior of `printObject()` so new commands cannot accidentally bypass it. 3. For `adb-info`, construct a minimal response containing only the device ID, ADB status, host, and port. Omit `adbPassword`. 4. If credential display is operationally necessary, require an explicit flag such as `--show-secrets`, display a warning, and avoid use in Agent or CI contexts. 5. Add automated tests with nested `adbPassword` fields to ensure they never appear in default output. 6. Review existing logs and Agent transcripts for prior credential exposure and rotate affected ADB credentials where possible. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
bin/morelogin.js:335
Finding
Proxy API Responses May Expose Authentication Passwords in Logs<![CDATA[ ## Vulnerability Details **File Location**: `bin/morelogin.js:335-363` **Vulnerability Type**: Plaintext disclosure of proxy credentials **Risk Level**: Medium ### Vulnerable Code ```javascript case 'list': { const body = payload ? validatePagePayload(payload) : parsePageOptions(options); const data = await callApi('/api/proxyInfo/page', { body }); printObject(data); return; } case 'add': { if (!payload) fail('proxy add: use --payload to pass full parameters'); validateProxyAddPayload(payload); const data = await callApi('/api/proxyInfo/add', { body: payload }); printObject(data); return; } case 'update': { if (!payload) fail('proxy update: use --payload to pass full parameters'); validateProxyUpdatePayload(payload); const data = await callApi('/api/proxyInfo/update', { body: payload }); printObject(data); return; } ``` The bundled API schema identifies password-bearing proxy fields: ```yaml password: type: string description: Password for proxy authentication ``` ### Technical Analysis Proxy list, add, and update responses are passed directly to `printObject()` without field filtering. The API contract includes proxy authentication passwords, so any endpoint that returns the complete proxy object can disclose those passwords through stdout. Although whether a particular MoreLogin API version returns the password depends on server behavior, the client makes no attempt to enforce the Skill's stated rule that proxy passwords must not be exposed in logs. Secure client behavior must not depend solely on the server omitting sensitive response properties. ### Attack Path 1. A MoreLogin account contains a proxy configuration with authentication credentials. 2. The API returns a proxy object that includes the `password` field after a list, add, or update request. 3. A user or Agent invokes an affected command, such as: ```bash node bin/morelogin.js proxy list ``` 4. The response is serialized unchange ...[truncated 732 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Apply centralized recursive redaction to all API responses before printing. 2. At minimum, redact keys matching `password`, `username`, `token`, `secret`, `authorization`, `apiKey`, `privateKey`, and `adbPassword`. 3. Use endpoint-specific output models for proxy commands rather than printing arbitrary server objects. 4. For proxy-list output, display only non-secret metadata such as proxy ID, name, protocol, host, port, status, and region. 5. Never print a returned proxy password after add or update operations; report only the operation result and proxy ID. 6. Add tests using nested proxy objects containing passwords to verify that plaintext values cannot reach stdout. 7. Rotate any credentials that may already have been captured in Agent transcripts or shared logs. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (66)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Using the skill to browse external sites like Google for BTC lookups and save screenshots is unrelated to MoreLogin profile or cloud-phone management. That kind of undeclared external interaction broadens both privacy risk and attack surface, because it enables arbitrary network activity under a misleadingly narrow description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Using the skill to browse external sites like Google for BTC lookups and save screenshots is unrelated to MoreLogin profile or cloud-phone management. That kind of undeclared external interaction broadens both privacy risk and attack surface, because it enables arbitrary network activity under a misleadingly narrow description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
Using the skill to browse external sites like Google for BTC lookups and save screenshots is unrelated to MoreLogin profile or cloud-phone management. That kind of undeclared external interaction broadens both privacy risk and attack surface, because it enables arbitrary network activity under a misleadingly narrow description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Using the skill to browse external sites like Google for BTC lookups and save screenshots is unrelated to MoreLogin profile or cloud-phone management. That kind of undeclared external interaction broadens both privacy risk and attack surface, because it enables arbitrary network activity under a misleadingly narrow description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Using the skill to browse external sites like Google for BTC lookups and save screenshots is unrelated to MoreLogin profile or cloud-phone management. That kind of undeclared external interaction broadens both privacy risk and attack surface, because it enables arbitrary network activity under a misleadingly narrow description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Using the skill to browse external sites like Google for BTC lookups and save screenshots is unrelated to MoreLogin profile or cloud-phone management. That kind of undeclared external interaction broadens both privacy risk and attack surface, because it enables arbitrary network activity under a misleadingly narrow description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Using the skill to browse external sites like Google for BTC lookups and save screenshots is unrelated to MoreLogin profile or cloud-phone management. That kind of undeclared external interaction broadens both privacy risk and attack surface, because it enables arbitrary network activity under a misleadingly narrow description.

Ae1

High
Category
analysis-evasion
Content
Entry equivalence note: `openclaw morelogin ...` and `node bin/morelogin.js ...` are fully equivalent (same arguments, same behavior, same exit code). Use eithe
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Entry equivalence note: `openclaw morelogin ...` and `node bin/morelogin.js ...` are fully equivalent (same arguments, same behavior, same exit code). Use eithe
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Intent-Code Divergence

High
Confidence
97% confidence
Finding
Lines L268-L289 assert that `cloudphone exec` is removed and that local ADB/SSH connection methods are removed, presenting a reduced capability set. However, L463-L517 and surrounding sections later document top-level `connect`, `run`, `config`, and `setup` commands plus CDP automation workflows as if they are current commands of this skill, which directly conflicts with the earlier statement that the document reflects the current implementation and available behavior.

Instruction Override

High
Category
Prompt Injection
Content
1. **View document**: `cat README.md`
2. **Run test**: `node bin/morelogin.js browser list --page 1 --page-size 1`
3. **Check configuration**: `node bin/morelogin.js config`
4. **View log**: Enable DEBUG mode
5. **Contact Support**: Morelogin Official Support or OpenClaw Community

---
Confidence
70% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The example connects to a browser via CDP, visits an arbitrary URL from environment input, extracts page data, and writes the results to a local file. That behavior is outside the stated MoreLogin-management purpose and expands the skill into generic scraping/automation, which increases the chance of policy evasion, misuse, or unintended data collection under the cover of an administrative skill.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The API exposes `/api/cloudphone/exeCommand`, which allows arbitrary shell command execution on a cloud phone. That capability goes beyond ordinary profile-management operations and can be used to install payloads, change device state, exfiltrate data, or automate abusive activity at scale. In the context of an agent skill, exposing raw command execution materially increases the risk of prompt-driven misuse or unintended destructive actions.

Known Vulnerable Dependency: basic-ftp==5.2.0 — 4 advisory(ies): GHSA-6v7q-wjvx-w8wg (basic-ftp: Incomplete CRLF Injection Protection Allows Arbitrary FTP Command Exe); CVE-2026-39983 (basic-ftp has FTP Command Injection via CRLF); CVE-2026-41324 (basic-ftp vulnerable to denial of service via unbounded memory consumption in Cl) +1 more

High
Category
Supply Chain
Confidence
92% confidence
Finding
basic-ftp 5.2.0 is a real supply-chain risk because published advisories indicate FTP command injection and denial-of-service conditions. In this lockfile it is only a transitive devDependency via get-uri/pac-proxy-agent/proxy-agent used by browser tooling, which reduces exposure, but if the skill processes attacker-controlled FTP URLs or PAC-related inputs during development or testing, exploitation could lead to unintended outbound requests, command injection at the FTP protocol layer, or process disruption.

Known Vulnerable Dependency: extract-zip==2.0.1 — 2 advisory(ies): CVE-2026-19693 (extract-zip allows arbitrary file writes through symlink archive entries); CVE-2026-56876 (extract-zip unvalidated symlink path traversal)

High
Category
Supply Chain
Confidence
96% confidence
Finding
extract-zip 2.0.1 has advisories for arbitrary file write and symlink traversal during archive extraction, which is a genuine high-risk class of issue. Here it is pulled in through @puppeteer/browsers as a devDependency, so the main danger arises when downloading and extracting browser archives; if an attacker can influence the archive source or contents, files could be written outside the intended directory.

Known Vulnerable Dependency: ip-address==10.1.0 — 2 advisory(ies): CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco); CVE-2026-42338 (ip-address has XSS in Address6 HTML-emitting methods)

High
Category
Supply Chain
Confidence
84% confidence
Finding
ip-address 10.1.0 is flagged by advisories, but in this dependency tree it is a transitive devDependency under socks/socks-proxy-agent/proxy-agent and there is no direct evidence from the lockfile that the vulnerable HTML-emitting methods or ambiguous IPv4 parsing paths are exposed to untrusted user input. The issue is still real at the package level, but in this skill context its exploitability appears limited and likely lower impact than the archive and websocket issues.

Known Vulnerable Dependency: tar-fs==3.0.4 — 3 advisory(ies): CVE-2025-48387 (tar-fs can extract outside the specified dir with a specific tarball); CVE-2024-12905 (tar-fs Vulnerable to Link Following and Path Traversal via Extracting a Crafted ); CVE-2025-59343 (tar-fs has a symlink validation bypass if destination directory is predictable w)

High
Category
Supply Chain
Confidence
97% confidence
Finding
tar-fs 3.0.4 has multiple path traversal and link-following advisories affecting archive extraction, which are credible and serious filesystem compromise primitives. In this lockfile it is a transitive devDependency via @puppeteer/browsers, so exposure is tied to fetching and unpacking browser artifacts; if a crafted tarball is processed, extraction could escape the target directory and overwrite arbitrary files.

Known Vulnerable Dependency: ws==8.16.0 — 3 advisory(ies): CVE-2024-37890 (ws affected by a DoS when handling a request with many HTTP headers); CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
90% confidence
Finding
ws 8.16.0 has known denial-of-service and possible memory disclosure advisories, and this is a genuine concern because browser automation stacks commonly expose websocket-based DevTools/BiDi connections. In this skill's context, which explicitly manages CDP/ADB/browser automation, websocket handling is more security-relevant than in a generic package, though the lockfile alone does not prove direct external exposure.

Session Persistence

Medium
Category
Rogue Agent
Content
1. **Start the Morelogin app**
2. **Log in** (register a new account or log in to an existing one)
3. **Create a browser profile**:
   - Click "Create Profile"
   - Select browser type (Chrome recommended)
   - Configure proxy (optional)
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The guide tells users to record profile names, identifiers, and IP/region metadata in `TOOLS.md`, which may be broadly readable in the workspace and can expose operational account mapping. In the context of an anti-detect browser and multi-account automation tool, those identifiers are more sensitive than ordinary app settings because they help enumerate accounts and infrastructure used for automation.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
Exporting `MORELOGIN_TOKEN` in shell startup files persists the credential in plaintext across sessions and increases the chance of leakage through backups, dotfile sync, local disclosure, or accidental sharing. Because this token likely grants access to profile-management functions, exposure could enable unauthorized control of browser profiles or related automation resources.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# Morelogin defaults to localhost only

# Use firewall rules
sudo pfctl -f /etc/pf.conf  # macOS
```

### 3. Isolate Profiles
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The quick-start includes commands to clear local and cloud cache, which can affect user data and session state, but the markdown provides no warning about the impact or that the action may be difficult to undo. For markdown files, safety-affecting behaviors should be disclosed to the user.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The command reference includes delete operations for proxies, groups, and tags, but the document does not warn that these commands remove configuration objects and may be irreversible. In markdown skill documentation, destructive operations should be accompanied by clear cautions about impact on user data or system state.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
bin/common.js:3