T09 · Insecure Skill Coding Practices
- Location
bin/obsidian-headless.sh:445- Finding
Command Execution Through Ripgrep Option Injection
- Content
View full analysis
/dev/null; then results=$(rg -i "$keyword" "$VAULT_PATH" -t md -l 2>/dev/null) else results=$(grep -ril "$keyword" "$VAULT_PATH" --include="*.md" 2>/dev/null) fi ``` ```bash # Fuzzy-search content local content_results if command -v rg &>/dev/null; then content_results=$(rg -i "$keyword" "$VAULT_PATH" -t md -l 2>/dev/null | head -10) else content_results=$(grep -ril "$keyword" "$VAULT_PATH" --include="*.md" 2>/dev/null | head -10) fi ``` ### Technical Analysis The user-controlled `keyword` is passed to `rg` before an option terminator. Shell quoting prevents ordinary shell metacharacter expansion, but it does not stop the receiving program from interpreting an argument beginning with `-` as a command-line option. Consequently, a search keyword beginning with a ripgrep option is processed as configuration rather than as the intended search pattern. Ripgrep supports security-sensitive options, including preprocessing options such as `--pre=COMMAND`. A crafted keyword can therefore cause ripgrep to start an attacker-selected local process. The same structural defect exists in the `grep` fallback because the keyword is also passed before `--`. Although the reviewed code establishes a direct command-execution path through ripgrep, no equivalent command-execution option was confirmed for the fallback implementation. Both `search_content` and `fuzzy_search` are affected. These functions receive their keywords from natural-language commands without rejecting leading hyphens. ### Attack Path 1. An attacker gains the ability to supply a natural-language search instruction to the Skill. 2. The attacker uses the content-search or fuzzy-search command and supplies a keyword ...[truncated 1604 chars]- Remediation
View remediation
/dev/null; then results=$(rg -i -t md -l -- "$keyword" "$VAULT_PATH" 2>/dev/null) else results=$(grep -ril --include="*.md" -- "$keyword" "$VAULT_PATH" 2>/dev/null) fi ``` Apply the same correction to fuzzy search: ```bash if command -v rg &>/dev/null; then content_results=$(rg -i -t md -l -- "$keyword" "$VAULT_PATH" 2>/dev/null | head -10) else content_results=$(grep -ril --include="*.md" -- "$keyword" "$VAULT_PATH" 2>/dev/null | head -10) fi ``` Additional hardening should include: 1. Add regression tests using keywords such as `-n`, `--help`, `--pre=...`, and `--` to verify that they are treated only as literal patterns. 2. Invoke dependencies through a controlled `PATH` in security-sensitive or automated environments. 3. Run the Skill under a dedicated, least-privileged account with access limited to the intended vault. 4. Consider using ripgrep's fixed-string mode (`-F`) if regular-expression searches are not required: ```bash rg -i -F -t md -l -- "$keyword" "$VAULT_PATH" ``` 5. Review all external command invocations and consistently place `--` before untrusted positional arguments. ]]>
