Back to skill

Security audit

maestro-mobile-test

Security checks for vulnerabilities and agentic risk

Overview

This mobile-testing skill mostly matches its stated purpose, but setup can run unverified internet-downloaded code and privileged installers.

Review before installing or running setup. Prefer installing Maestro from a pinned, verified release instead of curl | bash, run setup as an unprivileged user, approve any sudo/package-manager steps deliberately, and avoid copying the CI example until the installer and third-party actions are pinned and verified.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/setup.sh:154
Finding

Unverified Remote Installer Execution in Setup Script

Content
View full analysis
/dev/null; then MAESTRO_VERSION=$(maestro --version 2>&1 | head -1) echo "✅ Maestro found: $MAESTRO_VERSION" else echo "Installing Maestro CLI..." if [ -n "${JAVA_HOME:-}" ]; then export PATH="$JAVA_HOME/bin:$PATH" fi curl -Ls "https://get.maestro.mobile.dev" | bash echo "" export PATH="$HOME/.maestro/bin:$PATH" echo "✅ Maestro installed to ~/.maestro/bin" fi ``` ### Technical Analysis The setup script downloads a mutable response from `https://get.maestro.mobile.dev` and passes it directly to Bash. It does not pin a Maestro version, verify a cryptographic signature, validate a checksum, save the response for inspection, or constrain the downloaded program. TLS protects the connection in transit, but it does not protect against compromise of the publisher's infrastructure, DNS or account takeover, accidental replacement of the installer, or a future malicious modification at the same URL. The effective code executed by the Skill can therefore change after the packaged Skill has been reviewed. This behavior is not the minimum privilege or trust level necessary to install Maestro. A fixed release artifact can be downloaded and verified without granting a remote endpoint an unrestricted shell execution channel. ### Attack Path 1. An attacker compromises the remote installer endpoint, its publishing pipeline, or credentials controlling its content. 2. The attacker replaces the expected installer with arbitrary shell commands. 3. A user runs `scripts/setup.sh` while Maestro is not already available in `PATH`. 4. `curl` retrieves the attacker-controlled response. 5. The shell immediately interprets the response as Bash code w ...[truncated 916 chars]
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:28
Finding

Documentation Recommends Direct Execution of a Mutable Remote Script

Content
View full analysis
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:272
Finding

CI Example Executes an Unpinned Remote Shell Payload

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (15)

External Script Fetching

High
Category
Supply Chain
Confidence
98% confidence
Finding

curl -Ls https://get.maestro.mobile.dev | bash downloads a remote script and executes it immediately with no integrity verification, version pinning, or review step. If the endpoint, transit path, or hosting account is compromised, the agent or user system can execute arbitrary code, and this skill's shell-oriented context makes that especially dangerous.

Content

Scanner excerpt · SKILL.md (reported line 28)May include surrounding context.

md
| Java 17+ | `java -version` | `brew install --cask temurin@17` (macOS), `sudo apt install openjdk-17-jdk` (Linux), `winget install Microsoft.OpenJDK.17` (Windows) — or run `scripts/setup.sh` which auto-installs |
| Android SDK | `echo $ANDROID_HOME` | Android Studio |
| AVD (emulator image) | `emulator -list-avds` | Android Studio → AVD Manager |
| Maestro CLI | `maestro --version` | `curl -Ls https://get.maestro.mobile.dev \| bash` — or run `scripts/setup.sh` |
| Built APK (Android) | Check `android/app/build/outputs/apk/` | `cd android && ./gradlew assembleDebug` |

### Environment setup

External Script Fetching

High
Category
Supply Chain
Confidence
98% confidence
Finding

The GitHub Actions example repeats the same remote-script execution pattern in CI, where compromise can expose repository secrets, tamper with artifacts, or modify test outputs. In CI this can be even more severe because the script runs unattended and may have access to credentials or trusted build context.

Content

Scanner excerpt · SKILL.md (reported line 272)May include surrounding context.

api-level: 34 script: | # Install Maestro + app, then run flows curl -Ls "https://get.maestro.mobile.dev" | bash adb install -r android/app/build/outputs/apk/debug/app-debug.apk $HOME/.maestro/bin/maestro test .maestro/suites/smoke.yaml

text

Chaining Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

The | bash chaining pattern removes the inspection boundary between fetching remote content and executing it. This is a classic command-chaining abuse pattern because any malicious or unexpected response body becomes live shell input immediately, compounding the CI risk already present in this section.

Content

Scanner excerpt · SKILL.md (reported line 272)May include surrounding context.

api-level: 34 script: | # Install Maestro + app, then run flows curl -Ls "https://get.maestro.mobile.dev" | bash adb install -r android/app/build/outputs/apk/debug/app-debug.apk $HOME/.maestro/bin/maestro test .maestro/suites/smoke.yaml

