Back to skill

Security audit

Wjs Burning Subtitles

Security checks for vulnerabilities and agentic risk

Overview

This skill does a real subtitle-rendering job, but it can automatically download and run an unverified third-party FFmpeg binary from a shared temporary path.

Review before installing. The subtitle workflow itself is understandable, but avoid the automatic FFmpeg fallback unless you trust evermeet.cx and the local environment. Prefer a trusted package-manager or administrator-installed ffmpeg with libass, or require the skill to pin and verify a known binary and store it in a private user-owned cache before execution.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/render.py:52
Finding

Unsigned Third-Party FFmpeg Binary Is Automatically Downloaded and Executed

Content
View full analysis
bool: r = subprocess.run([ff, "-filters"], capture_output=True, text=True) return any(" subtitles " in line for line in r.stdout.splitlines()) def fetch_static_ffmpeg() -> str: print("→ downloading libass-enabled ffmpeg from evermeet.cx…", file=sys.stderr) STATIC_FF.parent.mkdir(parents=True, exist_ok=True) z = "/tmp/ff_evermeet.zip" urllib.request.urlretrieve(EVERMEET_URL, z) with zipfile.ZipFile(z) as zf: zf.extractall(STATIC_FF.parent) os.chmod(str(STATIC_FF), 0o755) if not libass_ok(str(STATIC_FF)): sys.exit("static ffmpeg also lacks libass — abort") return str(STATIC_FF) ``` The returned program is subsequently used as the executable in an external process: ```python ff = pick_ffmpeg(need_libass=burn) # ... cmd = [ff, "-hide_banner", "-y", *inputs] # ... r = subprocess.run(cmd) sys.exit(r.returncode) ``` The documentation recommends the equivalent behavior: ```bash curl -fsSL -o /tmp/ff.zip https://evermeet.cx/ffmpeg/getrelease/zip unzip -o /tmp/ff.zip -d /tmp/ff_bin >/dev/null FF=/tmp/ff_bin/ffmpeg $FF -version | grep -oE -- "--enable-(libass|libfreetype)" ``` ### Technical Analysis When subtitle burn-in requires libass and the system FFmpeg does not provide it, the skill downloads a mutable ZIP archive from a third-party endpoint. It does not pin a release version, verify a cryptographic checksum, validate a publisher signature, or otherwise establish the provenance of the executable before running it. HTTPS provides transport protecti ...[truncated 1813 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/render.py:53
Finding

Predictable Shared Temporary FFmpeg Path Permits Local Binary Planting

Content
View full analysis
str: print("→ downloading libass-enabled ffmpeg from evermeet.cx…", file=sys.stderr) STATIC_FF.parent.mkdir(parents=True, exist_ok=True) z = "/tmp/ff_evermeet.zip" urllib.request.urlretrieve(EVERMEET_URL, z) with zipfile.ZipFile(z) as zf: zf.extractall(STATIC_FF.parent) os.chmod(str(STATIC_FF), 0o755) if not libass_ok(str(STATIC_FF)): sys.exit("static ffmpeg also lacks libass — abort") return str(STATIC_FF) ``` ```python def pick_ffmpeg(need_libass: bool) -> str: if STATIC_FF.exists(): return str(STATIC_FF) sys_ff = shutil.which("ffmpeg") or "ffmpeg" if not need_libass: return sys_ff if libass_ok(sys_ff): return sys_ff return fetch_static_ffmpeg() ``` The selected path is later executed: ```python ff = pick_ffmpeg(need_libass=burn) # ... cmd = [ff, "-hide_banner", "-y", *inputs] # ... r = subprocess.run(cmd) ``` ### Technical Analysis The executable is cached under the fixed, globally predictable path `/tmp/ff_bin/ffmpeg`. `pick_ffmpeg()` trusts any existing filesystem object at that path and returns it without checking: - File ownership - Directory ownership and permissions - Whether the path is a regular file - Whether the path or its parent contains symbolic links - Expected cryptographic digest - Publisher signature - Previously recorded provenance - Even whether the cached program still supports libass A local attacker can prepare `/tmp/ff_bin` before the first legitimate invocation and place an attacker-controlled executable at the expected path. Because `/tmp` is conventionally shared, predictability c ...[truncated 1529 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/render.py:61
Finding

