T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:35
- Finding
- Command Injection Through an Untrusted Obsidian Vault Path<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 35–38 **Vulnerability Type**: Shell command injection through unsafe path interpolation **Risk Level**: High ### Vulnerable Code ```bash # Count total files find "<YOUR_VAULT_PATH>" -type f -name "*.md" | wc -l # Count files by folder find "<YOUR_VAULT_PATH>" -type f -name "*.md" -printf "%h\n" | sort | uniq -c ``` ### Technical Analysis The skill instructs the agent to obtain a vault path from the user and insert it into shell commands. If the agent performs direct textual substitution, the path becomes part of shell syntax rather than being passed as a discrete process argument. Double quotes do not safely neutralize all shell syntax introduced before parsing. For example, a path containing a closing quote and shell separators can terminate the intended argument and append another command. Command substitutions such as `$(...)` may also execute inside double quotes if included in the generated command. The documentation provides no validation, canonicalization, argument-array execution, or shell-safe encoding requirement. Consequently, an attacker who can influence the supplied vault path may transform the intended read-only scan into arbitrary command execution. ### Attack Path 1. The user selects the scan or comparison functionality. 2. The skill asks the user to provide an Obsidian vault path. 3. An attacker supplies a path containing shell metacharacters, such as a closing quote followed by a command separator and an attacker-controlled command. 4. The agent substitutes that value directly for `<YOUR_VAULT_PATH>`. 5. The shell parses the injected content as executable syntax rather than as part of a filesystem path. 6. The injected command executes with the same operating-system identity and permissions as the agent process. A conceptual malicious value could follow this structure: ```text "; <attacker-controlled-command>; # ``` After direct substitution, the original `find ...[truncated 863 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not generate shell command strings by replacing `<YOUR_VAULT_PATH>` with user-controlled text. 2. Invoke `find` through a structured process API that accepts an executable and a separate argument array. The vault path must be supplied as one argument without shell parsing. 3. Resolve the path to a canonical absolute path and verify that it: - Exists. - Is a directory. - Falls within an explicitly authorized filesystem scope. 4. Reject null bytes and invalid path representations, but do not rely on character filtering as the primary command-injection defense. 5. Avoid `eval`, `sh -c`, `bash -c`, or equivalent mechanisms when processing the path. 6. If a shell script is unavoidable, obtain the path as already-separated input and expand a variable with strict quoting: ```bash vault_path="$1" if [[ ! -d "$vault_path" ]]; then printf 'Invalid vault directory\n' >&2 exit 1 fi find "$vault_path" -type f -name '*.md' | wc -l find "$vault_path" -type f -name '*.md' -printf '%h\n' | sort | uniq -c ``` 7. Add an explicit instruction that agents must not interpolate the path into executable shell text. 8. Request user confirmation of the canonical path before scanning, especially when it points outside the expected vault location. 9. Add tests covering paths containing spaces, quotes, semicolons, dollar signs, command-substitution syntax, leading hyphens, and newline characters. ]]>
