T09 · Insecure Skill Coding Practices
- Location
references/commands.md:14- Finding
PowerShell Command Injection Through Untrusted URL Substitution
- Content
View full analysis
" ``` Equivalent command templates containing the same unsafe URL substitution pattern also appear throughout `references/commands.md` and in `SKILL.md`. ### Technical Analysis The skill instructs the agent to replace the quoted `` placeholder with a user-provided URL and execute the resulting PowerShell command. Placing an untrusted value inside a double-quoted PowerShell string does not make it safe. PowerShell evaluates subexpressions such as `$()` inside double-quoted strings. Backticks and embedded quotation marks may also change how a generated command is parsed. If the agent constructs command text by textual substitution, a URL containing PowerShell syntax can therefore cause commands to be evaluated before `yt-dlp` receives the argument. For example, a value conceptually containing: ```text https://example.invalid/video?q=$(Start-Process calc.exe) ``` would cause the `$()` expression to be evaluated when embedded directly into the documented command template. The exact payload can be replaced with file operations, process execution, credential access, or network activity. This risk applies to every documented command that places a user-controlled URL directly into executable PowerShell text. ### Attack Path 1. An attacker sends the agent a URL containing PowerShell metacharacters or a `$()` subexpression. 2. The skill recognizes the message as a download request. 3. The agent replaces `` in the documented PowerShell template with the attacker-controlled text. 4. PowerShell parses the resulting command. 5. PowerShell evaluates the injected expression before invoking `yt-dlp`. 6. Th ...[truncated 760 chars]- Remediation
View remediation
` with raw user input. - Pass the URL as a discrete process argument through a structured process API. - If PowerShell must be used, store the URL as data and invoke the process with an argument array: ```powershell $arguments = @( "-m", "yt_dlp", "-f", "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best", "--merge-output-format", "mp4", "-o", "$OUT\%(title)s.%(ext)s", "--", $UserUrl ) & $PYTHON @arguments ``` - Obtain `$UserUrl` through a data boundary rather than generating a script containing its contents. - Validate the URL with `System.Uri`, allowing only required schemes such as `https` and, if necessary, `http`. - Reject control characters, line breaks, NUL characters, and malformed absolute URLs. - Use `--` before the URL so a value beginning with a hyphen cannot be interpreted as a `yt-dlp` option. - Apply the same correction to every video, audio, playlist, subtitle, thumbnail, and metadata command template. - Run the downloader under a non-administrative account with restricted filesystem and network permissions. ]]>
