Back to skill

Security audit

vhs-recorder

Security checks for vulnerabilities and agentic risk

Overview

This documentation-only skill is mostly coherent for making terminal recordings, but it includes hidden and overbroad destructive command examples that users or agents could run.

Review this skill before installing. It can be useful for VHS terminal demos, but do not copy its destructive cleanup examples as written. Run tape files only in disposable test directories or containers, pin third-party tools where possible, and replace global Docker or rm -rf cleanup commands with narrowly named demo resources.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:10
Finding
Unpinned Third-Party Dependencies May Execute Unreviewed Code<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:10`; `references/examples.md:12`; `references/examples.md:24` **Vulnerability Type**: Unpinned and mutable third-party dependencies **Risk Level**: Medium ### Vulnerable Code `SKILL.md:10`: ```markdown - `vhs` installed (`brew install vhs` / `go install github.com/charmbracelet/vhs@latest`) ``` `references/examples.md:12`: ```tape Type "npx create-app my-app" → Enter → Wait /Success/ → Sleep 2s ``` `references/examples.md:24`: ```tape Type "npm install" → Enter → Wait /added/ → Sleep 2s ``` ### Technical Analysis The documented installation and execution commands do not pin reviewed dependency versions. The `@latest` selector explicitly resolves to a mutable release, while `npx create-app` may download and execute a package selected from the configured npm registry. A bare `npm install` relies on the current package manifest and lockfile state, neither of which is defined or verified by this Skill. Consequently, the code executed when a user follows these instructions can differ from the code available when the Skill was audited. A compromised upstream release, package-name confusion, malicious registry configuration, or tampered dependency graph could introduce arbitrary installation or lifecycle code. ### Attack Path 1. An attacker compromises a referenced package, publishes a malicious version under the expected package name, or influences the package registry used by the victim. 2. The victim follows the Skill and invokes `go install ...@latest`, `npx create-app my-app`, or `npm install`. 3. The package manager retrieves an unreviewed or attacker-controlled version. 4. Compilation hooks, npm lifecycle scripts, or the downloaded executable run under the invoking user's account. 5. The malicious dependency can access files, environment variables, credentials, and network resources available to that account. ### Impact Assessment Successful exploitation could provide arbitrary code ex ...[truncated 395 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace `@latest` with an explicitly reviewed VHS version. - Document checksum or signature verification for downloaded binaries. - Pin npm package versions, for example by using an exact version rather than an unqualified package name. - Use a committed lockfile and deterministic installation commands such as `npm ci`. - Disable npm lifecycle scripts where they are unnecessary, or explicitly document why they are required. - Verify official package identities and registries before installation. - Prefer isolated, least-privileged environments such as disposable containers or virtual machines when demonstrating third-party installers. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/examples.md:30
Finding
Docker Cleanup Command Stops All Running Containers<![CDATA[ ## Vulnerability Details **File Location**: `references/examples.md:30` **Vulnerability Type**: Overbroad destructive resource operation **Risk Level**: Medium ### Vulnerable Code ```tape Hide Type "docker stop $(docker ps -q)" → Enter Show ``` ### Technical Analysis The command substitution `$(docker ps -q)` returns the identifiers of every running container visible to the active Docker daemon. Passing that complete list to `docker stop` does not restrict cleanup to the container created by the demonstration. The fact that the operation appears inside a hidden VHS section only prevents it from appearing in the recording; it does not limit or sandbox the operation. On a developer workstation, CI runner, or shared Docker host, unrelated containers can therefore be stopped. ### Attack Path 1. A host has one or more unrelated Docker containers running. 2. A user executes the supplied Docker workflow while connected to that Docker daemon. 3. `docker ps -q` enumerates all running containers visible to the user. 4. The resulting container identifiers are passed to `docker stop`. 5. Both the demonstration container and unrelated workloads are terminated. ### Impact Assessment The command can cause denial of service for all containers accessible through the active Docker context. This may interrupt development services, databases, CI jobs, or shared application workloads. It does not itself escalate privileges, but users with access to a privileged or remote Docker daemon could affect every running container exposed by that daemon. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Assign the demonstration container a unique, explicit name and stop only that container: ```tape Type "docker run -d --name vhs-demo-app -p 8080:8080 app" → Enter ... Type "docker stop vhs-demo-app && docker rm vhs-demo-app" → Enter ``` - Alternatively, capture the container ID returned by `docker run` and reuse only that identifier during cleanup. - Avoid global selectors such as `docker ps -q` in cleanup examples. - Add a precondition warning if the workflow may run against a shared or remote Docker daemon. - Prefer a dedicated Docker network, Compose project name, or label, and restrict cleanup to resources carrying that unique identifier. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (12)

Chaining Abuse

High
Category
Tool Misuse
Content
Type "npm install" → Enter → Wait /added/ → Sleep 2s
Type "npm run demo" → Enter → Wait /Complete/ → Sleep 3s
Hide
Type "cd /tmp && rm -rf repo" → Enter
Show
```
Confidence
88% confidence
Finding
The chained cleanup command `cd /tmp && rm -rf repo` combines navigation with irreversible deletion, which obscures the destructive action and makes mistakes harder to notice. Chained destructive commands in examples are risky because users may tweak or reuse them with different paths, leading to accidental data loss.

