Back to skill

Security audit

android-agent

Security checks for vulnerabilities and agentic risk

Overview

The skill’s Android control purpose is coherent, but it grants broad phone-control authority and has under-disclosed risks around sensitive actions and PIN handling.

Install only if you intend to let an AI operate a dedicated Android device you own. Avoid using a primary phone or apps with banking, 2FA, private messages, medical data, or saved personal accounts. Do not set ANDROID_PIN until PIN redaction is fixed, and prefer manual unlock plus explicit review before purchases, messages, rides, or account changes.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run-task.py:30
Finding

Android PIN May Be Exposed Through ADB Error Messages and Process Arguments

Content
View full analysis
str: """Run an ADB command and return stdout.""" cmd = ["adb"] if serial: cmd += ["-s", serial] cmd += list(args) result = subprocess.run(cmd, capture_output=True, text=True, timeout=30) if check and result.returncode != 0: raise RuntimeError(f"adb {' '.join(args)} failed: {result.stderr.strip()}") return result.stdout.strip() ``` ```python pin = os.environ.get("ANDROID_PIN") if not pin: print("🔒 Phone is locked but ANDROID_PIN not set — skipping unlock") print(" Set ANDROID_PIN environment variable or unlock manually") return print("🔑 Unlocking phone...") # Swipe up to reveal PIN pad adb(serial, "shell", "input", "swipe", "540", "1800", "540", "800", "300") time.sleep(1) # Type the PIN — works on most devices adb(serial, "shell", "input", "text", pin) ``` ```python except Exception as e: print() print("=" * 60) print(f"❌ Task failed: {e}") print("=" * 60) if args.verbose: import traceback traceback.print_exc() sys.exit(1) ``` ### Technical Analysis The phone PIN is passed directly to ADB as a command-line argument: ```text adb -s shell input text ``` Command-line arguments may be visible to other local processes through process-inspection facilities while the command is running. More importantly, the shared `adb()` helper constructs an exception containing all ADB arguments when the command fails. Because the PIN is one of those arguments, an unlock failure can produce an exception containing the plaintext PIN. The top-level exception handler prints that exception. If output is collected ...[truncated 1799 chars]
Remediation
View remediation
str: cmd = ["adb"] if serial: cmd += ["-s", serial] cmd += list(args) result = subprocess.run(cmd, capture_output=True, text=True, timeout=30) if check and result.returncode != 0: operation = "" if sensitive else " ".join(args) raise RuntimeError( f"ADB operation failed: {operation}; " f"error={result.stderr.strip()}" ) return result.stdout.strip() ``` The PIN-entry call should then set `sensitive=True`, while the top-level handler should continue to print only sanitized exceptions. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Security-Sensitive Dependencies Are Installed Without Exact Version or Hash Pinning

Content
View full analysis
=0.4.20 openai>=1.0.0 ``` The metadata declares different minimum requirements: ```json "requirements": { "bins": ["adb", "python3"], "python": ["droidrun>=0.4.26", "openai>=1.0.0"] } ``` ### Technical Analysis Both Python dependencies use minimum-version constraints without upper bounds, exact versions, or package hashes. Every future release satisfying these constraints is eligible for installation without having been reviewed with this project. This is particularly security-sensitive because DroidRun and the OpenAI client execute in a process that has access to: - `OPENAI_API_KEY`; - Android device access through ADB; - screenshots and screen-derived information; - user-supplied task descriptions; - the host user’s environment and filesystem permissions. The minimum DroidRun version is also inconsistent: `requirements.txt` permits version `0.4.20`, while `skill.json` requires at least `0.4.26`. Installation behavior can therefore vary depending on which dependency declaration is consumed. No evidence was found that the currently named packages are malicious. The vulnerability is the project’s acceptance of unreviewed future versions and its lack of reproducible, integrity-verified dependency resolution. ### Attack Path 1. A user installs the project with `pip install -r requirements.txt` or through tooling that reads `skill.json`. 2. The package resolver selects any available versions satisfying the broad `>=` constraints. 3. A future compromised, malicious, or security-regressed package release remains eligible for automatic selection. 4. Package installation or import executes code with the privileges of the host user. 5. The dependency can access environment variables, including `OP ...[truncated 967 chars]
Remediation
View remediation
=` constraints. 2. Generate and commit a lock file containing all transitive dependency versions. 3. Use package hashes, such as pip’s `--require-hashes` mode, to verify artifact integrity. 4. Synchronize `requirements.txt` and `skill.json` so all installation paths enforce the same versions. 5. Upgrade dependencies through an explicit review process rather than automatically accepting future releases. 6. Run dependency vulnerability and provenance checks in CI. 7. Prefer an isolated virtual environment with only the permissions required for the Skill. 8. Where practical, separate the process holding `OPENAI_API_KEY` from components that directly control ADB devices. For example, the requirements should follow an exact, reviewed form: ```text droidrun== \ --hash=sha256: openai== \ --hash=sha256: ``` All transitive dependencies should also be locked and hash-verified. The actual versions and hashes must be selected from artifacts independently reviewed and tested by the project maintainers. ]]>
Vulnerability Patterns
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (10)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The examples encourage execution of privacy-sensitive and potentially transactional actions such as reading messages and emails, checking a bank balance, ordering rides or food, and interacting with shopping carts, without any warning about consent, confirmation, or data sensitivity. In an agent skill context, copy-pastable examples strongly shape user behavior and can normalize unsafe automation of actions involving personal data or financial consequences.

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 · SKILL.md (reported line 130)May include surrounding context.

md
echo -e "${RED}❌ ADB not found.${NC}"
    echo "Install it:"
    echo "  macOS:  brew install android-platform-tools"
    echo "  Ubuntu: sudo apt install android-tools-adb"
    exit 1
fi

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/connect.sh (reported line 21)May include surrounding context.

sh
echo -e "${RED}❌ ADB not found.${NC}"
    echo "Install it:"
    echo "  macOS:  brew install android-platform-tools"
    echo "  Ubuntu: sudo apt install android-tools-adb"
    exit 1
fi

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run-task.py (reported line 37)May include surrounding context.

python
if serial:
        cmd += ["-s", serial]
    cmd += list(args)
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
    if check and result.returncode != 0:
        raise RuntimeError(f"adb {' '.join(args)} failed: {result.stderr.strip()}")
    return result.stdout.strip()

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run-task.py (reported line 156)May include surrounding context.

python
cmd += ["-s", serial]
    cmd += ["exec-out", "screencap", "-p"]
    with open(out_path, "wb") as f:
        result = subprocess.run(cmd, stdout=f, stderr=subprocess.PIPE, timeout=30)
    if result.returncode != 0:
        raise RuntimeError(f"screencap failed: {result.stderr.decode(errors='ignore').strip()}")
    size = os.path.getsize(out_path)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest description advertises broad AI-powered control of a connected Android phone without defining scope, user consent boundaries, or trigger constraints. Because phone control can include launching apps, reading on-screen content, sending inputs, and affecting accounts or communications, this ambiguity increases the risk of accidental or overbroad activation by an agent or user.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest states that the skill can control a plugged-in phone and lists environment variables such as ANDROID_PIN and ANDROID_SERIAL, but it does not warn users about the sensitivity of device control or credential-like configuration. This can mislead users into enabling a skill with powerful capabilities over a personal device without understanding risks such as unintended actions, data exposure, or account compromise on the connected phone.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The examples hard-code India-specific services and currency references such as PhonePe, Swiggy, Instamart, and '2000 rupees', which steers usage toward a particular locale without offering alternatives or noting that the examples are region-specific. This can conflict with language/locale policy expectations when a skill is presented as generally applicable.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified with a lower bound only, which allows installation of any newer version, including releases with breaking changes or compromised upstream packages. This weakens supply-chain integrity and can cause the skill to pull in unexpected code during installation or deployment.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
droidrun>=0.4.20
openai>=1.0.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is not pinned to a specific version, so environment setup may resolve to different package versions over time, including potentially vulnerable or malicious upstream releases. In a skill context that relies on external SDKs, this increases supply-chain risk and reduces reproducibility.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
droidrun>=0.4.20
openai>=1.0.0

Static analysis

No suspicious patterns detected.