Fixed Shared Temporary Paths Create Archive and File-Operation Race Conditions

Content
View full analysis
str: print("→ downloading libass-enabled ffmpeg from evermeet.cx…", file=sys.stderr) STATIC_FF.parent.mkdir(parents=True, exist_ok=True) z = "/tmp/ff_evermeet.zip" urllib.request.urlretrieve(EVERMEET_URL, z) with zipfile.ZipFile(z) as zf: zf.extractall(STATIC_FF.parent) os.chmod(str(STATIC_FF), 0o755) if not libass_ok(str(STATIC_FF)): sys.exit("static ffmpeg also lacks libass — abort") return str(STATIC_FF) ``` The relevant fixed paths are: ```python STATIC_FF = Path("/tmp/ff_bin/ffmpeg") z = "/tmp/ff_evermeet.zip" ``` ### Technical Analysis The download archive and extraction destination use fixed names under the shared `/tmp` namespace. The code does not create a private temporary directory, atomically reserve the archive path, validate ownership of pre-existing path components, or reject symbolic-link and replacement races before writing, extracting, changing permissions, and executing the result. This creates time-of-check/time-of-use opportunities in environments where another local principal can prepare or interfere with these predictable paths. For example, a maliciously prepared directory structure or a path swapped during processing may redirect or alter the files the script expects to download, extract, chmod, or execute. The use of `extractall()` also accepts every archive member without enforcing an explicit allowlist for the one expected executable. Although Python's ZIP extraction performs some filename normalization, the project does not independently validate that each extracted member is required, that its resolved destination remains in a newly created private directory, or that links and unexpected file types are rejected. ### Attack Path 1. A local ...[truncated 1295 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill explicitly uses shell commands and network access, including downloading binaries and invoking ffmpeg, but declares no tool scope or permissions metadata. This creates an authorization gap where an agent may run higher-risk capabilities without clear restriction or user awareness, increasing the chance of unsafe execution in environments that rely on manifest-level scoping.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill directs the agent to download and execute a third-party ffmpeg binary from evermeet.cx as an automatic fallback, without a prominent safety warning, integrity verification, or a required approval step. Running externally fetched executables is a major supply-chain risk: if the source, transport, or local extraction path is compromised, arbitrary code could execute on the host.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
98% confidence
Finding

This command performs external network retrieval of a zip archive and then uses the extracted ffmpeg binary directly from /tmp. The dangerous part is not mere transmission but the immediate trust and execution of unverified remote code from a writable temporary directory, which substantially raises supply-chain and tampering risk.

Content

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

Fastest fix on macOS — drop in a static build, no system changes

bash
curl -fsSL -o /tmp/ff.zip https://evermeet.cx/ffmpeg/getrelease/zip
unzip -o /tmp/ff.zip -d /tmp/ff_bin >/dev/null
FF=/tmp/ff_bin/ffmpeg
$FF -version | grep -oE -- "--enable-(libass|libfreetype)"

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script is designed to automatically fetch and later execute a remote ffmpeg binary from evermeet.cx when libass is unavailable. That creates a supply-chain execution path: if the download source, transport, DNS, host, or extracted artifact is compromised, arbitrary code can run locally under the user's account.

Content

No source excerpt is available for this finding.

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/render.py (reported line 57)May include surrounding context.

python
def libass_ok(ff: str) -> bool:
    r = subprocess.run([ff, "-filters"], capture_output=True, text=True)
    return any(" subtitles " in line for line in r.stdout.splitlines())

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

This function retrieves a zip from the network, extracts it into /tmp, marks the ffmpeg binary executable, and then uses it. Executing newly downloaded binaries without strong integrity verification is dangerous, and using a predictable world-writable temporary path also increases the chance of local tampering, symlink abuse, or replacement by another local actor.

Content

No source excerpt is available for this finding.

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/render.py (reported line 168)May include surrounding context.

python
cmd += ["-c:a","aac","-b:a", f"{a.audio_bitrate}k", a.out]

    print(" ".join(cmd), file=sys.stderr)
    r = subprocess.run(cmd)
    sys.exit(r.returncode)

Static analysis

No suspicious patterns detected.