Back to skill

Security audit

Obsidian Headless

Security checks for vulnerabilities and agentic risk

Overview

This skill appears intended to manage an Obsidian vault, but unsafe search command handling and under-disclosed persistent install/config behavior make it require Review before installation.

Install only if you are comfortable with a shell script reading and modifying the configured Obsidian vault. Avoid using it with untrusted natural-language input until the rg/grep option-injection bug is fixed, prefer a dedicated test vault for tests, and review or avoid the installer’s shell profile/PATH changes and world-readable vault-path config.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
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. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (32)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 38)May include surrounding context.

md
- 📄 **多行内容** - 文件名和内容可以用换行符分隔

### 安全保障
- 🛡️ **路径遍历防护** - 阻止 `../etc/passwd` 攻击
- ✅ **删除验证** - 确保只能删除仓库内文件
- 🔒 **输入验证** - 阻止非法字符和控制字符

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 191)May include surrounding context.

md
- 📄 **多行内容** - 文件名和内容可以用换行符分隔

### 安全保障
- 🛡️ **路径遍历防护** - 阻止 `../etc/passwd` 攻击
- ✅ **删除验证** - 确保只能删除仓库内文件
- 🔒 **输入验证** - 阻止非法字符和控制字符

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 93)May include surrounding context.

md
export OBSIDIAN_VAULT=/new/path

# 方法2: 删除配置重新输入
rm ~/.config/obsidian-headless/vault-path
./obs "obs创建笔记 测试"

# 方法3: 使用修改库路径命令

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 285)May include surrounding context.

md
export OBSIDIAN_VAULT=/new/path

# 方法2: 删除配置重新输入
rm ~/.config/obsidian-headless/vault-path
./obs "obs创建笔记 测试"

# 方法3: 使用修改库路径命令

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 294)May include surrounding context.

md
export OBSIDIAN_VAULT=/new/path

# 方法2: 删除配置重新输入
rm ~/.config/obsidian-headless/vault-path
./obs "obs创建笔记 测试"

# 方法3: 使用修改库路径命令

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · USAGE.md (reported line 78)May include surrounding context.

md
export OBSIDIAN_VAULT=/new/path

# 方法2: 删除配置重新输入
rm ~/.config/obsidian-headless/vault-path
./obs "obs创建笔记 测试"

# 方法3: 使用修改库路径命令

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test.sh (reported line 88)May include surrounding context.

sh
# 清理测试笔记
echo
echo "清理测试数据..."
rm -f "$OBSIDIAN_VAULT/$TEST_NOTE.md" 2>/dev/null || true
rm -f "$OBSIDIAN_VAULT/${TEST_NOTE}.md" 2>/dev/null || true

echo

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test.sh (reported line 89)May include surrounding context.

sh
echo
echo "清理测试数据..."
rm -f "$OBSIDIAN_VAULT/$TEST_NOTE.md" 2>/dev/null || true
rm -f "$OBSIDIAN_VAULT/${TEST_NOTE}.md" 2>/dev/null || true

echo
echo "====================="

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description states that Obsidian notes are managed '通过自然语言指令' and all documented commands and examples are Chinese-only, implying a fixed language requirement. The file does not offer an opt-in language choice or explain that the skill is intentionally region-specific, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding

The skill advertises and instructs shell-based operations but does not declare any explicit tool scope or allowed-tools boundary. This increases the chance that an agent may invoke shell access more broadly than intended, reducing least-privilege protections and making any downstream command-handling bugs more dangerous.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

该技能在触发词列表中包含“笔记”,这是一个高频通用词,缺少上下文约束时容易匹配到用户普通表达,而不仅限于调用此技能。虽然文档后文推荐使用 obs 前缀,但技能描述中的显式触发词列表仍将宽泛词直接列为可触发条件,且未提供负例或排除条件。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

