Back to skill

Security audit

vhs-recording

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says, but it asks agents to run command-bearing VHS tape files with weak safety checks and includes public upload and mutable install examples.

Install only if you intend to run VHS terminal recordings and are comfortable treating `.tape` files as executable code. Review every tape and included `Source` file before running it, avoid untrusted tapes, prefer disposable demo projects, sanitize secrets and environment output, and use `--publish` only for recordings you are willing to make public.

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)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:55
Finding

Untrusted VHS Tape Files Can Execute Arbitrary Shell Commands

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:55-63, 81-84; modules/execution.md:43-55, 84-87; modules/tape-syntax.md:61-75, 111-118, 178-183
Vulnerability Type: Execution of insufficiently validated command-bearing files
Risk Level: High

Vulnerable Code

SKILL.md:55-63:

markdown
### Phase 1: Validate Tape File

1. Confirm tape file exists at specified path
2. Read tape file contents
3. Verify required directives:
   - `Output` directive specifies GIF destination
   - At least one action command (Type, Enter, etc.)

SKILL.md:81-84:

markdown
### Phase 3: Execute Recording

```bash
vhs <tape-file.tape>
text

`modules/execution.md:43-55`:

```markdown
### Tape File Validation

Check tape file before execution:

```bash
# Verify file exists
test -f tape-file.tape && echo "Found" || echo "Missing"

# Check for Output directive
rg -q "^Output" tape-file.tape && echo "Has output" || echo "No output directive"
# fallback: grep -q "^Output" tape-file.tape

# Validate syntax (dry run)
vhs validate tape-file.tape
text

`modules/execution.md:84-87`:

```markdown
### Basic Execution

```bash
vhs tape-file.tape
text

`modules/tape-syntax.md:61-75`:

```markdown
### Type

Types text into the terminal:

```tape
Type "echo 'Hello World'"
Type@50ms "slower typing"

Enter

Sends Enter key (execute command):

tape
Enter
text

`modules/tape-syntax.md:111-118`:

```markdown
### Hide/Show

Control visibility of actions:

```tape
Hide
Type "secret setup commands"
Enter
Show
text

`modules/tape-syntax.md:178-183`:

```markdown
### Source

Include other tape files:

```tape
Source common-setup.tape
text

### Technical Analysis

VHS tape files are executable terminal automation definitions. A `Type` directive places attacker-controlled text into th
...[truncated 2380 chars]
Remediation
View remediation

Remediation Suggestions

  1. Treat every tape file as executable code rather than passive recording input.
  2. Require explicit user approval before executing tapes from external, downloaded, generated, or otherwise untrusted sources.
  3. Display all executable Type/Enter sequences to the user before execution, including actions enclosed by Hide.
  4. Resolve every Source directive and recursively review the complete inclusion graph. Reject missing files, inclusion cycles, path traversal, and references outside an approved project directory.
  5. Canonicalize and validate Output and Screenshot paths. Restrict generated files to an explicitly approved output directory.
  6. Run untrusted tapes in a disposable sandbox or container with a read-only project mount, a dedicated writable output directory, no host credentials, minimal environment variables, and network access disabled by default.
  7. Add policy checks for destructive or sensitive commands. Such checks should supplement sandboxing rather than replace it because shell syntax can bypass simple deny lists.
  8. Document that syntax validation confirms only VHS grammar and does not establish the safety of commands.
  9. Avoid exposing sensitive values in the terminal environment and use a dedicated low-privilege account for recording.

T08 · Insecure Dependencies

Warning
Location
modules/execution.md:27
Finding

Dependency Installation Uses Mutable and Unpinned Upstream Versions

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:70-76; modules/execution.md:27-39, 113-117
Vulnerability Type: Unpinned third-party dependency installation
Risk Level: Medium

Vulnerable Code

SKILL.md:70-76:

markdown
If not installed:
```bash
# Linux/WSL
go install github.com/charmbracelet/vhs@latest

# macOS
brew install charmbracelet/tap/vhs
text

