Back to skill

Security audit

Apple TV

Security checks for vulnerabilities and agentic risk

Overview

This Apple TV skill appears purpose-aligned, but it needs review because broad triggers and under-disclosed credential handling could cause unintended device control or expose pairing credentials locally.

Install only if you are comfortable giving the skill control over a paired Apple TV. Before use, narrow or remove broad triggers like "TV", consider requiring confirmation for power and app-launch commands, pin the pyatv version, and protect or rotate Apple TV pairing credentials if local process command lines may be logged or monitored.

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)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:14
Finding
Unpinned Third-Party Dependency Installation## Vulnerability Details **File Location**: `SKILL.md`, line 14 **Vulnerability Type**: Unpinned dependency and unsafe supply-chain resolution **Risk Level**: Medium ### Vulnerable Code ```bash pipx install pyatv --python python3.11 ``` ### Technical Analysis The documented installation command installs the latest version of `pyatv` and its transitive dependencies available from the configured package index. It does not specify an audited version, use a lock file, or validate package integrity with cryptographic hashes. Consequently, the code installed by users can change after this Skill has been reviewed. A compromised package release or transitive dependency could introduce arbitrary build-time or runtime behavior. An incompatible future release could also alter command semantics or security behavior. This finding does not establish that the current `pyatv` package is malicious. The weakness is that the installation procedure does not constrain users to a known, reviewed dependency set. ### Attack Path 1. An attacker compromises the publishing account, distribution channel, or a transitive dependency used by `pyatv`. 2. The attacker publishes a modified release containing malicious installation or runtime code. 3. A user follows the Skill documentation and runs the unpinned `pipx install pyatv` command. 4. The package resolver downloads the compromised release because no exact version or integrity hash is required. 5. Package-controlled code executes during installation or when the Apple TV utility is subsequently invoked. ### Impact Assessment Exploitation could execute code with the privileges of the user running `pipx`. This may expose files accessible to that account, including the Apple TV configuration and pairing credentials, and may permit modification of user-owned data or installation of user-level persistence. It does not inherently grant administrative privileges unless installation is performed by a ...[truncated 72 chars]
Remediation
## Remediation Suggestions - Pin `pyatv` to an exact version that has been reviewed and tested, for example: ```bash pipx install 'pyatv==REVIEWED_VERSION' --python python3.11 ``` - Maintain a lock file containing exact versions of all transitive dependencies. - Where the installation workflow supports it, require cryptographic hashes for downloaded distributions. - Document the expected package index and prevent fallback to untrusted or unexpected package sources. - Establish a dependency-update process that includes vulnerability scanning, changelog review, and functional testing before changing the pinned version.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/appletv.py:68
Finding
Apple TV Pairing Credentials Exposed in Child Process Arguments## Vulnerability Details **File Location**: `scripts/appletv.py`, lines 68-74 **Vulnerability Type**: Sensitive credentials passed through command-line arguments **Risk Level**: Medium ### Vulnerable Code ```python cmd = [str(ATVREMOTE), "--id", config["id"]] creds = config.get("credentials", {}) if creds.get("companion"): cmd.extend(["--companion-credentials", creds["companion"]]) if creds.get("airplay"): cmd.extend(["--airplay-credentials", creds["airplay"]]) ``` The resulting command is executed at lines 78-79: ```python import subprocess result = subprocess.run(cmd, capture_output=True, text=True) ``` ### Technical Analysis The script reads Companion and AirPlay pairing credentials from configuration and places them directly in the argument vector of the `atvremote` child process. Although the script correctly uses an argument list rather than a shell command and therefore does not introduce shell injection at this location, command-line arguments are not an appropriate secret-transport mechanism. Depending on operating-system process visibility, local access controls, diagnostic tooling, audit configuration, crash reporting, and endpoint telemetry, another local principal or monitoring service may be able to inspect or retain the child process command line. The credentials may remain in logs or telemetry after the process exits. Exploitability depends on local process-inspection permissions and system configuration. The source nevertheless unnecessarily places long-lived device credentials in an observable process metadata channel. ### Attack Path 1. A user configures valid Companion or AirPlay credentials in `appletv.json`. 2. The user invokes a command such as `status`, `play`, or `app`. 3. `run_atvremote` appends the plaintext credentials to the child process argument vector. 4. A local observer, process-monitoring service, audit collector, or diagnostic tool captures the `atvremote ...[truncated 931 chars]
Remediation
## Remediation Suggestions - Prefer using the `pyatv` Python API directly so credentials remain in process memory and are not copied into a child process argument vector. - If supported by `atvremote`, provide credentials through a protected configuration file, operating-system credential store, inherited file descriptor, or other mechanism that does not expose them in `argv`. - Create credential files with restrictive permissions such as `0600`, verify ownership before reading them, and reject files writable by unrelated users. - Avoid printing, logging, or including credentials in exceptions and diagnostic output. - Document the local process-argument exposure if the underlying CLI offers no secure credential-input mechanism. - Advise users to rotate or re-pair credentials if process-command telemetry may already have captured them.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill invokes shell commands such as `scripts/appletv.py` and `atvremote` but does not declare any tool scope or allowed-tools boundary. That creates an authorization gap where an agent may execute shell-capable actions without explicit least-privilege constraints, increasing the chance of unintended command execution or abuse if the skill is triggered unexpectedly.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrase `TV` is extremely broad and likely to match ordinary conversation unrelated to this skill. Because the skill performs real-world control actions such as power, playback, and app launching via shell-backed commands, accidental invocation could cause unintended device actions and expand opportunities for prompt/command routing mistakes.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd.extend(args)
    
    import subprocess
    result = subprocess.run(cmd, capture_output=True, text=True)
    return result.stdout, result.stderr, result.returncode

def cmd_status():
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""Scan for Apple TVs."""
    import subprocess
    print("🔍 Scanning for Apple TVs...\n")
    result = subprocess.run([str(ATVREMOTE), "scan"], capture_output=False)
    return result.returncode

def main():
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.