整个技能说明、命令词和交互示例均固定为中文,未说明是否支持其他语言,也未向用户提供语言选择或显式中文 opt-in。根据规则,未提供选择而强制特定语言/locale 的自然语言约束属于应报告的政策问题。

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 · SKILL.md (reported line 240)May include surrounding context.

  1. 安装 ripgrep:
    bash
    # Ubuntu/Debian
    sudo apt install ripgrep
    
    # macOS
    brew install ripgrep
    

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 · SKILL.md (reported line 300)May include surrounding context.

  1. 安装 ripgrep:
    bash
    # Ubuntu/Debian
    sudo apt install ripgrep
    
    # macOS
    brew install ripgrep
    

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 · USAGE.md (reported line 350)May include surrounding context.

  1. 安装 ripgrep:
    bash
    # Ubuntu/Debian
    sudo apt install ripgrep
    
    # macOS
    brew install ripgrep
    

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
76% confidence
Finding

The skill's natural-language interface is presented entirely in Chinese, with command invocations and usage patterns implicitly requiring Chinese terms such as obs创建笔记 and obs删除笔记. There is no indication that users may opt into another language or that the locale restriction is intentionally limited to a Chinese-specific deployment context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file describes a skill that creates notes and directly writes provided content into files, but it does not include a user-facing warning that the command modifies data in the configured vault. Although deletion is explicitly called out as requiring confirmation, the creation section omits similar disclosure about filesystem changes and path-based writes.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script's help text, prompts, confirmations, and operational messages are written in Chinese, and command parsing is centered on Chinese trigger phrases, with no user opt-in or locale selection. This is a natural-language policy issue because the skill imposes a specific language on all users rather than offering a language or locale choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script stores the local vault path in ~/.config/obsidian-headless/vault-path and explicitly sets mode 644, making it world-readable to other local users. This can disclose sensitive filesystem layout information, usernames, project names, or confidential vault locations, which is especially relevant on multi-user systems and shared servers where this headless tool is likely to run.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · bin/obsidian-headless.sh (reported line 102)May include surrounding context.

sh
mkdir -p "${CONFIG_DIR}"
        echo "${user_path}" > "${CONFIG_FILE}"
        # 设置配置文件权限(644: 所有者可读写,其他人只读)
        chmod 644 "${CONFIG_FILE}"
        echo >&2
        echo "✓ 已保存配置到: ${CONFIG_FILE}" >&2
        echo "下次使用会自动加载此路径" >&2

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · bin/obsidian-headless.sh (reported line 623)May include surrounding context.

sh
mkdir -p "${CONFIG_DIR}"
        echo "${user_path}" > "${CONFIG_FILE}"
        # 设置配置文件权限(644: 所有者可读写,其他人只读)
        chmod 644 "${CONFIG_FILE}"
        echo >&2
        echo "✓ 已保存配置到: ${CONFIG_FILE}" >&2
        echo "下次使用会自动加载此路径" >&2

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 · install.sh (reported line 24)May include surrounding context.

sh
else
    echo -e "${YELLOW}⚠${NC} ripgrep (rg) 未安装(推荐安装以获得更快的搜索速度)"
    echo "  安装命令:"
    echo "    Ubuntu/Debian: sudo apt install ripgrep"
    echo "    macOS: brew install ripgrep"
fi

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The installer appends an alias to the user's shell startup file automatically, changing future shell behavior without explicit consent. While not overtly malicious, persistent profile modification is security-relevant because it creates hidden execution paths and can surprise users into invoking repository-controlled code later.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script attempts to place a symlink into /usr/local/bin, affecting command resolution on the system PATH without an upfront disclosure or confirmation step. Persistent PATH changes can cause users or other scripts to execute this tool unexpectedly, which is especially sensitive for an install script run from a cloned repository.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This shell script performs file deletion in the user's Obsidian vault as part of test cleanup. Although the operations are visible in code, there is no explicit warning in comments or user-facing output before deletion that test data will be removed from the vault path.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.