`modules/execution.md:27-39`:

```markdown
### Installation

```bash
# Go (recommended)
go install github.com/charmbracelet/vhs@latest

# macOS
brew install charmbracelet/tap/vhs

# Arch Linux
yay -S vhs

# Nix
nix-env -iA nixpkgs.vhs
text

`modules/execution.md:113-117`:

```markdown
**ttyd not found**
```bash
# Install ttyd
go install github.com/aspect-build/aspect-cli/pkg/ttyd@latest
# Or via package manager
text

### Technical Analysis

The Go installation commands explicitly use `@latest`, which resolves to a mutable upstream release at installation time. The package-manager commands similarly do not identify a reviewed version or immutable artifact. The instructions also do not require checksum, signature, provenance, or source verification.

As a result, the code installed in the future can differ from the version considered during this audit. If an upstream repository, release process, package-manager account, tap, or distribution source is compromised, following these instructions could install attacker-controlled code. Unreviewed future releases can also introduce incompatible or unsafe behavior without any modification to this Skill.

This is a supply-chain weakness rather than evidence that the currently named projects are malicious.

### Attack Path

1. An attacker compromises an upstream repository, package publication account, package-manager source, or release pipeline.
2. The attacker publishes a modified release that becomes the version selected by `@latest` or by an unpinned 
...[truncated 1127 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace @latest with explicitly reviewed release versions, such as module@vX.Y.Z.
  2. Where practical, pin immutable source commit hashes or package artifact digests.
  3. Document expected SHA-256 checksums or supported signature/provenance verification procedures for downloaded artifacts.
  4. Specify tested package versions for Homebrew, Arch, and Nix installations, or provide a lock file and reproducible environment definition.
  5. Prefer official, trusted package repositories and clearly identify the expected package owner and source.
  6. Regularly review and deliberately update pinned versions rather than allowing automatic resolution to arbitrary future releases.
  7. Perform installation in a constrained environment without elevated privileges, host credentials, or unnecessary network and filesystem access.
  8. Separate installation from recording execution and obtain explicit user consent before adding third-party software.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · modules/execution.md (reported line 50)May include surrounding context.

md
# Verify file exists
test -f tape-file.tape && echo "Found" || echo "Missing"

# Check for Output directive
rg -q "^Output" tape-file.tape && echo "Has output" || echo "No output directive"
# fallback: grep -q "^Output" tape-file.tape

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · modules/execution.md (reported line 51)May include surrounding context.

md
test -f tape-file.tape && echo "Found" || echo "Missing"

# Check for Output directive
rg -q "^Output" tape-file.tape && echo "Has output" || echo "No output directive"
# fallback: grep -q "^Output" tape-file.tape

# Validate syntax (dry run)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · modules/tape-syntax.md (reported line 15)May include surrounding context.

@book-detail: Extended explanation for book chapters

text

## Output Directive

Specifies the output file path (required):

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger list contains broad generic terms such as "gif", "demo", and "tutorial", which can match many unrelated user requests and cause this skill to activate outside its intended terminal-recording context. Overly broad invocation increases the chance that the agent executes recording-oriented workflow steps, including shell command suggestions or tool use, in inappropriate contexts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The guide includes vhs tape-file.tape --publish and explicitly notes publication to vhs.charm.sh (public), but it does not warn that terminal recordings may capture sensitive commands, output, environment details, paths, or secrets and then upload them externally. In a recording/demo workflow, accidental disclosure is realistic because users often run tapes against real projects and terminals containing confidential data.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · modules/execution.md (reported line 179)May include surrounding context.

Install fonts in WSL2:

bash
sudo apt install fonts-jetbrains-mono
fc-cache -fv

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The example demonstrates hidden execution (Hide/Show) together with real shell commands that change repository state (git add ., git commit). In a skill that generates terminal recordings, users may copy or reuse examples directly; hiding setup/actions without an explicit warning increases the risk of obscuring side effects and normalizing non-transparent command execution.

Content

No source excerpt is available for this finding.