Back to skill

Security audit

Awesome GeeLark Skill

Security checks for vulnerabilities and agentic risk

Overview

This GeeLark automation skill is mostly coherent, but it needs review because it handles powerful API and social-account credentials with real credential-protection gaps.

Install only after reviewing the credential flow. Keep baseUrl fixed to the official GeeLark API, create a real .gitignore entry for assets/config.json and logs, set config permissions to 600, prefer environment variables or a secret store, rotate exposed tokens, and do not give third-party social-media passwords to the agent. Manually confirm deletion, posting, credentialed RPA, and bulk operations.

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/init_config.py:54
Finding
API credentials are visibly collected and stored without enforced restrictive permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/init_config.py:54-82` **Related Documentation**: `scripts/init_config.py:89-92`, `SKILL.md:21-23` **Vulnerability Type**: Plaintext credential exposure and insecure file permissions **Risk Level**: Medium ### Vulnerable Code ```python token = input("Token: ").strip() if not token: print("❌ Token is required") return None app_id = input("App ID (optional, press Enter to skip): ").strip() api_key = input("API Key (optional, press Enter to skip): ").strip() # Create config config = { "auth": { "token": token, }, "baseUrl": "https://openapi.geelark.com", "rateLimit": { "perMinute": 200, "perHour": 24000 } } if app_id: config["auth"]["appId"] = app_id if api_key: config["auth"]["apiKey"] = api_key # Save config with open(config_path, 'w', encoding='utf-8') as f: json.dump(config, f, indent=2, ensure_ascii=False) ``` The script subsequently claims that the credential file is protected: ```python print(" - config.json contains your sensitive credentials") print(" - Do NOT commit config.json to version control") print(" - config.json is already in .gitignore") ``` ### Technical Analysis The initializer uses `input()` for the bearer token and API key. Unlike a secret-aware prompt such as `getpass.getpass()`, `input()` displays the entered value on the terminal. This can expose credentials through shoulder surfing, screen recording, terminal-sharing sessions, or captured interactive output. The credentials are then written as plaintext using the process's default file-creation mode. The code neither creates the file with mode `0600` nor applies `os.chmod(config_path, 0o600)` after writing it. Consequently, effective access depends on the user's umask and environment. Under a permissive configuration, other local users or processes may be able to read the file. The audited project structure did not contain the `.gitignore` fi ...[truncated 1913 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use non-echoing prompts for all secrets: ```python from getpass import getpass token = getpass("Token: ").strip() api_key = getpass("API Key (optional, press Enter to skip): ").strip() ``` 2. Create the configuration file atomically with owner-only permissions: ```python import os import json import tempfile fd, temporary_path = tempfile.mkstemp( dir=assets_dir, prefix=".config-", text=True ) try: os.fchmod(fd, 0o600) with os.fdopen(fd, "w", encoding="utf-8") as f: json.dump(config, f, indent=2, ensure_ascii=False) f.flush() os.fsync(f.fileno()) os.replace(temporary_path, config_path) os.chmod(config_path, 0o600) except Exception: try: os.unlink(temporary_path) except OSError: pass raise ``` 3. Add and distribute an actual `.gitignore` containing at least: ```gitignore assets/config.json logs/ ``` 4. Remove or correct the claim that `.gitignore` protection already exists unless the file is included and verified. 5. Prefer an operating-system credential store, injected environment secret, or dedicated secret manager instead of long-term plaintext token storage. 6. On startup, verify that the credential file is owned by the current user and is not group- or world-readable. Refuse to continue or display a prominent warning when permissions are unsafe. 7. Document token rotation and immediate revocation procedures for suspected exposure. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/geelark_client.py:91
Finding
Configurable API origin permits forwarding the bearer token to an untrusted server<![CDATA[ ## Vulnerability Details **File Location**: `scripts/geelark_client.py:91-124` **Related Locations**: `scripts/utils.py:82-94`, `scripts/doctor.py:171-188`, `scripts/geelark_boot_helper.py:212-230` **Vulnerability Type**: Unvalidated destination for authenticated network requests **Risk Level**: Medium ### Vulnerable Code The client accepts a caller-supplied or configuration-supplied base URL without validating its scheme or hostname: ```python if base_url is None: # Load base URL from config file base_url = get_base_url() self.token = token self.base_url = base_url self._phones_started = set() # Track started phones, must close after use # Initialize logger if task_name and phone_id are provided self._log = None if task_name and phone_id: self._log = CloudPhoneLog(task_name, phone_id) self._log.info("GeeLarkClient initialized") ``` The bearer token is subsequently attached to requests sent to that origin: ```python resp = requests.post( f"{self.base_url}{endpoint}", headers={"Content-Type": "application/json", "traceId": generate_traceid(), "Authorization": f"Bearer {self.token}"}, json=data, timeout=timeout ) ``` The configuration helper returns `baseUrl` without destination validation: ```python def get_base_url(config_path: Optional[str] = None) -> str: """ Get Base URL from config file. """ config = load_config(config_path) return config['baseUrl'] ``` ### Technical Analysis The endpoint whitelist in `GeeLarkClient.call()` restricts API path names, but it does not restrict the network destination. `baseUrl` may come from `assets/config.json` or directly from a caller, and the implementation does not enforce: - The HTTPS scheme. - The official `openapi.geelark.com` hostname. - The standard HTTPS port. - Absence of embedded URL credentials. - A trusted-origin policy for custom deployments. The Authorization header is constructed independently of the destination and is the ...[truncated 2565 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce an explicit trusted-origin policy before storing or using `base_url`: ```python from urllib.parse import urlparse TRUSTED_API_HOSTS = {"openapi.geelark.com"} def validate_base_url(value: str) -> str: parsed = urlparse(value) if parsed.scheme != "https": raise ValueError("GeeLark API base URL must use HTTPS") if parsed.hostname not in TRUSTED_API_HOSTS: raise ValueError("Untrusted GeeLark API hostname") if parsed.port not in (None, 443): raise ValueError("Unexpected GeeLark API port") if parsed.username or parsed.password: raise ValueError("Credentials are not allowed in the API URL") if parsed.query or parsed.fragment: raise ValueError("Query strings and fragments are not allowed in the API base URL") return value.rstrip("/") ``` 2. Validate the default configuration value when loading it and validate caller-provided values in every public constructor or helper that accepts `base_url`. 3. Prefer removing configurable production origins entirely if no legitimate alternate GeeLark endpoint is required. 4. If custom deployments are necessary, require an explicit opt-in flag and a separate credential for each trusted origin. Never automatically reuse the production GeeLark token for an arbitrary custom origin. 5. Create a `requests.Session` with a destination-checking request wrapper so all authenticated requests consistently enforce the trusted origin. 6. Reject plaintext HTTP unconditionally when credentials are attached. 7. Avoid including authentication headers in generic connectivity checks. Separate unauthenticated reachability testing from authenticated API validation. 8. Add tests confirming that malformed URLs, HTTP URLs, alternate ports, local addresses, IP literals, and untrusted domains are rejected before any request is made. ]]>
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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (62)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill description emphasizes GeeLark API management and social-media operations, but the supplied content prominently includes local diagnostics, app launching by package name, UI hierarchy dumping, and ADB-serial workflows. Such description-behavior mismatch is dangerous in security terms because it obscures operational reach and may lead an agent or reviewer to authorize broader local-device control than intended.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill description emphasizes GeeLark API management and social-media operations, but the supplied content prominently includes local diagnostics, app launching by package name, UI hierarchy dumping, and ADB-serial workflows. Such description-behavior mismatch is dangerous in security terms because it obscures operational reach and may lead an agent or reviewer to authorize broader local-device control than intended.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill description emphasizes GeeLark API management and social-media operations, but the supplied content prominently includes local diagnostics, app launching by package name, UI hierarchy dumping, and ADB-serial workflows. Such description-behavior mismatch is dangerous in security terms because it obscures operational reach and may lead an agent or reviewer to authorize broader local-device control than intended.

Chaining Abuse

High
Category
Tool Misuse
Content
brew install android-platform-tools

# Ubuntu/Debian
sudo apt update && sudo apt install adb

# Windows
# Option 1: Using winget
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Ae1

High
Category
analysis-evasion
Content
| `references/error_codes.md` | All error codes and solutions | API call fails |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Instruction Override

High
Category
Prompt Injection
Content
import uiautomator2 as u2

d = u2.connect(f"{ip}:{port}")
d.debug = True  # Enable debug mode to see HTTP request/response details
```

### 3. Test with Single Device First
Confidence
70% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Instruction Override

High
Category
Prompt Injection
Content
import uiautomator2 as u2

d = u2.connect(f"{ip}:{port}")
d.debug = True  # Enable debug mode to see HTTP request/response details
```

### 3. Test with Single Device First
Confidence
70% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Instruction Override

High
Category
Prompt Injection
Content
## Debugging Tips

### Enable Debug Mode

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

Instruction Override

High
Category
Prompt Injection
Content
## Debugging Tips

### Enable Debug Mode

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

Instruction Override

High
Category
Prompt Injection
Content
## Debugging Tips

### Enable Debug Mode

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

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Install system dependencies
# macOS:   brew install android-platform-tools
# Ubuntu:  sudo apt install adb

# Install Python dependencies (recommended: use virtual environment)
python3 -m venv .venv
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill documents capabilities that involve reading credentials from local files, writing logs, making network/API calls, and executing local subprocesses, but it does not declare any explicit tool scope such as allowed-tools or permissions. In an agent environment, this creates an authorization gap where consumers may invoke a skill without understanding or constraining its actual access, increasing the risk of unintended shell execution, credential exposure, or filesystem/network misuse.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
> **Credential Handling:**
> - API credentials (token, appId, apiKey) are stored in `assets/config.json`
> - This file is protected by `.gitignore` — **never commit it**
> - Set restrictive permissions: `chmod 600 assets/config.json`
> - **⚠️RPA tasks require third-party account login. We recommend completing login in GeeLark first. Never send account credentials to the agent.**
> - Logs are written to `logs/cloudphone/` — review and mask sensitive data before sharing
>
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
> **Credential Handling:**
> - API credentials (token, appId, apiKey) are stored in `assets/config.json`
> - This file is protected by `.gitignore` — **never commit it**
> - Set restrictive permissions: `chmod 600 assets/config.json`
> - **⚠️RPA tasks require third-party account login. We recommend completing login in GeeLark first. Never send account credentials to the agent.**
> - Logs are written to `logs/cloudphone/` — review and mask sensitive data before sharing
>
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
brew install android-platform-tools

# Ubuntu/Debian
sudo apt update && sudo apt install adb

# Windows
# Option 1: Using winget
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
brew install android-platform-tools

# Ubuntu/Debian
sudo apt update && sudo apt install adb

# Windows
# Option 1: Using winget
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## 🗑️ Deletion Workflow (MANDATORY)

**⚠️ AI agents MUST follow this exact sequence for deletion operations. Never skip steps or auto-execute.**

### Step 1: List Available Phones
```python
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- **Credential Rotation**: Implement regular credential rotation on a scheduled basis. 
- **File Permissions**: Restrict access to `assets/config.json`:
  ```bash
  chmod 600 assets/config.json
  ```
- **Log Review**: Before sharing logs, review `logs/cloudphone/` for sensitive data and redact as needed
- **Dependency Verification**: Verify `adb` and `uiautomator2` are from official sources
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

External Transmission

Medium
Category
Data Exfiltration
Content
"Authorization": "Bearer your_token_here"
}

response = requests.post(
    "https://openapi.geelark.com/open/v1/phone/list",
    headers=headers,
    json={"page": 1, "pageSize": 10}
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
"Authorization": "Bearer your_token_here"
}

response = requests.post(
    "https://openapi.geelark.com/open/v1/phone/list",
    headers=headers,
    json={"page": 1, "pageSize": 10}
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
"Authorization": "Bearer your_token_here"
}

response = requests.post(
    "https://openapi.geelark.com/open/v1/phone/list",
    headers=headers,
    json={"page": 1, "pageSize": 10}
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
"Authorization": "Bearer your_token_here"
}

response = requests.post(
    "https://openapi.geelark.com/open/v1/phone/list",
    headers=headers,
    json={"page": 1, "pageSize": 10}
Confidence
70% 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
90% confidence
Finding
This markdown file documents `/open/v1/phone/delete` and marks it with a warning icon, but the surrounding text only notes a prerequisite that phones must be stopped first, not that deletion may be destructive or irreversible. Under the markdown-specific SQP-2 criteria, descriptions of actions affecting user data or system state should clearly warn about those impacts.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The markdown lists `/open/v1/group/delete`, `/open/v1/tag/delete`, and `/open/v1/proxy/delete` as available operations, but it does not warn users that these actions remove configuration objects and may disrupt existing setups or automation. For markdown files, SQP-2 applies when potentially destructive behaviors are described without clear warnings about user/system impact.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation normalizes submitting third-party account credentials such as TikTok, Instagram, Facebook, Google, and Shein usernames/passwords through API tasks without privacy or handling safeguards. In an agent-skill context, this increases the risk of credential collection, insecure storage, unintended logging, and transmission of sensitive secrets to an external service.

Static analysis

No suspicious patterns detected.