Versioned security assessment

Report ID: SA-9C287660

7/8/2026, 3:32:02 AM

media-use security assessment v3

Skill Security Certification Report

Audit History
Audit model: codex Historical report
Skill name
media-use
Version
v3
Maintainer
heygen-com
Coverage
82 Files scanned · 9,330 Lines analyzed
Policy version
Unavailable

Highest confirmed finding severity

Critical

85 confirmed security findings require attention.

Installation context

Historical evidence

This report may not describe the currently installable artifact. Open the current Skill page for install guidance.

Open current Skill page

This report does not block or authorize the manifest or ZIP.

The skill has a legitimate media workflow, but it combines network providers, credential loading, filesystem caches, bundled binaries, and extensive local command execution. Several static hits are false positives from Markdown, tests, or JavaScript template literals, but critical risks remain in shell-backed local model execution, remote installer guidance, parent .env loading, and cross-project global cache reuse.

Report position

Historical report

Open audit history before using this report to install.

Audit attestation

Not attestable

The required immutable binding is incomplete.

Human verification

Not verified

No human verification is recorded for this report.

Coverage

82 Files scanned · 9,330 Lines analyzed

282 items shown for review

Limitations

This report does not claim runtime or sandbox execution and does not prove the absence of side effects.

Evidence chain

Follow the evidence from source binding to the install contract. Available evidence supports verification; it is not a safety guarantee.

  1. Source

    Binding unavailable

  2. Artifact

    Identity incomplete

  3. Audit

    Complete

  4. Install contract

    Open manifest to verify

    Open manifest

Capabilities observed

Observed means this report recorded supporting evidence. Not recorded does not prove that a capability is absent.

Contains scripts

May execute code included with the Skill.

Observed in 17 evidence locations

Network access

May connect to external services.

Observed in 38 evidence locations

Filesystem access

May read or write local files.

Observed in 190 evidence locations

Env variables

May read values from the process environment.

Observed in 76 evidence locations

External commands

May invoke commands or programs outside the Skill.

Observed in 492 evidence locations