Missing User Warnings

High
Confidence
99% confidence
Finding
The Docker cleanup example uses `docker stop $(docker ps -q)`, which stops all running containers on the host, not just the demo container. In a documentation context this is dangerous because users may paste it verbatim and disrupt unrelated services, development environments, or production-like workloads on their machine.

Missing User Warnings

High
Confidence
99% confidence
Finding
The 'Error Recovery' example displays `rm -rf production-db/` as typed input before correction, normalizing an extremely destructive command without any warning. Even though it is framed as a near-miss, readers can still copy the snippet, and the dramatic presentation may encourage unsafe imitation rather than discourage it.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Error Recovery (dramatic pause + backspace)
```tape
Type "rm -rf production-db/"
Sleep 3s
Backspace 100
Type "rm -rf test-db/" → Enter → Sleep 2s
Confidence
98% confidence
Finding
`rm -rf production-db/` is a destructive command targeting a path suggestive of important data, and the example presents it directly in a tape script. In the context of a terminal recording skill, including realistic destructive parameters materially increases the chance of harmful copy-paste or adaptation into real workflows.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Type "rm -rf production-db/"
Sleep 3s
Backspace 100
Type "rm -rf test-db/" → Enter → Sleep 2s
Type "# Phew!" → Enter → Sleep 2s
```
Confidence
95% confidence
Finding
`rm -rf test-db/` is still a destructive recursive deletion command, even if aimed at a less sensitive-looking directory. Although the impact may be lower than deleting a production path, presenting it as an example still teaches and normalizes unsafe command patterns in a context that does not require them.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This example block contains hidden setup and cleanup commands, including cloning into `/tmp` and deleting a repo, without any warning that commands are executed in a shell and may alter the filesystem. Documentation for a recording tool is especially risky when commands are framed as copyable examples, because readers may assume they are harmless display-only actions.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The examples include destructive shell actions such as `rm -rf repo` and stopping containers, which are not essential to demonstrating terminal recording syntax and may be copied into real environments. Because these commands are presented as normal workflow steps with hidden execution, users may run them without appreciating the cleanup side effects.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The documentation explicitly recommends using Hide/Show for installing dependencies, cloning repositories, building, creating test files, and clearing the terminal. Those actions can modify the local system or workspace while being intentionally concealed from the recording, which reduces transparency and can enable misleading or unsafe demonstrations.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The hidden-sections guidance normalizes concealing system- and file-modifying actions without warning users that the recording may omit meaningful environmental changes. In a terminal-recording skill, this is especially risky because viewers may trust the visible transcript while missing hidden setup or cleanup that changes dependencies, repositories, or local files.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The multi-stage example performs `git add .` and `git commit -m 'fix'`, which modify repository state and can capture broad file changes. The surrounding markdown does not warn that the example changes version control history or working tree contents.

Static analysis

No suspicious patterns detected.