Back to skill

Security audit

embedded-captions

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent captioning tool, but it asks to mutate installed skills and can fetch or run remote code during a workflow described as local.

Install only if you are comfortable with a captioning skill that can update global skills and retrieve runtime dependencies. Prefer running it in a restricted project environment, review or pin the updater and WhisperX dependency path, pre-provision model assets, and block remote browser script loads when processing sensitive videos.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T08 · Insecure Dependencies

Error
Location
scripts/transcribe.cjs:181
Finding
WhisperX Is Dynamically Retrieved and Executed Through uvx<![CDATA[ ## Vulnerability Details **File Location**: `scripts/transcribe.cjs:181-205` **Vulnerability Type**: Runtime execution of externally retrieved dependency code **Risk Level**: High ### Vulnerable Code ```js const whisperxSpec = `whisperx==${process.env.WHISPERX_VERSION || "3.8.6"}`; const wxArgs = [ "--python", "3.12", "--from", whisperxSpec, "whisperx", wav, "--model", wxModel, "--device", "cpu", "--compute_type", "int8", "--output_dir", outDir, "--output_format", "json", "--no_align_deletes", "--print_progress", "False", ]; if (language) wxArgs.push("--language", language); // strip our flag if this whisperx build doesn't know it let r = cp.spawnSync("uvx", wxArgs, { encoding: "utf8", timeout: 600000 }); ``` ### Technical Analysis The default transcription path invokes `uvx` with a package specification for `whisperx`. If the package is not already cached, `uvx` can retrieve the package and its transitive Python dependencies and then execute them with the privileges of the user running the Skill. The top-level WhisperX version defaults to `3.8.6`, which provides some reproducibility, but no package hashes or locked transitive dependency set are enforced. The effective executed code may consequently change if a dependency release is replaced, compromised, or resolved differently by the package manager. The package specification is also influenced by the inherited `WHISPERX_VERSION` environment variable. This is not direct shell-command injection because `spawnSync` receives an argument array rather than a shell command, but an attacker capable of controlling the environment could select a different package version for execution. ### Attack Path 1. The user or Agent runs `bash scripts/prepare.sh <project>`. 2. `prepare.sh` launches `scripts/transcribe.cjs`. 3. Unless `TRANSCRIBE_ENGINE` disables WhisperX, the script constructs a package specification from `WHISPERX_VERSION` or the default version. 4. The scr ...[truncated 904 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Preinstall WhisperX from a reviewed, immutable dependency set rather than resolving it during each Skill run. 2. Maintain a lockfile that fixes every transitive dependency and verifies package hashes. 3. Use an explicitly trusted package index and prevent fallback to unapproved indexes. 4. Replace unrestricted `WHISPERX_VERSION` handling with an allowlist of reviewed versions. 5. Require explicit user confirmation before any first-time package retrieval. 6. Run transcription in a sandbox with: - Network access disabled after dependency provisioning. - Read access limited to the input media. - Write access limited to the project directory. - No access to SSH keys, cloud credentials, or unrelated home-directory files. 7. Record the exact package versions and hashes used in the generated project metadata. ]]>

T08 · Insecure Dependencies

Error
Location
SKILL.md:12
Finding
Unversioned npx Self-Update Executes Mutable Remote Package Code<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:12` **Vulnerability Type**: Unpinned package execution and post-review Skill replacement **Risk Level**: High ### Vulnerable Instruction ```markdown > **First, keep this skill fresh — confirm with the user before running:** `npx hyperframes skills update embedded-captions`. A fast no-op when everything is current; otherwise it refreshes this skill plus the core domain skills it depends on before you rely on them. ``` ### Technical Analysis The Skill directs the Agent to invoke `npx hyperframes` without an explicit package version or integrity constraint. Depending on the local environment and npm cache, `npx` may retrieve and immediately execute the currently resolved `hyperframes` package. The invoked command is also intended to replace or refresh this Skill and related Skills. Therefore, code and instructions that were not part of the audited artifact may become active before the workflow continues. User confirmation reduces the risk of an unexpected update but does not protect against package takeover, registry compromise, dependency compromise, or an unsafe future release. This is both a dependency supply-chain risk and a mutable-code execution channel. It is not classified as instruction hijacking because the reviewed instruction openly describes the update behavior and does not attempt to override safety constraints. ### Attack Path 1. The Agent loads the Skill and follows its initial update instruction. 2. The Agent asks for confirmation, and the user approves the update. 3. `npx` resolves the unversioned `hyperframes` package from its configured npm registry or cache. 4. Package lifecycle or command code executes under the Agent's user account. 5. The updater replaces this Skill or related core Skills with content not covered by the current audit. 6. The Agent relies on and executes the newly installed instructions or scripts. 7. A compromised package or update can consequently obtai ...[truncated 568 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the command to a reviewed package version, for example through a project lockfile rather than an unversioned `npx` invocation. 2. Verify the package artifact against an expected integrity digest before execution. 3. Separate update checking from update installation: - First report the installed and available versions. - Show the source and expected digest. - Obtain explicit approval for the specific version. 4. Download updates into a staging directory and present a file diff before activating them. 5. Do not automatically replace the currently executing Skill. 6. Preserve the audited version and support an explicit rollback procedure. 7. Disable package lifecycle scripts where they are unnecessary. 8. Run the updater with filesystem access restricted to the designated Skill installation directory. ]]>

T03 · Remote Payload Retrieval and Execution

Warning
Location
scripts/preview-frames.cjs:108
Finding
Caption Templates Can Load Executable JavaScript from a Remote CDN<![CDATA[ ## Vulnerability Details **File Locations**: - `modes/cinematic/engine.html:29` - `modes/cinematic/cinematic-cream/template.html:87` - `scripts/make-theme.cjs:561` - `scripts/preview-frames.cjs:108-111` **Vulnerability Type**: Remote JavaScript retrieval during local preview or rendering **Risk Level**: Medium ### Vulnerable Code Cinematic templates reference GSAP through a remote CDN: ```html <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script> ``` Theme generation includes an integrity attribute: ```js const GSAP = `<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js" integrity="sha384-sG0Hv1tP1lZCk9KQmrIbY/XNwi+OY84GQqhMscbnsoBFqAz8KNCil1kvfL3Hbbk2" crossorigin="anonymous"></script>`; ``` The preview code substitutes a local copy when available but permits the remote request otherwise: ```js } else if (req.resourceType() === "script" && /gsap/i.test(u) && /^https?:/i.test(u)) { if (gsapSource) req.respond({ status: 200, contentType: "application/javascript", body: gsapSource }); else req.continue(); // no local bundle — let the CDN load (online machines) ``` The preview browser is also launched with weakened browser isolation: ```js const browser = await puppeteer.launch({ headless: "new", executablePath: fs.existsSync(exe) ? exe : undefined, args: ["--disable-web-security", "--allow-file-access-from-files", "--disable-dev-shm-usage"], }); ``` ### Technical Analysis The generated or template HTML depends on executable JavaScript served by jsDelivr. Although the URL pins GSAP to version `3.14.2`, the cinematic template references observed during the audit do not include a Subresource Integrity attribute. A compromised CDN response, package artifact, TLS trust path, or local network interception capability could therefore alter the code executed by Chromium. The theme generator includes SRI, which is a meaningful mitigation for theme output. The preview path also attempts to ser ...[truncated 1880 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Bundle the reviewed GSAP asset directly inside the Skill package. 2. Rewrite all generated templates to reference only the bundled local asset. 3. Block every outbound network request during preview and final rendering; fail closed if a required local dependency is unavailable. 4. Apply a Content Security Policy such as: - `default-src 'none'` - `script-src 'self'` - Explicit local allowances only for required media and styles. 5. If remote loading must remain, require SRI on every script reference and maintain the expected digest in reviewed source. 6. Remove `--disable-web-security` and `--allow-file-access-from-files` unless a documented, unavoidable requirement exists. 7. Serve project assets from a restricted loopback HTTP server instead of using broad file URL access. 8. Run Chromium in an OS-level sandbox with access limited to a disposable rendering directory. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (30)

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The skill advertises that processing runs locally end to end, but it instructs the agent to run a network-based self-update command and notes dependency/model downloads from GitHub and remote caches. This creates a supply-chain and trust-boundary mismatch: an operator may approve the skill believing it is offline/local-only, while execution can fetch and install changed code or assets from the network at runtime.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The template fetches GSAP at runtime from a third-party CDN, which breaks the stated local-only execution model and introduces a supply-chain and privacy risk. If the CDN response is tampered with, unavailable, or causes network egress in restricted environments, rendered jobs could execute attacker-controlled JavaScript or fail unpredictably.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The template loads GSAP from a public CDN even though the skill metadata says the workflow runs locally end to end. That creates an external supply-chain and availability dependency: a compromised CDN, MITM on an untrusted network, or upstream script change could inject code into the rendering environment or break local/offline execution.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
Remote CDN script loading is unnecessary for a local caption-rendering workflow and expands the attack surface beyond the host system. If the remote asset is tampered with or unavailable, the skill can execute attacker-controlled JavaScript or fail unpredictably, undermining both security and reproducibility.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The template loads GSAP from a third-party CDN even though the skill claims to run locally end to end. This introduces an unnecessary external dependency that can leak usage metadata, break offline operation, and create a supply-chain risk if the CDN response is tampered with or unavailable.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
For a local video-captioning workflow, outbound network access to fetch a runtime library is not operationally necessary and expands the attack surface. An attacker controlling or intercepting the CDN response could execute arbitrary script in the rendering context, while ordinary users also lose the privacy and reliability expected from a local-only tool.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The template loads GSAP from a third-party CDN even though the skill metadata promises a fully local end-to-end workflow. This creates a supply-chain and privacy risk: rendering now depends on network access and trust in an external host, and a compromised or changed CDN asset could execute arbitrary script in the rendering environment.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The file loads GSAP from a third-party CDN even though the skill metadata says the workflow runs locally end to end. That creates a supply-chain and integrity risk: if the CDN, package, or network path is tampered with, arbitrary script would execute in the rendering context, and it also breaks offline/local-only assumptions by making a network dependency visible to external infrastructure.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill description explicitly claims a local-only workflow, but the example code imports GSAP from a public CDN at runtime. That creates a supply-chain and privacy boundary violation: rendering now depends on a third-party network resource that could be unavailable, tampered with, blocked, or used to leak execution metadata, undermining both the documented trust model and reproducibility guarantees.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The guidance explicitly allows dropping filler, condensing phrases, and skipping speech, which conflicts with the skill metadata stating it can be used for plain verbatim captions. In a captioning workflow, this can silently produce inaccurate or non-verbatim subtitles, creating integrity, accessibility, and compliance risk if a user expected faithful captions.

Intent-Code Divergence

Low
Confidence
82% confidence
Finding
The document says to pass through original word timestamps without retiming, but earlier permits dropping words from groups. That inconsistency can cause implementers to produce malformed group/word mappings or misleading timing semantics, undermining correctness and making downstream rendering logic error-prone.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The file imports executable JavaScript from a public CDN despite the skill claiming the workflow runs locally end to end. This creates a supply-chain and availability risk: a compromised CDN, package version swap, or network dependency can inject code into local rendering workflows or break reproducibility/offline use.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The file loads GSAP from a third-party CDN, which contradicts the skill's stated local end-to-end workflow and introduces a supply-chain and privacy risk. If the CDN asset is unavailable, tampered with, or replaced, opening the example render could execute untrusted JavaScript in the local rendering environment.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The script launches Chrome with `--disable-web-security` and `--allow-file-access-from-files` while opening a local `file://` HTML document. If that HTML or any referenced script/content is attacker-controlled, the page runs with weakened same-origin protections and can read other local files or make otherwise restricted cross-origin requests, expanding the blast radius beyond a normal local render check. In this skill, the tool explicitly processes arbitrary project HTML for local rendering, so treating the content as untrusted makes this materially risky.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The script launches Chromium against attacker-controlled local HTML with both --disable-web-security and --allow-file-access-from-files enabled. In this mode, any script embedded in index.html or rail.html can make cross-file requests and read other local files reachable by the browser process, which is broader than needed for a local validation gate and turns malformed project content into a local file exposure primitive.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The generated HTML unconditionally loads GSAP from a remote jsDelivr CDN, which breaks the skill's stated local-only execution model and creates a supply-chain/network dependency at render time. If the CDN is unavailable, intercepted, or serves compromised content, the generated pages will execute untrusted JavaScript during rendering.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The script explicitly states the workflow runs locally end to end, yet it relies on hyperframes' auto-download of a large model into ~/.cache on first run. That creates an undeclared network dependency and a supply-chain exposure path at execution time, which is risky in environments expecting offline-only processing or strict egress controls.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
A local captioning/matting skill invoking a backend that can fetch executable model assets over the network expands the trust boundary beyond the local machine. Even if the download is legitimate, it introduces policy bypass, reproducibility issues, and potential compromise if the remote source or transport is tampered with.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The script launches Chromium with both --disable-web-security and --allow-file-access-from-files, then opens a project-supplied local index.html. That combination allows active content in the project HTML to bypass normal same-origin restrictions and read other local file:// resources available to the process, which is broader than required for layout measurement and creates a real attack surface if the project contents are untrusted or attacker-influenced.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
This preview utility launches Chromium with both --disable-web-security and --allow-file-access-from-files, which disables same-origin protections and permits broader local file access than is necessary for rendering local HTML screenshots. Because the tool loads project-controlled index.html/rail.html and intentionally allows remote script URLs to load if no local GSAP bundle is available, a malicious or compromised project file could abuse the relaxed browser to read cross-file content or interact with network resources in ways normal browser isolation would block.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The script executes a project-local shell script (`$PROJECT/_postfx.sh`) if present, which allows arbitrary command execution from untrusted project contents. In a caption-rendering skill, this is broader than the stated purpose and dangerous because any attacker who can influence the project directory can run arbitrary OS commands with the privileges of the render process.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The header comment claims the workflow runs locally with no external dependency concerns, but the actual WhisperX path uses `uvx` to resolve and install a Python package at runtime. That creates a supply-chain and integrity risk because execution depends on code fetched dynamically from package infrastructure rather than only preinstalled local components.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The script invokes `uvx --from whisperx==... whisperx ...`, which can download and execute package-managed code at runtime. Even with version pinning, this expands the attack surface to package registry compromise, dependency confusion, or unexpected transitive dependency changes, which is especially risky in an automation context that users expect to be local-only.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The `when` field is written as a broad, subjective trigger (`digital / hacker / AI / dystopia content; anything that wants the captions to feel like a corrupted feed`), which can cause the style to be selected for many loosely related inputs. In a routing system that chooses caption identities by descriptive matching, this ambiguity increases the chance of unintended invocation and inconsistent behavior, though the direct security impact is limited because this JSON is declarative styling data rather than executable logic.

Missing User Warnings

Low
Confidence
87% confidence
Finding
The page silently loads a remote script without disclosure, which can violate operator expectations for an offline/local workflow and create untracked network egress. In this skill context, that matters because video-processing workflows may run on sensitive media in isolated or privacy-conscious environments, so hidden outbound dependencies increase operational and trust risk.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/make-theme.test.mjs:71

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/transcribe.cjs:205