Capability review items (197)
Critical
Process exec
exec(fill(model.invoke, vars));
The exec callback runs a template-filled command string through a shell-backed execFileSync wrapper. User-controlled values can reach the shell.
Critical
Synchronous file execution
execFileSync("command", ["-v", bin], { stdio: "ignore", shell: true });
The code uses execFileSync with shell:true for template-filled local model commands. This can become command injection if variables contain shell metacharacters.
Critical
Synchronous file execution
execFileSync(cmd, { stdio: ["ignore", "pipe", "pipe"], shell: true, timeout: 600000 });
The code uses execFileSync with shell:true for template-filled local model commands. This can become command injection if variables contain shell metacharacters.
High
Hidden file in home directory
// Requires: $HEYGEN_API_KEY (or ~/.heygen) and ffmpeg for .wav output.
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
High
Node.js child_process module
import { spawn, spawnSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Process spawn
const proc = spawn(cmd, args, { detached: true, stdio: ["ignore", fd, fd] });
The production code spawns local commands for Python, ffmpeg, model generation, or CLIs. Arguments are mostly structured, but subprocess execution is security-relevant.
High
Process spawn
const proc = spawn(cmd, args, { detached: true, stdio: ["ignore", fd, fd] });
The production code spawns local commands for Python, ffmpeg, model generation, or CLIs. Arguments are mostly structured, but subprocess execution is security-relevant.
High
Synchronous spawn
return spawnSync(cmd, args, { stdio: "ignore" }).status === 0;
The production code spawns local commands for Python, ffmpeg, model generation, or CLIs. Arguments are mostly structured, but subprocess execution is security-relevant.
High
Synchronous spawn
return spawnSync(cmd, args, { stdio: "ignore" }).status === 0;
The production code spawns local commands for Python, ffmpeg, model generation, or CLIs. Arguments are mostly structured, but subprocess execution is security-relevant.
High
Generic API/secret keys
const lyriaKey = () => process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || "";
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Hidden file in home directory
// usable source wins — $HEYGEN_API_KEY / $HYPERFRAMES_API_KEY → a nearby .env → ~/.heygen/
The production code reads or writes hidden home-directory paths such as .media, .codex, or .heygen. These can contain reusable assets or credentials.
High
Hidden file in home directory
"no HeyGen credentials — set $HEYGEN_API_KEY, or run `npx hyperframes auth login` (writes ~/.heygen/
The production code reads or writes hidden home-directory paths such as .media, .codex, or .heygen. These can contain reusable assets or credentials.
High
Hidden file access
// usable source wins — $HEYGEN_API_KEY / $HYPERFRAMES_API_KEY → a nearby .env → ~/.heygen/
The production code reads or writes hidden home-directory paths such as .media, .codex, or .heygen. These can contain reusable assets or credentials.
High
Hidden file access
"no HeyGen credentials — set $HEYGEN_API_KEY, or run `npx hyperframes auth login` (writes ~/.heygen/
The production code reads or writes hidden home-directory paths such as .media, .codex, or .heygen. These can contain reusable assets or credentials.
High
Generic API/secret keys
const envKey = process.env.HEYGEN_API_KEY || process.env.HYPERFRAMES_API_KEY;
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Generic API/secret keys
if (!cred.api_key) return { expired: true };
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Generic API/secret keys
if (cred.api_key) return { headers: { "X-Api-Key": cred.api_key } };
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Generic API/secret keys
"no HeyGen credentials — set $HEYGEN_API_KEY, or run `npx hyperframes auth login` (writes ~/.heygen/
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Node.js child_process module
import { spawnSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Synchronous spawn
return spawnSync(cmd, args, { stdio: "ignore" }).status === 0;
The production code spawns local commands for Python, ffmpeg, model generation, or CLIs. Arguments are mostly structured, but subprocess execution is security-relevant.
High
Node.js child_process module
import { spawn, spawnSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Synchronous spawn
const r = spawnSync(cmd, args, {
The production code spawns local commands for Python, ffmpeg, model generation, or CLIs. Arguments are mostly structured, but subprocess execution is security-relevant.
High
Synchronous spawn
const r = spawnSync("ffmpeg", ["-i", absPath], { encoding: "utf8" });
The production code spawns local commands for Python, ffmpeg, model generation, or CLIs. Arguments are mostly structured, but subprocess execution is security-relevant.
High
Synchronous spawn
const r = spawnSync(
The production code spawns local commands for Python, ffmpeg, model generation, or CLIs. Arguments are mostly structured, but subprocess execution is security-relevant.
High
Synchronous spawn
const ff = spawnSync(
The production code spawns local commands for Python, ffmpeg, model generation, or CLIs. Arguments are mostly structured, but subprocess execution is security-relevant.
High
Hidden file in home directory
// 1. HeyGen (Starfish) — $HEYGEN_API_KEY / $HYPERFRAMES_API_KEY / ~/.heygen.
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
High
Generic API/secret keys
if (!process.env.ELEVENLABS_API_KEY) return false;
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Generic API/secret keys
"provider=heygen but no HeyGen credentials (set $HEYGEN_API_KEY or run `npx hyperframes auth login`)
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Generic API/secret keys
if (userProvider === "elevenlabs" && !process.env.ELEVENLABS_API_KEY)
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Generic API/secret keys
throw new Error("provider=elevenlabs but $ELEVENLABS_API_KEY is not set");
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Generic API/secret keys
client = ElevenLabs(api_key=os.environ["ELEVENLABS_API_KEY"])
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Generic API/secret keys
$GOOGLE_API_KEY or $GEMINI_API_KEY environment variable (treated as aliases).
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Generic API/secret keys
api_key = os.environ.get("GOOGLE_API_KEY") or os.environ.get("GEMINI_API_KEY") or ""
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Generic API/secret keys
if not api_key:
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Generic API/secret keys
raise RuntimeError("Neither GOOGLE_API_KEY nor GEMINI_API_KEY is set.")
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Generic API/secret keys
api_key=api_key,
The production code reads API credential environment variables or credential file fields for media providers. Secret access is intentional but sensitive.
High
Node.js child_process module
import { execFileSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Synchronous file execution
output: execFileSync(process.execPath, [RESOLVE_SCRIPT, ...args], {
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Hidden file in home directory
// the latter nested it at ~/.media/.media/manifest.jsonl, invisible to the
The production code reads or writes hidden home-directory paths such as .media, .codex, or .heygen. These can contain reusable assets or credentials.
High
Hidden file access
// the latter nested it at ~/.media/.media/manifest.jsonl, invisible to the
The production code reads or writes hidden home-directory paths such as .media, .codex, or .heygen. These can contain reusable assets or credentials.
High
Hidden file in home directory
// project (its own manifest) and across every project (the global ~/.media
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
High
Node.js child_process module
import { execFileSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Synchronous file execution
return execFileSync("codex", args, {
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Synchronous file execution
execFileSync(which, ["codex"], { stdio: ["ignore", "ignore", "ignore"], timeout: 5000 });
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Synchronous file execution
execFileSync(
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Hidden file in home directory
return 'codex CLI not reachable on PATH (a shell alias won\'t work — spawned processes can\'t see al
The production code reads or writes hidden home-directory paths such as .media, .codex, or .heygen. These can contain reusable assets or credentials.
High
Hidden file access
return 'codex CLI not reachable on PATH (a shell alias won\'t work — spawned processes can\'t see al
The production code reads or writes hidden home-directory paths such as .media, .codex, or .heygen. These can contain reusable assets or credentials.
High
Node.js child_process module
import { execFileSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Synchronous file execution
out = execFileSync("heygen", args, {
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Node.js child_process module
import { execFileSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Node.js child_process module
import { execFileSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Synchronous file execution
const out = execFileSync("hf", ["download", repo], {
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Synchronous file execution
execFileSync("which", [bin], { stdio: ["ignore", "ignore", "ignore"] });
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Synchronous file execution
execFileSync(bin, argv, {
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Node.js child_process module
import { execFileSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Synchronous file execution
const raw = execFileSync(
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Node.js child_process module
import { execSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Process exec
// `osMod` and `exec` are injectable for tests. `exec(cmd)` returns the command's
The code executes fixed system-probe commands to measure RAM and GPU capacity. It is intended, but it performs local system introspection.
High
Process exec
const out = String(exec("vm_stat"));
The code executes fixed system-probe commands to measure RAM and GPU capacity. It is intended, but it performs local system introspection.
High
Process exec
const out = String(exec("cat /proc/meminfo"));
The code executes fixed system-probe commands to measure RAM and GPU capacity. It is intended, but it performs local system introspection.
High
Process exec
const out = exec("nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits");
The code executes fixed system-probe commands to measure RAM and GPU capacity. It is intended, but it performs local system introspection.
High
Synchronous process execution
return execSync(cmd, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 4000 });
The code uses execSync for fixed system-probe commands. The commands are not user controlled, but they reveal host capabilities.
High
Linux /proc filesystem access
// reclaimable). Linux: /proc/meminfo MemAvailable. Fallback: total (optimistic
The production code reads /proc/meminfo to detect machine capacity for local model selection. It is read-only but still system introspection.
High
Linux /proc filesystem access
const out = String(exec("cat /proc/meminfo"));
The production code reads /proc/meminfo to detect machine capacity for local model selection. It is read-only but still system introspection.
High
Node.js child_process module
import { execFileSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Synchronous file execution
const out = execFileSync(
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Synchronous file execution
execFileSync("npx", argv, {
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Node.js child_process module
import { execFileSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Synchronous file execution
out = execFileSync(bin, argv, {
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Node.js child_process module
import { execFileSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Synchronous file execution
execFileSync("parakeet-mlx", ["--help"], {
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Synchronous file execution
execFileSync(
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Synchronous file execution
execFileSync("npx", ["hyperframes", "transcribe", inputPath, "--dir", workDir], {
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Node.js child_process module
import { execFileSync } from "node:child_process";
The production module imports Node child_process and uses it to run local tools or CLIs. Subprocess capability is a real execution risk.
High
Synchronous file execution
execFileSync(
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Synchronous file execution
execFileSync("ffmpeg", argv, { stdio: "ignore" });
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Synchronous file execution
const raw = execFileSync(
The production code uses execFileSync to run local CLIs such as ffmpeg, Codex, HeyGen, mflux, or transcription tools. This is a real external execution surface.
High
Hidden file in home directory
3. Check global cache `~/.media/` for a reusable asset matched on the same normalized prompt — auto-
The documentation describes use of a hidden home-directory global media cache. That cache can have privacy impact across projects.
High
Hidden file in home directory
- `~/.media/`: global cross-project reuse cache (content-addressed, SHA-256)
The documentation describes use of a hidden home-directory global media cache. That cache can have privacy impact across projects.
Medium
Synchronous file operations
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
request = JSON.parse(readFileSync(requestPath, "utf8"));
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const prev = existsSync(outPath) ? JSON.parse(readFileSync(outPath, "utf8")) : {};
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(outPath, JSON.stringify(meta, null, 2));
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
? readFileSync(resolve(positional), "utf8").trim()
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(wordsPath, JSON.stringify(withWordIds(words), null, 2));
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Hidden file access
// Requires: $HEYGEN_API_KEY (or ~/.heygen) and ffmpeg for .wav output.
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
Medium
Hidden file access
if (/cascade|feature.benefit/.test(at))
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
Medium
Hidden file access
if (/demo.loop|question.+answer/.test(at))
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
Medium
Hidden file access
if (/frustrat|anxiety|overwhelm|tension/.test(ar) && /relief|excite|triumph/.test(ar))
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
Medium
Hidden file access
if (/excit|awe|power|triumph/.test(ar))
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
Medium
Hidden file access
if (/trust|ease|clarity|reassur/.test(ar))
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
Medium
Environment variable access (dot notation)
const lyriaKey = () => process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || "";
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable object
const lyriaKey = () => process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || "";
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Fetch API call
const res = await fetch(`${HEYGEN_BASE}${path}`, opts);
The production code performs outbound fetch calls to provider, telemetry, or user-supplied media URLs. That is a real network capability requiring user awareness and controls.
Medium
Fetch API call
const res = await fetch(url);
The production code performs outbound fetch calls to provider, telemetry, or user-supplied media URLs. That is a real network capability requiring user awareness and controls.
Medium
Synchronous file operations
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
for (const raw of readFileSync(envPath, "utf8").split("\n")) {
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const raw = readFileSync(file, "utf8").trim();
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(destPath, bytes);
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Environment variable access (bracket notation)
if (!(key in process.env)) process.env[key] = val;
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable access (dot notation)
const envKey = process.env.HEYGEN_API_KEY || process.env.HYPERFRAMES_API_KEY;
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable access (dot notation)
const file = join(process.env.HEYGEN_CONFIG_DIR || join(homedir(), ".heygen"), "credentials");
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable object
if (!(key in process.env)) process.env[key] = val;
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable object
const envKey = process.env.HEYGEN_API_KEY || process.env.HYPERFRAMES_API_KEY;
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable object
const file = join(process.env.HEYGEN_CONFIG_DIR || join(homedir(), ".heygen"), "credentials");
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Synchronous file operations
import { copyFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Fetch API call
const res = await fetch(inner.audio_url);
The production code performs outbound fetch calls to provider, telemetry, or user-supplied media URLs. That is a real network capability requiring user awareness and controls.
Medium
Synchronous file operations
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(tmp, bytes);
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(wavAbs, bytes);
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const arr = JSON.parse(readFileSync(src, "utf8"));
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(p, text);
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Hidden file access
// 1. HeyGen (Starfish) — $HEYGEN_API_KEY / $HYPERFRAMES_API_KEY / ~/.heygen.
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
Medium
Hidden file access
.filter((w) => !/^<.*>$/.test(w.word.trim())) // drop <start>/<end> sentinels
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
Medium
Environment variable access (dot notation)
if (!process.env.ELEVENLABS_API_KEY) return false;
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable access (dot notation)
if (userProvider === "elevenlabs" && !process.env.ELEVENLABS_API_KEY)
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable access (dot notation)
npmExecPath = process.env.npm_execpath,
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable object
if (!process.env.ELEVENLABS_API_KEY) return false;
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable object
if (userProvider === "elevenlabs" && !process.env.ELEVENLABS_API_KEY)
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable object
npmExecPath = process.env.npm_execpath,
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable object
env = process.env,
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable object
env = process.env,
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Python environment access
client = ElevenLabs(api_key=os.environ["ELEVENLABS_API_KEY"])
The code reads provider credentials from the Python environment for media generation. That is expected but sensitive.
Medium
Python environment access
api_key = os.environ.get("GOOGLE_API_KEY") or os.environ.get("GEMINI_API_KEY") or ""
The code reads provider credentials from the Python environment for media generation. That is expected but sensitive.
Medium
dotenv library
pip install google-genai python-dotenv. audio.mjs Step 4b installs these on
The script loads dotenv support for cloud music generation credentials. That can import local secrets into the process.
Medium
Synchronous file operations
import { existsSync, readFileSync, statSync, writeFileSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const txt = readFileSync(path, "utf8");
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(outPath, JSON.stringify(payload, null, 2) + "\n");
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const audioMeta = JSON.parse(readFileSync(audioMetaPath, "utf8"));
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
import { readFileSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const meta = JSON.parse(readFileSync(resolve(args.meta), "utf8"));
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const html = readFileSync(resolve(composition), "utf8");
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
readFileSync,
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync,
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const html = readFileSync(join(tmp, hf), "utf8");
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
? readFileSync(indexPath, "utf8")
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
? readFileSync(manifestPath, "utf8")
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(outPath, report);
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
import { readFileSync, existsSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const content = readFileSync(spec.path, "utf8");
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Hidden file access
if (typeof v === "string" && /^#[0-9a-fA-F]{3,8}$/.test(v)) {
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
Medium
Synchronous file operations
import { readFileSync, writeFileSync, mkdirSync, existsSync, copyFileSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const bytes = readFileSync(filePath);
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(join(entryDir, COMPLETE_SENTINEL), "", "utf8");
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Hidden file access
// project (its own manifest) and across every project (the global ~/.media
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
Medium
Environment variable access (dot notation)
return join(process.env.CODEX_HOME || join(homedir(), ".codex"), "generated_images");
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable access (dot notation)
const authPath = join(process.env.CODEX_HOME || join(homedir(), ".codex"), "auth.json");
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable object
return join(process.env.CODEX_HOME || join(homedir(), ".codex"), "generated_images");
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Environment variable object
const authPath = join(process.env.CODEX_HOME || join(homedir(), ".codex"), "auth.json");
The production code reads environment variables for provider credentials or auth locations. This is expected but security-relevant.
Medium
Fetch API call
const res = await fetch(url);
The production code performs outbound fetch calls to provider, telemetry, or user-supplied media URLs. That is a real network capability requiring user awareness and controls.
Medium
Synchronous file operations
import { writeFileSync, copyFileSync, mkdirSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(destPath, Buffer.concat(chunks, total));
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Hidden file access
// ext derived from the asset URL by resolve.mjs (.jpg/.png/.webp)
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
Medium
Synchronous file operations
import { writeFileSync, mkdirSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(p, content);
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
readFileSync,
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
appendFileSync,
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync,
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const raw = readFileSync(p, "utf8");
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
appendFileSync(p, line);
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(join(projectDir, localPath), "", { flag: "wx" }); // durable reservation
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Hidden file access
throw new Error("media-use: timed out acquiring .media/.lock");
The line references a hidden path outside an obvious safe context. Kept for fail-closed review due to possible hidden-file access.
Medium
Fetch API call
await fetch(`${POSTHOG_HOST}/batch/`, {
The production code performs outbound fetch calls to provider, telemetry, or user-supplied media URLs. That is a real network capability requiring user awareness and controls.
Medium
Synchronous file operations
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
if (existsSync(file)) return readFileSync(file, "utf8").trim();
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(file, id);
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
import { readFileSync, readdirSync, existsSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
return readFileSync(join(projectDir, f), "utf8");
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
readFileSync,
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync,
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(tmp, data);
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const merged = mergeTokensToWords(JSON.parse(readFileSync(jsonPath, "utf8")));
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const t = JSON.parse(readFileSync(outPath, "utf8"));
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
import { mkdtempSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
const transcript = JSON.parse(readFileSync(resolve(args.transcript), "utf8"));
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Synchronous file operations
writeFileSync(
The production code performs synchronous filesystem reads or writes for manifests, caches, media files, or config. This is expected but broadens local data access.
Medium
Hidden file access
3. Check global cache `~/.media/` for a reusable asset matched on the same normalized prompt — auto-
The documentation describes use of a hidden home-directory global media cache. That cache can have privacy impact across projects.
Medium
Hidden file access
- `~/.media/`: global cross-project reuse cache (content-addressed, SHA-256)
The documentation describes use of a hidden home-directory global media cache. That cache can have privacy impact across projects.
Low
Hardcoded URL
export const HEYGEN_BASE = "https://api.heygen.com/v3";
The production code references fixed external service endpoints. They appear intentional, but they create real outbound network dependencies.
Low
Temp file creation
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
The production code creates temporary files or directories for media conversion or transcription. This is normal but can leave artifacts if cleanup fails.
Low
Temp file creation
const td = mkdtempSync(join(tmpdir(), "hf-tts-"));
The production code creates temporary files or directories for media conversion or transcription. This is normal but can leave artifacts if cleanup fails.
Low
Temp file creation
const td = mkdtempSync(join(tmpdir(), "hf-trans-"));
The production code creates temporary files or directories for media conversion or transcription. This is normal but can leave artifacts if cleanup fails.
Low
Temp file creation
const td = mkdtempSync(join(tmpdir(), "hf-txt-"));
The production code creates temporary files or directories for media conversion or transcription. This is normal but can leave artifacts if cleanup fails.
Low
Temp file creation
mkdtempSync,
The production code creates temporary files or directories for media conversion or transcription. This is normal but can leave artifacts if cleanup fails.
Low
Temp file creation
const tmp = mkdtempSync(join(tmpdir(), `mu-eval-${name}-`));
The production code creates temporary files or directories for media conversion or transcription. This is normal but can leave artifacts if cleanup fails.
Low
Hardcoded URL
"git clone https://github.com/dgrauet/ltx-2-mlx && cd ltx-2-mlx && uv sync --all-extras",
The production code references fixed external service endpoints. They appear intentional, but they create real outbound network dependencies.
Low
Hardcoded URL
"git clone https://github.com/dgrauet/ltx-2-mlx && cd ltx-2-mlx && uv sync --all-extras",
The production code references fixed external service endpoints. They appear intentional, but they create real outbound network dependencies.
Low
Hardcoded URL
const POSTHOG_HOST = "https://us.i.posthog.com";
The production code references fixed external service endpoints. They appear intentional, but they create real outbound network dependencies.
Low
Temp file creation
mkdtempSync,
The production code creates temporary files or directories for media conversion or transcription. This is normal but can leave artifacts if cleanup fails.
Low
Temp file creation
const workDir = mkdtempSync(join(tmpdir(), "media-use-asr-"));
The production code creates temporary files or directories for media conversion or transcription. This is normal but can leave artifacts if cleanup fails.
Low
Temp file creation
const workDir = mkdtempSync(join(tmpdir(), "media-use-whisper-"));
The production code creates temporary files or directories for media conversion or transcription. This is normal but can leave artifacts if cleanup fails.
Low
Environment variable access (dot notation)
process.env.HYPERFRAMES_PARAKEET,
The code reads an environment-controlled path for a local transcription tool. This changes local execution behavior and should be documented.
Low
Environment variable object
process.env.HYPERFRAMES_PARAKEET,
The code reads an environment-controlled path for a local transcription tool. This changes local execution behavior and should be documented.
Low
Temp file creation
import { mkdtempSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
The production code creates temporary files or directories for media conversion or transcription. This is normal but can leave artifacts if cleanup fails.
Low
Temp file creation
const tmpDir = mkdtempSync(join(tmpdir(), "media-use-cut-"));
The production code creates temporary files or directories for media conversion or transcription. This is normal but can leave artifacts if cleanup fails.

Risk findings

Confirmed security concerns are separated from items that still need review.

Confirmed security concerns (85)

RISK-001 Critical
Pipe to shell pattern
| `heygen` | catalog (bgm/sfx/image/icon), TTS + avatar upsell | `c
The documentation recommends piping a remote installer script directly into a shell. That pattern can execute unverified remote code on the user machine.
RISK-002 Critical
[HEURISTIC] DANGEROUS COMBINATION: Code execution + Network + Credential access
This combination is common in credential stealers and RATs
The skill contains real subprocess execution, network calls, and credential handling in production modules. The media context is legitimate, but this combination is dangerous for a community marketplace skill.
RISK-003 Critical
Shell Template Execution With Media Variables
The local model runner fills command templates with values such as text, prompt, paths, and output names, then executes the resulting string through a shell. Untrusted media prompts can become command-injection input.
execFileSync is configured with shell:true and local-run executes fill(model.invoke, vars). The templates include text and prompt placeholders, which are plausible user-controlled strings.
RISK-004 High
Environment file access
const lyriaKey = () => process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || "";
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-005 High
Environment file access
// usable source wins — $HEYGEN_API_KEY / $HYPERFRAMES_API_KEY → a nearby .env → ~/.heygen/
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-006 High
Environment file access
// Walk up ≤5 dirs from startDir; load the first .env (shell env always wins).
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-007 High
Environment file access
const envPath = join(dir, ".env");
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-008 High
Environment file access
if (!(key in process.env)) process.env[key] = val;
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-009 High
Environment file access
const envKey = process.env.HEYGEN_API_KEY || process.env.HYPERFRAMES_API_KEY;
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-010 High
Environment file access
const file = join(process.env.HEYGEN_CONFIG_DIR || join(homedir(), ".heygen"), "credentials");
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-011 High
Environment file access
if (!process.env.ELEVENLABS_API_KEY) return false;
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-012 High
Environment file access
if (userProvider === "elevenlabs" && !process.env.ELEVENLABS_API_KEY)
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-013 High
Environment file access
npmExecPath = process.env.npm_execpath,
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-014 High
Environment file access
env = process.env,
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-015 High
Environment file access
env = process.env,
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-016 High
Environment file access
return join(process.env.CODEX_HOME || join(homedir(), ".codex"), "generated_images");
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-017 High
Environment file access
const authPath = join(process.env.CODEX_HOME || join(homedir(), ".codex"), "auth.json");
The production code reads credential-bearing environment variables, .env files, or CLI auth files. That is sensitive configuration access.
RISK-018 High
Environment file access
process.env.HYPERFRAMES_PARAKEET,
The code reads an environment-controlled executable path for local transcription. This is not a secret, but it can alter which local binary runs.
RISK-019 High
[HEURISTIC] SUSPICIOUS COMBINATION: Filesystem + Credentials + Network
This combination could indicate credential harvesting and exfiltration
The skill reads credentials, writes project and home-directory media caches, and contacts external services. That combination is a real privacy and supply-chain risk even though the stated purpose is media generation.
RISK-020 High
Cross-Project Asset Exposure Through Global Cache
The skill promotes resolved assets to a global home-directory cache and lists global reuse candidates. This can expose another project's prompts, descriptions, or brand assets during later work.
The documentation explicitly warns that global candidates can surface another client's brand mark, and cache code stores reusable records under the home directory. The privacy risk is direct and intentional, even if mitigated by user review.
RISK-021 High
Automatic Parent .env Credential Loading
The HeyGen helper walks up parent directories and loads the first .env file into process.env. This can import unrelated project secrets into the skill process without an explicit user selection.
The code reads .env files while walking parent directories and writes missing keys into process.env. That is clear credential boundary expansion.
RISK-022 High
Nested Codex Agent Execution From User Prompt
The Codex image provider sends the media intent into a nested codex exec session with workspace-write and image generation enabled. A malicious intent could try to steer the nested agent beyond image generation.
The provider builds a prompt from intent and runs codex exec with tool flags and a no-confirmation instruction. The working directory is temporary, but nested agent prompt injection remains a meaningful risk.
RISK-023 Low
System reconnaissance
// "lines": [ // one TTS unit each; id joins back to the caller's model
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-024 Low
System reconnaissance
let voiceId = prev.voice_id ?? null;
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-025 Low
System reconnaissance
const id = String(line.id);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-026 Low
System reconnaissance
bgm_pid: prev.bgm_pid ?? null,
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-027 Low
System reconnaissance
bgmFields.bgm_pid = gen.pid;
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-028 Low
System reconnaissance
console.error(` bgm: launched ${gen.provider} (detached, pid ${gen.pid}) → ${gen.path}`);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-029 Low
System reconnaissance
* the eventual spawn fails loudly exactly as it did before — never worse.
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-030 Low
System reconnaissance
// cues: [{ id, name }] (id = the line/frame/scene the cue fires in). Returns
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-031 Low
System reconnaissance
anomalies.push(`sfx "${name}" (id ${id}): no HeyGen match — skipped`);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-032 Low
System reconnaissance
anomalies.push(`sfx "${name}" (id ${id}): retrieval failed — ${e.message}`);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-033 Low
System reconnaissance
`sfx "${name}" (id ${id}): not in bundled library — skipped (have: ${known}...)`,
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-034 Low
System reconnaissance
`sfx "${name}" (id ${id}): bundled file ${hit.file} missing from the offline ` +
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-035 Low
System reconnaissance
throw new Error(`invalid provider "${userProvider}" (heygen | elevenlabs | kokoro)`);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-036 Low
System reconnaissance
// Avoid `shell:true` and the .cmd shim entirely by invoking npm's JS CLI with
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-037 Low
Network reconnaissance
if (!pick) throw new Error("no public starfish voice to default to — pass --voice");
The production code includes network-related probing or URL handling. The evidence is weak but kept for fail-closed review.
RISK-038 Low
System reconnaissance
if (!pid || !Number.isFinite(Number(pid))) return false;
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-039 Low
System reconnaissance
const pid = audioMeta.bgm_pid || null;
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-040 Low
System reconnaissance
--offsets Explicit placement, "l1=0,l2=3.4" (voice id = start seconds)
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-041 Low
System reconnaissance
const id = target.slice(1);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-042 Low
System reconnaissance
.stat { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 14
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-043 Low
System reconnaissance
th { text-align: left; font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transf
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-044 Low
System reconnaissance
td { border-bottom: 1px solid var(--border); padding: 7px 8px; vertical-align: top }
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-045 Low
System reconnaissance
.col { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 14p
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-046 Low
System reconnaissance
pre.file-list { background: var(--bg); color: var(--muted); border: 1px solid var(--border) }
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-047 Low
System reconnaissance
.block-detail { border-top: 1px solid var(--border); padding-top: 20px; margin-top: 20px }
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-048 Low
System reconnaissance
.verdict.ship { background: #edfbf0; border: 1px solid #1a7a3a; color: #1a7a3a }
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-049 Low
System reconnaissance
.verdict.wait { background: #fff3ec; border: 1px solid #d94f04; color: #d94f04 }
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-050 Low
System reconnaissance
const id = nextId(projectDir, asset.type);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-051 Low
System reconnaissance
const record = records.find((r) => r.id === id);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-052 Low
System reconnaissance
if (!match) throw new Error(`invalid range: ${value}`);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-053 Low
System reconnaissance
throw new Error(`invalid word range: ${range}`);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-054 Low
System reconnaissance
const id = voice?.id ?? String(i);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-055 Low
System reconnaissance
if (!(id in offsets)) throw new Error(`--offsets is missing voice "${id}"`);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-056 Low
Network reconnaissance
"audio_meta has multiple voice lines with file-relative times; pass --sequential or --offsets so spa
The production code includes network-related probing or URL handling. The evidence is weak but kept for fail-closed review.
RISK-057 Low
System reconnaissance
// IPv6 equivalents on the literal hostname.
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-058 Low
System reconnaissance
// untrusted hostnames at scale.
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-059 Low
System reconnaissance
if (PLATFORM_HOSTS.test(url.hostname)) return false;
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-060 Low
System reconnaissance
if (PRIVATE_HOST.test(url.hostname)) return false;
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-061 Low
System reconnaissance
cols.id = Math.max(cols.id, (r.id ?? "").length);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-062 Low
System reconnaissance
pad("id", cols.id + 2) +
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-063 Low
System reconnaissance
pad(r.id, cols.id + 2) +
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-064 Low
System reconnaissance
// components from disk) the SAME machine did 512x512 in ~20s at 7.6GB
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-065 Low
System reconnaissance
// a bare repo id in --path breaks mlx unflatten.
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-066 Low
System reconnaissance
"FLUX.1 schnell int4. VERIFIED on 24GB (7.6GB free): --low-ram 512x512 in ~20s, photoreal. --low-ram
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-067 Low
System reconnaissance
// Coarse per-project lock so concurrent resolves don't race on id allocation.
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-068 Low
System reconnaissance
// Atomically allocate the next free id for `type` AND reserve its file, so a
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-069 Low
System reconnaissance
// caller grab the same id (the MU-23 clobber). Under the lock we take the max id
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-070 Low
System reconnaissance
const id = `${type}_${String(max + 1).padStart(3, "0")}`;
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-071 Low
System reconnaissance
// (hf download, idempotent) because a bare repo id breaks mlx unflatten.
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-072 Low
System reconnaissance
// for the voice type, ahead of the paid HeyGen TTS upsell
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-073 Low
System reconnaissance
// X4: agent-initiated paid should confirm). HeyGen catalog SEARCH is free;
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-074 Low
System reconnaissance
// HeyGen TTS now costs credits, so it is the paid upsell behind local Kokoro.
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-075 Low
System reconnaissance
const P = (name, caps) => ({ name, network: true, paid: true, ...caps }); // remote, paid
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-076 Low
System reconnaissance
// under --local-only), then HeyGen TTS as the higher-quality paid upsell and
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-077 Low
Network reconnaissance
// Catalog miss -> generate. Local first (best FLUX-class model the machine's
The production code includes network-related probing or URL handling. The evidence is weak but kept for fail-closed review.
RISK-078 Low
System reconnaissance
// Paginated text search over a manifest (project or global) by id / description
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-079 Low
System reconnaissance
const id = randomUUID();
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-080 Low
System reconnaissance
cachedVoiceId = j?.data?.[0]?.voice_id || null;
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-081 Low
System reconnaissance
return { id: w?.id ?? `w${index}`, text, start, end };
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-082 Low
System reconnaissance
const id = nextId(projectDir, type);
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-083 Low
System reconnaissance
// can't collide on an id during the download — MU-23)
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-084 Low
System reconnaissance
// truncated transcript at outPath (downstream reads it as valid JSON).
The code checks local tools or machine specs to choose media providers. This is expected behavior, but it is still host introspection.
RISK-085 Low
Network reconnaissance
throw new Error("--input and --out are required unless --plan is set");
The production code includes network-related probing or URL handling. The evidence is weak but kept for fail-closed review.

Remediation

Suggested fixes recorded by this audit. Applying them is the maintainer’s responsibility.

  1. FIX-001
    Critical
    Remote installer is documented as curl piped to bash.
    Replace the pipe-to-shell command with signed release downloads, package-manager installation, and checksum verification steps.
  2. FIX-002
    Critical
    Local model commands are template-filled and executed through a shell.
    Use execFileSync or spawn with argv arrays, quote nothing through a shell, and validate every prompt, path, and numeric argument before execution.
  3. FIX-003
    High
    The HeyGen helper auto-loads parent .env files into process.env.
    Require explicit credential sources, stop walking parent directories by default, and never import unrelated .env values into the process.
  4. FIX-004
    High
    Global media cache can expose prompts and assets across projects.
    Partition the cache by workspace or organization, redact prompt text from global listings, and require explicit confirmation before global reuse.
  5. FIX-005
    High
    A nested Codex CLI run receives user media intent as a prompt.
    Constrain nested agent execution with a fixed tool-only contract, remove no-confirmation wording, and reject intents that include instructions to alter files or run commands.
  6. FIX-006
    Medium
    Bundled MP3 assets are binary files outside static source review.
    Publish hashes, licenses, provenance, and malware-scanning results for each audio asset before marketplace publication.
  7. FIX-007
    Medium
    Telemetry is enabled unless users opt out.
    Make telemetry opt-in for marketplace distribution, document exact fields sent, and keep network failure non-blocking.

Expert evidence

Immutable subject identity, scanner metadata, dismissed matches, and source-level evidence.

Artifact subject

Marketplace commit
Unavailable
Content hash
Unavailable
Tree hash
Unavailable
Skill path
Unavailable
Audit payload hash
Unavailable

Analysis metadata

Audit model: codex

Analysis state: Complete

Scope is limited to the recorded files, lines, methods, and evidence. No runtime or sandbox execution is claimed.

Verify and export

The manifest and lockfile bind install artifacts to cryptographic hashes. This integrity claim is separate from the security assessment.

Audit attestation: not_attestable