Back to skill

Security audit

Plex Server

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real Plex/Shield manager, but it handles a full-access Plex token and optional ADB device control in risky, under-scoped ways.

Install only if you are comfortable granting this skill full Plex account/server access and possible ADB control of a Shield device. Avoid using it on shared machines or untrusted networks, consider rotating any token used in command examples, and review or patch token handling, HTTPS use, ADB enablement, and confirmation for reboot/restart before relying on it.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/shield-cli.js:50
Finding

Plex administrator token exposed through command-line arguments and request URLs

Content
View full analysis
node scripts/shield-cli.js setup ``` Discovery similarly places the token directly in curl's argument list: ```javascript const discoverResult = spawnSync('curl', [ '-s', `https://plex.tv/api/resources?X-Plex-Token=${token}` ], { encoding: 'utf8', timeout: 15000 }); ``` ### Technical Analysis The Plex token is described by the project as a universal key granting full access to the account and associated servers. Nevertheless, the Skill accepts it as a command-line argument and subsequently embeds it in URLs passed to a child `curl` process. This creates two credential-disclosure channels: 1. The initial setup or discovery command can remain in shell history, terminal logs, automation logs, or command auditing records. 2. While `curl` is running, the complete URL—including `X-Plex-Token`—can be exposed through process inspection facilities such as `ps`, `/proc`, monitoring agents, or process telemetry available to other authorized local users and services. Using `spawnSync` ...[truncated 1386 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/shield-cli.js:222
Finding

Full-access Plex token transmitted over unauthenticated plaintext HTTP

Content
View full analysis
]*address="([^"]+)"[^>]*port="32400"[^>]*local="1"[^>]*>/g)]; let localUrl; if (allLocalConns[serverIndex]) { localUrl = `http://${allLocalConns[serverIndex][1]}:32400`; config.shield_ip = allLocalConns[serverIndex][1]; } else { // Fallback: any local connection const anyLocal = [...xml.matchAll(/]*address="([^"]+)"[^>]*port="([^"]+)"[^>]*local="1"[^>]*>/g)]; if (anyLocal[serverIndex]) { localUrl = `http://${anyLocal[serverIndex][1]}:${anyLocal[serverIndex][2]}`; config.shield_ip = anyLocal[serverIndex][1]; } else if (anyLocal[0]) { localUrl = `http://${anyLocal[0][1]}:${anyLocal[0][2]}`; config.shield_ip = anyLocal[0][1]; } } ``` Every Plex API call then appends the full token to that endpoint: ```javascript function plexApi(endpoint, method = 'GET', rawXml = false) { const config = loadConfig(); const url = `${config.plex_url}${endpoint}${endpoint.includes('?') ? '&' : '?'}X-Plex-Token=${config.plex_token}`; const args = ['-s', '-X', method, url]; if (!rawXml) { args.push('-H', 'Accept: application/json'); } const result = spawnSync('curl', args, { encoding: 'utf8', timeout: 15000 }); return { stdout: result.stdout?.trim() || '', stderr: result.stderr?.trim() || '', status: result.status }; } ``` ### Technical Analysis Auto-discovery constructs the selected server endpoint with the `http://` scheme rather than preserving and validating a secure connection URI supplied by Plex. The API helper then places the full-access Plex token in every request URL. Because HTTP provides neither encryption nor ...[truncated 1720 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/shield-cli.js:222
Finding

Plex-only setup unintentionally enables ADB probing and device reconnaissance

Content
View full analysis
]*address="([^"]+)"[^>]*port="32400"[^>]*local="1"[^>]*>/g)]; let localUrl; if (allLocalConns[serverIndex]) { localUrl = `http://${allLocalConns[serverIndex][1]}:32400`; config.shield_ip = allLocalConns[serverIndex][1]; } else { // Fallback: any local connection const anyLocal = [...xml.matchAll(/]*address="([^"]+)"[^>]*port="([^"]+)"[^>]*local="1"[^>]*>/g)]; if (anyLocal[serverIndex]) { localUrl = `http://${anyLocal[serverIndex][1]}:${anyLocal[serverIndex][2]}`; config.shield_ip = anyLocal[serverIndex][1]; } else if (anyLocal[0]) { localUrl = `http://${anyLocal[0][1]}:${anyLocal[0][2]}`; config.shield_ip = anyLocal[0].address; } } config.plex_url = localUrl; ``` The `health` command then automatically attempts ADB access and executes shell diagnostics: ```javascript case 'health': { const output = {}; // ADB health const conn = adbConnect(); output.adb_connected = conn.connected; output.adb_message = conn.message; if (conn.connected) { const uptime = adbShell('uptime'); output.uptime = uptime.stdout; const mem = adbShell('dumpsys meminfo | grep "Used RAM"'); output.memory = mem.stdout; const disk = adbShell('df -h /data /sdcard 2>/dev/null'); output.disk = disk.stdout; const plexProc = adbShell('ps -A | grep -i plex'); output.plex_process = plexProc.stdout || 'NOT RUNNING'; const battery = adbShell('dumpsys battery | grep -E "level|temperature|status"'); output.battery = battery.stdout; } ``` ### Technical Analysis The d ...[truncated 2643 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (13)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/shield-cli.js discover <plex_token>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/shield-cli.js discover <plex_token>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/shield-cli.js discover <plex_token>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/shield-cli.js discover <plex_token>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/shield-cli.js discover <plex_token>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/shield-cli.js discover <plex_token>

Lp1

High
Category
MCP Least Privilege
Confidence
94% confidence
Finding

This CLI invokes external system commands via child_process.spawnSync for both adb and curl, giving the skill shell-like execution capability that can affect the host and network. In this context, the tool can connect to devices, reboot a Shield, stop/start Plex, and make authenticated network calls; if the surrounding permission model does not explicitly declare and gate shell/process execution, the skill has more operational power than expected and becomes dangerous if exposed to untrusted inputs or broader automation.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · README.md (reported line 41)May include surrounding context.

md
3. Refresh the page and look for any request to `plex.tv`
4. Check the request headers or query parameters for `X-Plex-Token`

> ⚠️ **Important:** Your Plex token grants full access to your account and all servers. Treat it like a password. The skill stores it in `~/.openclaw/shield/config.json` with `chmod 600` permissions.

### 2. Discover your servers

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

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

md
3. Refresh the page and look for any request to `plex.tv`
4. Check the request headers or query parameters for `X-Plex-Token`

> ⚠️ **Important:** Your Plex token grants full access to your account and all servers. Treat it like a password. The skill stores it in `~/.openclaw/shield/config.json` with `chmod 600` permissions.

### 2. Discover your servers

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

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

md
3. Refresh the page and look for any request to `plex.tv`
4. Check the request headers or query parameters for `X-Plex-Token`

> ⚠️ **Important:** Your Plex token grants full access to your account and all servers. Treat it like a password. The skill stores it in `~/.openclaw/shield/config.json` with `chmod 600` permissions.

### 2. Discover your servers

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · README.md (reported line 175)May include surrounding context.

}

text

The file is created with `chmod 600` (owner read/write only).

## Requirements

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill exposes a reboot ADB command for a device-management workflow but provides no warning, confirmation, or usage guardrails. Because the skill is user-invocable and allowed to run exec, an agent could trigger an immediate device reboot that disrupts active playback or other services, especially if invoked accidentally or with ambiguous user intent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The format command emits user-facing text such as nessun risultato trovato, Film, Serie TV, and Sottotitoli entirely in Italian. This imposes a specific language on users without any visible opt-in or locale selection, which matches the policy category for language/locale violations.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/shield-cli.js:63