ffmpeg-skill@3.2.3
CAUTION· startup onlyPublisher claims: "Agent Skill that gives coding agents (Claude Code, Cursor, Codex) a local video editor: 42 FFmpeg tools with a machine-readable contract, contract-derived MCP server, FFmpeg capability detection, probe-first / verify-last workflow. Cut, join, silence remo" Observed in sandbox: no network, touches nothing outside the project, writes no memory.
Coverage
Startup only; authenticated tool behavior not tested.- Tested
- server startup over stdio (initialize sent) · every file read, file written and host contacted by what ran
- Not tested
- the tool list (the server exited before answering) · what the tools do when called with real credentials
Is [email protected] safe to install?
KillerSkills ran it in the KillerSkills honeypot sandbox (2 scenarios; startup only; authenticated tool behavior not tested) on 2026-11-08 and scored it 70/100 (Caution). It is not known to be malicious, but it has behaviour or code a security policy should decide on before install. Notable findings: Hidden zero-width characters detected; Hidden zero-width characters detected; Privileged sudo command. Summary: no network, touches nothing outside the project, writes no memory.
Behavior trace
Honeypot run · 20 s · 2 scenarios · 0 deviationsStatic findings
# (क्ष is ka + virama + ZWJ + ssa) and only becomes emoji glue *between two emoji bases*.Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent.and skin-tone modifiers kept together -- 👩💻 is one cluster, not three, and 1️⃣ starts at theFix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent.console.warn(' Ubuntu: sudo apt install ffmpeg');Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, **_runner.child_kwargs())Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.* npx ffmpeg-skill --all # all of the aboveFix: Pin versions and sources; vendor anything fetched at install time.proc = subprocess.run([exe, f":lang={FC_LANG[script]}:family={font_name}", "file"],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.* npx ffmpeg-skill --cursor # Cursor (~/.cursor/skills/ffmpeg-skill)Fix: Pin versions and sources; vendor anything fetched at install time.self.json = False # emit() prints a JSON document instead of the output pathFix: Remove the call, or declare the host in frontmatter and explain in the README what is sent and why.proc = subprocess.run([exe, "--format=%{file}\n%{family}\n", font_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding="utf-8", errors="replace", timeout=5)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.out = subprocess.run([found_exe("ffprobe"), "-version"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True, encoding="utf-8", errors="replace",Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out." Arch: sudo pacman -S ffmpeg"Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell." Debian/Ubuntu: sudo apt install ffmpeg\n"Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.* npx ffmpeg-skill --codex # Codex (~/.agents/skills/ffmpeg-skill)Fix: Pin versions and sources; vendor anything fetched at install time.out = subprocess.run([safe_which("sysctl") or "/usr/sbin/sysctl", "-n", "hw.optional.arm64"],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.* npx ffmpeg-skill --dir ./skills # custom parent directoryFix: Pin versions and sources; vendor anything fetched at install time.codecs, pixel format / color space, audio channels and sample rate.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.proc = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.proc = subprocess.run([exe, "--format", "%{lang}\n", fonts_dir],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.return "your distribution's package update, e.g. sudo apt install --only-upgrade ffmpeg or sudo dnf upgrade ffmpeg"Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell." Fedora: sudo dnf install ffmpeg\n"Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.out = subprocess.run([found_exe("ffprobe"), "-version"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True, encoding="utf-8", errors="replace",Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.return subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding="utf-8", errors="replace",Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.child = subprocess.Popen([sys.executable] + list(argv), stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding="utf-8", errors="replace")Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.a starter and never a tail on its own: `क्ष` (Hindi ka + virama + ZWJ + ssa) and `abcdef`Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent.# the JSON is looked for as <outdir>/audio.json: a host PARAKEET_OUTPUT_TEMPLATE would name it otherwiseFix: Remove the call, or declare the host in frontmatter and explain in the README what is sent and why.return "sudo apt update && sudo apt install --only-upgrade ffmpeg"Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.proc = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.help=f"kill an ffmpeg run past this many seconds, kind=timeout (default {DEFAULT_TIMEOUT:.0f}; 0 = no limit)")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.proc = subprocess.run([exe, "--format", "%{family[0]}", path], stdout=subprocess.PIPE,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.proc = subprocess.run([exe, "-hide_banner", flag], stdout=subprocess.PIPE,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.proc = subprocess.run(list(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=text, **text_kw, timeout=limit)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.proc = subprocess.run([exe, f":lang={fc_lang}", "file", "family"],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.* npx ffmpeg-skill # Claude CodeFix: Pin versions and sources; vendor anything fetched at install time.proc = subprocess.run([exe, f":family={family}", "file"], stdout=subprocess.PIPE,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.proc = subprocess.run([exe, "--format=%{family}\n", font_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding="utf-8", errors="replace", timeout=_DETECT_TIMEOUT)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.print(f"ffmpeg-skill {d['version']} (this installed copy; re-run `npx ffmpeg-skill` to refresh it -- copies are not updated automatically)")Fix: Pin versions and sources; vendor anything fetched at install time.proc = subprocess.run([exe, "-hide_banner", flag], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding="utf-8", errors="replace", timeout=_DETECT_TIMEOUT)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out."ar": "\u0627\u0644\u0639\u0631\u0628\u064a\u0629", "he": "\u05e2\u05d1\u05e8\u05d9\u05ea",Fix: Put hosts, commands and strings in plain source. Decoding at runtime looks identical to malware and costs points on its own."hi": "\u0939\u093f\u0928\u094d\u0926\u0940", "th": "\u0e44\u0e17\u0e22",Fix: Put hosts, commands and strings in plain source. Decoding at runtime looks identical to malware and costs points on its own.against the latest published release. A copy installed with `npx ffmpeg-skill` is not updatedFix: Pin versions and sources; vendor anything fetched at install time.proc = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out."replacement": "Python 3.10 or later; the npx installer skips an older interpreter and doctor reports it as unsupported (ok: false)"},Fix: Pin versions and sources; vendor anything fetched at install time.proc = subprocess.run([exe, "-version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding="utf-8", errors="replace", timeout=_DETECT_TIMEOUT)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.…act", deterministic=True), "render": dict(role="execution", inputs=["project.json (clips, transitions, captions, overlays, audio, loudness, export, check)", "media asset plus --template NAME (a shipped delivery template)"], outputs=["final…Fix: Remove the call, or declare the host in frontmatter and explain in the README what is sent and why."it": "Italiano", "nl": "Nederlands", "pl": "Polski", "ru": "\u0420\u0443\u0441\u0441\u043a\u0438\u0439",Fix: Put hosts, commands and strings in plain source. Decoding at runtime looks identical to malware and costs points on its own.Two warnings never refuse or change the command: `short_segments: [{index, path, duration}]`Fix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.die("give a project.json (or --init FILE, or --template NAME INPUT)")Fix: Remove the call, or declare the host in frontmatter and explain in the README what is sent and why.proc = subprocess.run([sys.executable, str(HERE / argv[0])] + argv[1:] + ["--json"], stdout=subprocess.PIPE, stderr=subprocess.PIPE,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.…tic=True), "batch": dict(role="execution", inputs=["folder of media", "batch.json recipe (steps or a render project)"], outputs=["one artifact per input file in the recipe's output_dir (none for a steps recipe, not a render project, in whi…Fix: Remove the call, or declare the host in frontmatter and explain in the README what is sent and why.# frontmatter fails to load (GitHub's renderer reported it; npx skills add and ClaudeFix: Pin versions and sources; vendor anything fetched at install time.out = subprocess.run([found_exe("ffprobe"), "-version"], stdout=subprocess.PIPE,Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.die(f"--timemap must end in .json or .csv: {args.timemap}", kind="input")Fix: Remove the call, or declare the host in frontmatter and explain in the README what is sent and why."requirements": {"python": ">=3.10 (standard library only)", "ffmpeg": ">=6.1", "ffprobe": ">=6.1", "node": ">=16 (npx installer only)"},Fix: Pin versions and sources; vendor anything fetched at install time."da": "Dansk", "no": "Norsk", "fi": "Suomi", "cs": "Cestina", "uk": "\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430",Fix: Put hosts, commands and strings in plain source. Decoding at runtime looks identical to malware and costs points on its own.Cost to the agent
Tokens estimated at four characters each. The tool list is re-read by the agent on every turn, so it is the number to compare between servers that do the same job: ranked across the index.
Known vulnerabilities
No advisories in OSV for ffmpeg-skill@3.2.3 as of 6d ago. This is the package itself, not its dependencies.
What would make this Verified
10 points to 80 · weights: behavior 45%, static 25%, prompt 15%, publisher 15%- Unclaimed publisher≈ +8 on the totalClaim kajisho5: a verified publisher gets +50 on publisher trust. It is free and usually instant with GitHub sign-in.
- Hidden zero-width characters detected≈ +4 on the totalKeep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent.
- Privileged sudo command≈ +4 on the totalBuild commands from fixed arguments; do not interpolate untrusted strings into a shell.
- Destructive file system command detected≈ +4 on the totalBuild commands from fixed arguments; do not interpolate untrusted strings into a shell.
- Python subprocess execution detected≈ +2 on the totalBuild commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
- npx invocation of non-well-known package≈ +2 on the totalPin versions and sources; vendor anything fetched at install time.