Back to skill

Security audit

Mobilerun

Security checks for vulnerabilities and agentic risk

Overview

The skill is openly for remote Android control, but it asks for very sensitive device access and includes under-scoped automatic feedback, shell, and sideloading behavior users should review carefully.

Install only if you are comfortable giving Mobilerun remote control visibility into an Android device. Prefer a test or cloud device, avoid sensitive apps unless necessary, verify the Portal APK source independently, revoke Accessibility permission when done, and review any destructive action or feedback payload before allowing it.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:847
Finding
Automatic Transmission of Potentially Sensitive Diagnostic Data Without User Consent<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:847-870`; conflicting privacy statement at `references/security.md:5-10` **Vulnerability Type**: Unconsented telemetry and sensitive diagnostic-data disclosure **Risk Level**: Medium ### Vulnerable Code Snippet ```markdown ## Feedback Submit feedback to help improve the Mobilerun platform. This is important for identifying bugs and improving agent performance. **When to auto-submit feedback:** - When a task fails unexpectedly - When the agent behaves incorrectly or produces wrong results - When API errors occur that seem like platform bugs - Include the `taskId`, error details, and what happened **When the user asks to submit feedback:** - Ask for a few details (what happened, what they expected) but don't push hard - If they don't want to elaborate, just submit with whatever details you have POST /feedback Content-Type: application/json { "title": "Task failed unexpectedly", "feedback": "The agent got stuck on the login screen and timed out after 50 steps.", "rating": 2, "taskId": "uuid-of-related-task" } ``` The security documentation makes the following conflicting assertion: ```markdown ## Data Handling - **Screenshots and UI tree data** may contain personal information visible on the user's screen (messages, emails, photos, etc.). This data is fetched on-demand for the current task and is not stored, cached, or transmitted beyond the API response. - All API calls go to `https://api.mobilerun.ai/v1` over HTTPS. - The skill does not collect analytics, telemetry, or usage data. ``` ### Technical Analysis The Skill directs the agent to submit feedback automatically when a task fails, behaves incorrectly, or encounters a suspected platform error. The submission includes a task identifier, error details, and a narrative describing what happened. These values may expose sensitive task context, including application names, task objectives, account-related states, UI content, or d ...[truncated 1667 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic feedback submission and require explicit, informed user approval before every transmission. 2. Show the complete proposed feedback payload to the user before submission. 3. Apply data minimization: - Exclude screenshots and accessibility-tree content. - Remove message text, email content, contacts, account identifiers, and credentials. - Avoid including full task prompts when a generic failure classification is sufficient. 4. Redact tokens, authorization headers, API keys, URLs containing signed parameters, and other secrets. 5. Make `taskId` optional and include it only when necessary for a user-approved support request. 6. Document feedback retention, access controls, processing purposes, and deletion procedures. 7. Correct `references/security.md` so that it accurately discloses feedback telemetry and its consent model. 8. Add a structured local redaction pass and a strict schema that rejects unexpected diagnostic fields. ]]>

T08 · Insecure Dependencies

