Back to skill

Security audit

Loom Vision

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to do what it claims, but it can automatically download Loom videos and keep local copies, transcripts, and frames while relying on an unpinned downloader dependency.

Review before installing. Use it only for Looms you are comfortable downloading locally, set a private OUTPUT_ROOT when processing sensitive recordings, delete generated video/transcript/frame files after use, and prefer a pinned/reviewed loom-dl version. The artifacts do not show malicious behavior, but the current scoping and retention controls deserve user attention.

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 (3)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:17
Finding
Unpinned Third-Party Executable Dependency<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:17-21` **Additional Location**: `README.md:33-39` **Vulnerability Type**: Supply-chain risk from an unpinned executable dependency **Risk Level**: Medium ### Vulnerable Code ```yaml - id: node-loom-dl kind: node package: loom-dl bins: [loom-dl] label: Install loom-dl (npm) ``` The installation documentation also recommends installing the package without a version constraint: ```bash npm install -g loom-dl ``` ### Technical Analysis The skill declares and executes the third-party npm package `loom-dl` without pinning an exact version or enforcing an integrity hash. Consequently, installations at different times may retrieve different package contents, and the effective executable can change after this skill has been audited. Because the package is installed globally and later invoked by `process-loom.sh`, a compromised publisher account, malicious future release, or compromised upstream distribution path could cause arbitrary package code to run with the privileges of the user performing the installation or invoking the CLI. This is a supply-chain weakness rather than evidence that the current `loom-dl` package is malicious. ### Attack Path 1. An attacker compromises the `loom-dl` npm publishing account, package repository, or release process. 2. The attacker publishes a malicious version under the legitimate package name. 3. A user or OpenClaw installation process follows the unversioned dependency declaration or runs `npm install -g loom-dl`. 4. npm installs the attacker-controlled release because no exact version or integrity value is enforced. 5. The skill invokes `loom-dl` from `process-loom.sh`. 6. The malicious dependency executes with the invoking user's privileges and can access the supplied Loom URL, inherited environment variables, and resources available to that user. ### Impact Assessment Successful exploitation could provide arbitrary code execution with the privi ...[truncated 351 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `loom-dl` to an exact, reviewed version rather than accepting the latest release. 2. Use a project-local dependency with a committed lockfile instead of recommending a global npm installation. 3. Enforce package integrity through npm lockfile integrity values or an equivalent verified artifact hash. 4. Document the expected package publisher, source repository, and reviewed version. 5. Run the downloader with the minimum necessary filesystem and network permissions, preferably in a sandbox. 6. Establish a dependency-update process that requires source review and renewed integrity verification before changing the pinned version. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
process-loom.sh:58
Finding
Insufficient Validation of the Downloader URL<![CDATA[ ## Vulnerability Details **File Location**: `process-loom.sh:58-64` and `process-loom.sh:85` **Vulnerability Type**: Untrusted URL passed to a network-capable third-party executable **Risk Level**: Medium ### Vulnerable Code ```bash # Extract video ID from URL - Loom share URLs are .../share/<32-hex>/... VIDEO_ID=$(echo "$URL" | grep -oE '[a-f0-9]{32}' | head -1) if [[ -z "$VIDEO_ID" ]]; then echo "ERROR: Could not extract a 32-hex video ID from URL: $URL" >&2 echo " Expected format: https://www.loom.com/share/<32-hex-id>/..." >&2 exit 1 fi ``` The superficially validated value is later passed unchanged to the downloader: ```bash loom-dl --url "$URL" --out "$OUTPUT_DIR/video.mp4" --transcript >&2 ``` ### Technical Analysis The validation only checks whether the supplied string contains a lowercase 32-character hexadecimal substring. It does not parse the value as a URL or enforce: - The `https` scheme. - An approved Loom hostname. - The expected `/share/<video-id>` path. - The absence of embedded credentials or unexpected ports. - An exact relationship between the extracted identifier and the URL path. For example, an attacker-controlled URL containing an arbitrary 32-character hexadecimal path component passes validation even if its hostname is unrelated to Loom. The entire original URL is then supplied to the network-capable `loom-dl` executable. The exact request behavior and supported schemes depend on `loom-dl`; however, the script itself does not enforce its documented Loom-only trust boundary. This can expose the runtime to unintended outbound requests and downloader-specific parsing behavior. ### Attack Path 1. An attacker supplies a URL such as: `https://attacker.example/0123456789abcdef0123456789abcdef` 2. The regular expression finds the 32-character hexadecimal substring. 3. The script derives an output directory from that substring and accepts the input. 4. The original attacker-controlled URL is passed unchanged ...[truncated 959 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse the input with a URL parser rather than validating it with a substring regular expression. 2. Require the `https` scheme. 3. Allow only explicitly approved Loom hostnames, such as `www.loom.com`, after canonicalizing the hostname. 4. Require an exact path pattern such as `/share/<32-lowercase-hex-id>` and extract the identifier only from that path component. 5. Reject embedded credentials, unexpected ports, malformed encodings, backslashes, and ambiguous hostnames. 6. Review and restrict redirect handling. Every redirect destination should be revalidated against the same hostname and scheme policy. 7. Where possible, run the downloader with outbound network access restricted to required Loom endpoints. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
process-loom.sh:39
Finding
Predictable Shared Temporary Storage and Unsafe Output Reuse<![CDATA[ ## Vulnerability Details **File Location**: `process-loom.sh:39` and `process-loom.sh:66-67` **Additional Locations**: `process-loom.sh:111-113` and `process-loom.sh:245-247` **Vulnerability Type**: Unsafe temporary-directory handling, symlink exposure, and plaintext sensitive-data retention **Risk Level**: Medium ### Vulnerable Code ```bash OUTPUT_ROOT="${OUTPUT_ROOT:-${TMPDIR:-/tmp}/loom-vision}" ``` ```bash OUTPUT_DIR="$OUTPUT_ROOT/loom-$VIDEO_ID" mkdir -p "$OUTPUT_DIR" ``` Files are then copied or overwritten in that predictable directory: ```bash # Keep the raw JSON under a predictable name alongside the converted files. if [[ "$TRANSCRIPT_JSON" != "$OUTPUT_DIR/transcript.json" ]]; then cp -f "$TRANSCRIPT_JSON" "$OUTPUT_DIR/transcript.json" fi ``` ```bash ffmpeg -y -i "$OUTPUT_DIR/video.mp4" \ -vf "fps=1/${FRAME_INTERVAL_SECONDS},scale=${FRAME_MAX_WIDTH_PX}:-1" \ -q:v "$FRAME_QUALITY" \ "$OUTPUT_DIR/frame_%03d.jpg" 2>/dev/null ``` ### Technical Analysis The default output root is a predictable path under the system temporary directory, and each video uses a deterministic directory based on its public video identifier. The script uses `mkdir -p` rather than creating a unique directory atomically and does not: - Set a restrictive `umask`. - Verify ownership and permissions of existing directories. - Reject symbolic links in the output path. - Ensure that output files are newly created regular files. - Remove stale frames before reprocessing. - Automatically remove downloaded videos and transcripts after use. The generated video, transcript, and screenshots may contain source code, internal UI states, personal information, access details displayed on screen, or confidential business discussions. Their effective permissions depend on the invoking process's umask; common defaults can make newly created files readable by other local users. If an attacker can prepare a writable output hierarchy, replace a configured output root, or ...[truncated 1897 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set `umask 077` before creating any output directory or file. 2. Create a private, unique directory atomically with `mktemp -d`, for example beneath a trusted base directory. 3. If deterministic directories are required, create them with restrictive permissions and verify that they are owned by the current user, are not symbolic links, and are not writable by other users. 4. Open output files using no-follow and exclusive-creation semantics where supported. 5. Reject symbolic links and unexpected file types before overwriting existing paths. 6. Remove existing `frame_*.jpg` files safely before reprocessing, or use a unique directory for every run. 7. Provide a documented retention policy and an option to delete the original video, transcript, and frames after analysis. 8. Avoid trusting a user-controlled `TMPDIR` or `OUTPUT_ROOT` without canonicalization and ownership checks. 9. Consider encrypting retained output where Loom content may contain confidential information. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The README explains that the skill downloads the source video, transcript, and sampled frames, but it does not warn users that these artifacts are stored locally under a temporary output directory. Because Loom videos often contain sensitive code, credentials, internal UI, or user data, omission of this disclosure increases the risk of unintentional retention and exposure of confidential material.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The README states the skill triggers automatically when a Loom URL is pasted or when the user asks about Loom video content, which is broad enough to cause unintended activation in normal conversation. For a skill that downloads remote content and stores video, transcript, and extracted frames locally, accidental invocation can lead to unnecessary data collection and processing of potentially sensitive recordings.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The trigger conditions are broad enough to auto-invoke on ordinary Loom-related requests, including cases where a user may only want discussion of a video rather than local processing. Because this skill downloads the video and writes transcripts and sampled frames to disk, over-broad triggering can cause unnecessary collection and retention of potentially sensitive audiovisual content without clear user awareness or consent.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill documentation tells the agent to run a processor that downloads the Loom video and persists the original video, transcript, raw transcript JSON, and extracted frames, but it does not include an explicit warning to the user that this local storage will occur. This creates a privacy and data-handling risk, especially for Loom videos that may contain proprietary code, credentials, internal dashboards, or other sensitive visual information.

Static analysis

No suspicious patterns detected.