Back to skill

Security audit

MuPiBox Media DB

Security checks for vulnerabilities and agentic risk

Overview

The skill coherently manages a MuPiBox media database, with disclosed local backups and API mutations, but users should be careful with its plaintext HTTP default.

Install only if you intend to let the agent modify your MuPiBox media database. Use a trusted or isolated network for the default HTTP endpoint, prefer an HTTPS base URL if your MuPiBox setup supports it, and review backup files in ~/.mupibox-db-backups if media metadata is sensitive.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/mupibox_media_manager.py:22
Finding

Plaintext HTTP Transport for Media Database Operations

Content
View full analysis

Vulnerability Details

File Location: scripts/mupibox_media_manager.py, lines 22–46; documented in SKILL.md, lines 12 and 22
Vulnerability Type: Plaintext transmission of database contents and mutation requests
Risk Level: Medium

Vulnerable Code

python
DEFAULT_BASE_URL = "http://mupibox:8200"
DEFAULT_BACKUP_DIR = Path.home() / ".mupibox-db-backups"


@dataclass
class Client:
    base_url: str

    def _get(self, path: str) -> Any:
        req = request.Request(self.base_url.rstrip("/") + path, method="GET")
        with request.urlopen(req, timeout=20) as resp:
            body = resp.read().decode("utf-8")
            return json.loads(body)

    def _post(self, path: str, payload: dict[str, Any]) -> str:
        data = json.dumps(payload).encode("utf-8")
        req = request.Request(
            self.base_url.rstrip("/") + path,
            method="POST",
            data=data,
            headers={"Content-Type": "application/json"},
        )
        with request.urlopen(req, timeout=20) as resp:
            return resp.read().decode("utf-8", errors="replace")

The documented default is also plaintext:

markdown
- Access to a running MuPiBox backend instance (MuPiBox host is often `http://mupibox/`, API for this script defaults to `http://mupibox:8200`; override with `--base-url`)

Technical Analysis

The client defaults to an http:// backend and transmits database reads and mutation requests without transport encryption. The requests also contain no client-supplied authorization header or other request authentication mechanism.

An attacker with a network-adjacent position, control over DNS or local hostname resolution, or access to a compromised network device could observe the database returned by /api/data. The attacker could also intercept, redirect, replay, or modify requests sent to /api/add, /api/edit, and /api/delete.

Because HTT ...[truncated 1818 chars]

Remediation
View remediation

Remediation Suggestions

  1. Change the default endpoint to an HTTPS URL:

    python
    DEFAULT_BASE_URL = "https://mupibox:8200"
    
  2. Reject plaintext HTTP by default. If compatibility with isolated legacy deployments is required, permit it only through an explicit option such as --allow-insecure-http and display a prominent warning.

  3. Configure the MuPiBox backend with a certificate trusted by the client. Preserve Python's default certificate and hostname verification rather than introducing an unverified TLS context.

  4. Add backend authentication, such as a narrowly scoped bearer token, and avoid placing credentials in command-line arguments where they may appear in process listings. Prefer environment variables, protected configuration files, or an operating-system credential store.

  5. Add request integrity or anti-replay protections where supported, particularly for destructive endpoints. Examples include short-lived authenticated requests, nonces, or server-side authorization controls.

  6. Restrict access to the backend using host firewall rules and network segmentation. The API should only accept connections from authorized management hosts.

  7. Document the security assumptions for local-network deployments and clearly state that plaintext HTTP does not protect against interception, spoofing, or request modification.

  8. Add tests confirming that insecure URL schemes are refused unless explicit insecure mode is enabled and that HTTPS certificate-validation failures stop all mutations.

Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (3)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises network, file read, and file write capabilities through its documented workflow and bundled script, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates an authorization and review gap: an agent or reviewer cannot easily determine or constrain what resources the skill may access, increasing the risk of unintended file access, unauthorized network calls, or misuse of the local backup/restore path.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script silently writes full database backups to a predictable location in the user's home directory before mutations. If the media database contains sensitive metadata, users may unknowingly leave additional local copies behind, increasing exposure through local compromise, shared accounts, backup tooling, or accidental disclosure.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/mupibox_media_manager.py (reported line 103)May include surrounding context.

python
item: dict[str, Any] = {"type": args.type, "category": args.category}

    for key in ["artist", "title", "query", "id", "playlistid", "artistid", "showid", "audiobookid", "cover"]:
        val = getattr(args, key, None)
        if val is not None:
            item[key] = val

Static analysis

No suspicious patterns detected.