text

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/setup.sh (reported line 130)May include surrounding context.

sh
;;
      Linux)
        if command -v apt-get &>/dev/null; then
            sudo apt-get update && sudo apt-get install -y openjdk-17-jdk
            export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
        elif command -v dnf &>/dev/null; then
            sudo dnf install -y java-17-openjdk-devel

External Script Fetching

High
Category
Supply Chain
Confidence
98% confidence
Finding

Piping a remote script directly into bash executes whatever content is returned by the remote endpoint without verification, making the local machine fully trust the network path and remote server. In a setup script that may be run by developers with broad local access, compromise of the download source, TLS interception, or unexpected upstream changes could lead to arbitrary code execution.

Content

Scanner excerpt · scripts/setup.sh (reported line 154)May include surrounding context.

sh
if [ -n "${JAVA_HOME:-}" ]; then
        export PATH="$JAVA_HOME/bin:$PATH"
    fi
    curl -Ls "https://get.maestro.mobile.dev" | bash
    echo ""
    export PATH="$HOME/.maestro/bin:$PATH"
    echo "✅ Maestro installed to ~/.maestro/bin"

Chaining Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

Using '| bash' turns a network fetch into immediate shell execution, eliminating any opportunity for inspection or integrity validation. In the context of a developer setup skill that installs tools and modifies PATH, this is especially dangerous because it can execute arbitrary attacker-controlled commands on the host with the user's privileges.

Content

Scanner excerpt · scripts/setup.sh (reported line 154)May include surrounding context.

sh
if [ -n "${JAVA_HOME:-}" ]; then
        export PATH="$JAVA_HOME/bin:$PATH"
    fi
    curl -Ls "https://get.maestro.mobile.dev" | bash
    echo ""
    export PATH="$HOME/.maestro/bin:$PATH"
    echo "✅ Maestro installed to ~/.maestro/bin"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill instructs the agent to run shell commands and bundled scripts, but it does not declare any explicit tool scope such as allowed-tools or permissions. That mismatch weakens policy enforcement and can let the skill invoke broader shell capabilities than a reviewer or orchestrator expects, especially because the content includes installation, emulator boot, adb, and script execution steps.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill metadata says to use this skill whenever the user mentions broad phrases like 'test my react native app' or 'test the expo app,' even if they do not name the skill. Because this skill performs shell-heavy setup and execution, broad auto-triggering increases the chance of unintended invocation and surprise execution of installation or emulator commands in contexts where the user did not explicitly consent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The 'When to use this skill' section repeats broad invocation rules that can cause the agent to select this shell-capable skill based on generic testing language. In context, that is riskier because the skill includes package installation, local script execution, adb port mapping, and emulator control, so accidental routing can quickly escalate from advice to system changes.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
90% confidence
Finding

The skill recommends sudo apt install openjdk-17-jdk, which normalizes privileged package installation from within the skill flow. While common for setup docs, invoking or encouraging root-level actions from an agent increases the blast radius of mistakes, makes social engineering easier, and can combine dangerously with any untrusted package source or script execution path.

Content

Scanner excerpt · SKILL.md (reported line 25)May include surrounding context.

md
| Requirement | How to check | Install |
|---|---|---|
| Java 17+ | `java -version` | `brew install --cask temurin@17` (macOS), `sudo apt install openjdk-17-jdk` (Linux), `winget install Microsoft.OpenJDK.17` (Windows) — or run `scripts/setup.sh` which auto-installs |
| Android SDK | `echo $ANDROID_HOME` | Android Studio |
| AVD (emulator image) | `emulator -list-avds` | Android Studio → AVD Manager |
| Maestro CLI | `maestro --version` | `curl -Ls https://get.maestro.mobile.dev \| bash` — or run `scripts/setup.sh` |

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/setup.sh (reported line 130)May include surrounding context.

sh
;;
      Linux)
        if command -v apt-get &>/dev/null; then
            sudo apt-get update && sudo apt-get install -y openjdk-17-jdk
            export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
        elif command -v dnf &>/dev/null; then
            sudo dnf install -y java-17-openjdk-devel

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/setup.sh (reported line 133)May include surrounding context.

sh
;;
      Linux)
        if command -v apt-get &>/dev/null; then
            sudo apt-get update && sudo apt-get install -y openjdk-17-jdk
            export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
        elif command -v dnf &>/dev/null; then
            sudo dnf install -y java-17-openjdk-devel

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · scripts/setup.sh (reported line 160)May include surrounding context.

sh
echo "✅ Maestro installed to ~/.maestro/bin"
fi

# --- Write env helper ---
echo ""
echo "--- Writing environment helper ---"
ENV_HELPER="$HOME/.maestro/activate.sh"