Error
Location
references/setup-and-billing.md:53
Finding
Unverified APK Sideloading Followed by Granting Accessibility Service Privileges<![CDATA[ ## Vulnerability Details **File Location**: `references/setup-and-billing.md:53-75` **Vulnerability Type**: Unverified third-party binary installation with high-impact Android permissions **Risk Level**: High ### Vulnerable Code Snippet ```markdown ### Step 1: Download the Portal APK 1. On the Android device, open Chrome and go to **https://droidrun.ai/portal** 2. This redirects to the GitHub releases page for the Portal app 3. Scroll down to the **"Assets"** section at the bottom of the latest release 4. Tap the file named **`droidrun-portal-vx.x.x.apk`** (the version number varies) -- this is the APK file to download - Do NOT tap "Source code (zip)" or "Source code (tar.gz)" -- those are the source code, not the app ### Step 2: Install the APK 1. Once downloaded, tap the APK file to install it (or find it in Downloads) 2. **Android may show a sideloading prompt** -- this is standard for apps distributed outside the Play Store (like beta apps or open-source projects): - Droidrun Portal is open source: https://github.com/droidrun/droidrun-portal - Follow the on-screen prompts to complete installation ### Step 3: Enable Accessibility 1. Open the Droidrun Portal app 2. A red banner at the top says **"Accessibility Service Not Enabled"** -- tap **"Enable Now"** 3. This opens Android Settings. Find **"Droidrun Portal"** in the list of accessibility services 4. Tap on it and **toggle it on** 5. Android will show a confirmation dialog explaining what the accessibility service can do -- tap **"Allow"** or **"OK"** This permission is required -- without it, the agent cannot read the screen UI tree or control the device. ``` ### Technical Analysis The setup process tells users to follow a redirect, download the mutable “latest” APK release, sideload it, and then grant it Android Accessibility Service privileges. It does not provide a pinned release version, SHA-256 digest, expected signing-certificate fingerprint, reproducible-build verific ...[truncated 2196 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin setup instructions to a specifically reviewed Portal release rather than a mutable “latest” release. 2. Publish an expected SHA-256 digest through a separately protected official channel and require users to verify it before installation. 3. Publish and document the expected Android signing-certificate SHA-256 fingerprint. 4. Instruct users to verify that upgrades are signed by the same certificate as the installed application. 5. Prefer distribution through a verified application store with signing and update protections. 6. If sideloading remains necessary: - Link directly to the canonical release page. - Clearly state the expected final download domain. - Warn users to stop if redirects or filenames differ. - Provide exact release and verification instructions. 7. Protect release publication with hardware-backed multifactor authentication, branch protection, signed tags, isolated builds, and provenance attestations. 8. Consider reproducible builds and publish build provenance so that the binary can be compared with the public source. 9. Explain the full security implications of Accessibility Service permission before instructing the user to grant it. 10. Request only the Android permissions strictly necessary for remote-control functionality. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
references/troubleshooting.md:61
Finding
Generic Device Shell Endpoint Expands Control Beyond the Documented Least-Privilege Interface<![CDATA[ ## Vulnerability Details **File Location**: `references/troubleshooting.md:61-72` **Vulnerability Type**: Excessive device command-execution capability **Risk Level**: High ### Vulnerable Code Snippet ```markdown **7. Play Store won't open via `PUT /apps/com.android.vending`** - **Symptom:** Attempting to open the Play Store via the apps endpoint fails or the app doesn't launch. - **Cause:** Some devices restrict programmatic launching of the Play Store, or the Play Store package name doesn't respond to standard launch intents. - **Fix:** Use a tap-based approach instead: 1. Take a screenshot to see the current screen 2. Navigate to the home screen: `POST /devices/{deviceId}/key` with `HOME` 3. Look for the Play Store icon in the UI tree and tap it, or use the shell endpoint: ``` POST /devices/{deviceId}/shell {"command": "am start -a android.intent.action.MAIN -n com.android.vending/.AssetBrowserActivity"} ``` ``` ### Technical Analysis The troubleshooting guide introduces a shell endpoint that accepts a free-form command string. The documented use only invokes an Android activity manager command to launch the Play Store, but the interface is substantially more powerful than the narrowly scoped tap, swipe, keyboard, global-action, and app-management operations described elsewhere. Launching a known application does not require a generic shell-command primitive. A dedicated launch endpoint or a fixed server-side operation would satisfy the stated need with fewer privileges. The documentation does not specify: - A server-side command allowlist - Rejection of shell metacharacters or compound commands - The Android identity under which commands execute - Whether user-controlled values can enter the command - A confirmation requirement - Auditing or command-output handling - Restrictions against accessing files, settings, packages, or system services The security guide warns against interpolating raw user input into URL ...[truncated 1898 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the generic shell fallback from the Skill. 2. Use the existing application-launch endpoint or add a dedicated operation that launches a fixed, validated package and activity. 3. If a shell endpoint must remain: - Enforce a strict server-side allowlist of complete command templates. - Do not pass requests through a shell interpreter. - Invoke commands using a fixed argument array. - Reject metacharacters, redirections, substitutions, pipelines, and additional commands. - Validate package and activity identifiers against installed-package data. 4. Never interpolate raw user input into a command. 5. Require explicit user approval before every shell operation and display the exact operation in understandable terms. 6. Execute commands under the least-privileged Android identity available. 7. Deny access to filesystem inspection, package installation, settings mutation, credential stores, and privileged services unless separately authorized for a necessary feature. 8. Record tamper-resistant audit events containing the approved operation, device, time, and result while excluding sensitive output. 9. Apply short timeouts, output-size limits, and rate limits. 10. Document the endpoint’s permission model and supported operations in the primary security documentation. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (32)

Vague Triggers

High
Confidence
97% confidence
Finding
The activation trigger is extremely broad, covering essentially any request involving phones, automation, screenshots, reading screens, scraping, app testing, and AI agent tasks. That increases the chance the skill is loaded into contexts where invasive device control, data access, or destructive actions become available unnecessarily, expanding attack surface and likelihood of misuse.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
**What to show the user:** Only report user-relevant device info: device name, state (`ready`/`disconnected`). Do NOT surface internal fields like `streamUrl`, `streamToken`, socket status, `assignedAt`, `terminatesAt`, or `taskCount` unless the user explicitly asks for technical details. If a device is `disconnected`, simply tell the user their phone is disconnected and ask them to open the Portal app and tap Connect. If they need help, walk them through the setup steps in [references/setup-and-billing.md](./references/setup-and-billing.md).

**Clean up cloud devices:** Cloud devices consume credits while running. Always terminate cloud devices (`DELETE /devices/{deviceId}`) when you're done using them -- don't leave them running. This applies whether you provisioned the device yourself or finished a task on an existing cloud device that the user no longer needs.

**Privacy:** Screenshots and the UI tree can contain sensitive personal data. Never share or transmit this data to anyone other than the user. Never print, log, or reveal the `MOBILERUN_API_KEY` in chat -- use it only for API calls.
Confidence
84% confidence
Finding
The skill instructs the agent to always terminate cloud devices when done, including devices that may already exist and that the user may still want. Because DELETE is immediate and state-changing, this creates a meaningful risk of unintended service disruption, loss of session state, and unnecessary destructive actions without explicit confirmation.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
2. `GET /devices/{deviceId}/wait` -- wait until ready
3. `POST /tasks` with the new `deviceId` -- run the task (or submit multiple tasks -- they will queue and execute in order)
4. Monitor via `GET /tasks/{taskId}/status` until all tasks finish
5. `DELETE /devices/{deviceId}` -- terminate the device

**Important:** `DELETE /devices/{deviceId}` terminates the device immediately. If any tasks are still queued or running on that device, they will be orphaned or interrupted. Always wait for all tasks to finish before terminating.
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
2. `GET /devices/{deviceId}/wait` -- wait until ready
3. `POST /tasks` with the new `deviceId` -- run the task (or submit multiple tasks -- they will queue and execute in order)
4. Monitor via `GET /tasks/{taskId}/status` until all tasks finish
5. `DELETE /devices/{deviceId}` -- terminate the device

**Important:** `DELETE /devices/{deviceId}` terminates the device immediately. If any tasks are still queued or running on that device, they will be orphaned or interrupted. Always wait for all tasks to finish before terminating.
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### Terminate a Cloud Device

```
DELETE /devices/{deviceId}
Content-Type: application/json

{}
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### Clear Input

```
DELETE /devices/{deviceId}/keyboard
```

Clears the currently focused input field.
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### Uninstall App

```
DELETE /devices/{deviceId}/apps/{packageName}
Content-Type: application/json

{}
Confidence
88% confidence
Finding
The skill exposes an app uninstall action on the controlled device without clearly requiring heightened confirmation before use. Uninstalling apps is destructive, can remove user data or access to important tools, and is especially risky in a broadly activated phone-control skill.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### Delete an App

```
DELETE /apps/{id}
```

Removes the app from R2 storage and the database. Use this before re-uploading an app with the same package name.
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Only one app per package name is allowed. To update:
1. Find the existing app: `GET /apps?query=com.example.myapp`
2. Delete it: `DELETE /apps/{id}`
3. Upload the new version using the 3-step upload flow above

---
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Exfiltration Commands

High
Category
Prompt Injection
Content
- Send a message via `POST /tasks/{id}/message` to nudge it in the right direction.
- Let the user know and ask if they want to steer it or cancel.

### Send Message to Task

```
POST /tasks/{task_id}/message
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
2. Alternatively, install the app manually on the device through the Play Store, then use it directly
  3. For cloud devices, specify required apps in the `apps` array when provisioning: `POST /devices?deviceType=... { "apps": ["com.example.app"] }`

**9. `DELETE /keyboard` (clear) fails -- 'Accessibility fallback failed'**

- **Symptom:** `DELETE /devices/{deviceId}/keyboard` returns an error about accessibility fallback failing.
- **Cause:** The clear-text action relies on the accessibility service to select and delete text. It can fail if the focused field doesn't support text selection or the accessibility service lost its connection.
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
**9. `DELETE /keyboard` (clear) fails -- 'Accessibility fallback failed'**

- **Symptom:** `DELETE /devices/{deviceId}/keyboard` returns an error about accessibility fallback failing.
- **Cause:** The clear-text action relies on the accessibility service to select and delete text. It can fail if the focused field doesn't support text selection or the accessibility service lost its connection.
- **Fix:** Use an alternative approach to clear text:
  1. Type replacement text with the `clearFirst` flag:
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

External Transmission

Medium
Category
Data Exfiltration
Content
The hosted mobile cloud platform. Grant AI native control of Android devices to tap, swipe, type, navigate apps, fill out forms, extract data, automate workflows, and run QA. Connect your own phone, spin up on-demand virtual devices, or use always-on emulated and physical devices in the cloud. iOS support coming soon.

Base URL: `https://api.mobilerun.ai/v1`
Auth: `Authorization: Bearer <MOBILERUN_API_KEY>`

**Important:** The base domain (`https://api.mobilerun.ai/`) returns 404. You must always include `/v1` in the path. All API calls should be made via `curl`. Example:
Confidence
87% confidence
Finding
The skill is fundamentally designed to send device commands and retrieve device data from an external API endpoint. In context this is expected functionality, but it is still a real external-transmission capability because screenshots, UI state, app/package information, and task instructions flow to a third-party service.

External Transmission

Medium
Category
Data Exfiltration
Content
Base URL: `https://api.mobilerun.ai/v1`
Auth: `Authorization: Bearer <MOBILERUN_API_KEY>`

**Important:** The base domain (`https://api.mobilerun.ai/`) returns 404. You must always include `/v1` in the path. All API calls should be made via `curl`. Example:

```bash
curl -s https://api.mobilerun.ai/v1/devices \
Confidence
87% confidence
Finding
This line reinforces the use of an external API with bearer-token authentication, enabling third-party transmission of commands and potentially sensitive mobile-device data. Although core to the skill's purpose, it still represents meaningful data egress and remote-control capability that must be treated as sensitive.

External Transmission

Medium
Category
Data Exfiltration
Content
**Important:** The base domain (`https://api.mobilerun.ai/`) returns 404. You must always include `/v1` in the path. All API calls should be made via `curl`. Example:

```bash
curl -s https://api.mobilerun.ai/v1/devices \
  -H "Authorization: Bearer $MOBILERUN_API_KEY"
```
Confidence
87% confidence
Finding
The example curl call demonstrates direct communication with the external Mobilerun service using the user's API credential. That creates a concrete path for off-platform transmission and remote actuation, which is sensitive even if intended.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Quick Start

The API key (`MOBILERUN_API_KEY`) is already available -- OpenClaw handles credential setup before this skill loads. Do NOT ask the user for an API key. Just use it.

1. **Check for a ready device:**
   ```bash
Confidence
80% 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.

External Transmission

Medium
Category
Data Exfiltration
Content
1. **Check for a ready device:**
   ```bash
   curl -s https://api.mobilerun.ai/v1/devices \
     -H "Authorization: Bearer $MOBILERUN_API_KEY"
   ```
   - `state: "ready"` = **good to go, skip to the user's request**
Confidence
87% confidence
Finding
Listing devices via the external API transmits account/device metadata to a third-party service and obtains inventory information about connected phones. In a phone-control skill, this is expected but still security-relevant because it exposes connected-device context and readiness for control.

External Transmission

Medium
Category
Data Exfiltration
Content
3. **Take a screenshot to confirm** (optional, only if first action fails):
   ```bash
   curl -s https://api.mobilerun.ai/v1/devices/{deviceId}/screenshot \
     -H "Authorization: Bearer $MOBILERUN_API_KEY" -o screenshot.png
   ```
   If this returns a PNG image, the device is working.
Confidence
90% confidence
Finding
Taking screenshots through the external API is a genuine data-transmission risk because screenshots can contain highly sensitive personal information from the user's device. This is core functionality, but the sensitivity is elevated by the nature of the data being collected and transmitted.

Missing User Warnings

Medium
Confidence
82% confidence
Finding
The skill encourages the agent to proceed directly with device actions when a device is ready and emphasizes operational efficiency, but it does not consistently require user confirmation before destructive or high-impact operations like deleting cloud devices, uninstalling apps, typing into forms, or modifying settings. In a phone-control context, that can lead to unintended state changes or privacy-impacting actions without an adequate consent checkpoint.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The document tells the agent not to share screenshots or UI data with anyone other than the user, yet later instructs sending related task details to the platform via feedback. That inconsistency can cause privacy-sensitive device context to be disclosed under the guise of support/feedback, undermining the stated privacy boundary.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Get all clickable/interactive elements
curl -s "https://api.mobilerun.ai/v1/devices/{id}/ui-state?filter=true" \
  -H "Authorization: Bearer $MOBILERUN_API_KEY" | \
  jq '[.a11y_tree | recurse(.children[]?) |
  select(.isClickable==true or .isEditable==true) |
Confidence
90% confidence
Finding
Fetching UI state from the external API transmits structured accessibility-tree data that may reveal screen contents, app structure, visible text, and interactive elements. In practice this can be as sensitive as screenshots and enables detailed remote observation of the device.

External Transmission

Medium
Category
Data Exfiltration
Content
{text: (.text // .contentDescription), bounds: .boundsInScreen, isEditable}]'

# Get elements with content descriptions (media items, icons, etc.)
curl -s "https://api.mobilerun.ai/v1/devices/{id}/ui-state?filter=true" \
  -H "Authorization: Bearer $MOBILERUN_API_KEY" | \
  jq '[.a11y_tree | recurse(.children[]?) |
  select(.contentDescription != null and .contentDescription != "") |
Confidence
90% confidence
Finding
This UI-state example extracts content descriptions, which can expose labels and semantic information about the current screen to the external platform. That is intended functionality, but it materially increases observability into user activity and on-screen content.

External Transmission

Medium
Category
Data Exfiltration
Content
{desc: .contentDescription, bounds: .boundsInScreen, isClickable}]'

# Get editable fields only
curl -s "https://api.mobilerun.ai/v1/devices/{id}/ui-state?filter=true" \
  -H "Authorization: Bearer $MOBILERUN_API_KEY" | \
  jq '[.a11y_tree | recurse(.children[]?) |
  select(.isEditable==true) | {text, resourceId, bounds: .boundsInScreen}]'
Confidence
90% confidence
Finding
Extracting editable fields from UI state can reveal draft text, form structure, and input targets on the user's device through the external API. That is a real privacy and integrity risk because it facilitates both observation and manipulation of sensitive inputs.

External Transmission

Medium
Category
Data Exfiltration
Content
select(.isEditable==true) | {text, resourceId, bounds: .boundsInScreen}]'

# Get phone state + screen bounds only (lightweight, always safe)
curl -s "https://api.mobilerun.ai/v1/devices/{id}/ui-state?filter=true" \
  -H "Authorization: Bearer $MOBILERUN_API_KEY" | \
  jq '{phone_state, device_context}'
```
Confidence
84% confidence
Finding
This example fetches only phone state and screen bounds, which is less sensitive than full UI trees or screenshots, but it still involves external transmission of device context. The context makes it less dangerous than the other E1 instances, though it remains part of the remote-observation surface.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
Submit 2 tasks:
1. `"Open the Uber app, set the destination to 123 Main Street, select UberX, and stop before confirming -- report back the estimated price and arrival time"`
2. Only submit after reviewing the result of task 1 with the user — don't auto-confirm a purchase.

**Include safety conditions when appropriate:**
- `"If the app asks for login, stop and tell me"`
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.

Static analysis

No suspicious patterns detected.