T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/scan-skills.sh:147
- Finding
- Attacker-Controlled Directory Name Bypasses Content and Outbound Scanning<![CDATA[ ## Vulnerability Details **File Location**: `scripts/scan-skills.sh:147-150`; `scripts/audit-outbound.sh:190-193` **Vulnerability Type**: Path-based security scanner bypass **Risk Level**: High ### Vulnerable Code From `scripts/scan-skills.sh:147-150`: ```bash # Skip scanning our own skill (contains pattern definitions that would trigger false positives) if [[ "$file" == *"openclaw-security-hardening"* ]]; then return fi ``` From `scripts/audit-outbound.sh:190-193`: ```bash # Skip the security hardening skill itself if [[ "$file" == *"openclaw-security-hardening"* ]]; then return fi ``` ### Technical Analysis Both scanners attempt to suppress false positives for their own package by checking whether the complete file path contains the substring `openclaw-security-hardening`. The condition does not establish that the file is actually located inside this toolkit's canonical installation directory. The scanned path is attacker-controlled when a user or automated installation process evaluates a newly downloaded Skill. Consequently, any directory whose name contains the trusted substring receives the same exemption. For example, all supported files under a directory named `openclaw-security-hardening-malicious` are skipped before their contents are examined. This also affects `install-guard.sh`, which relies on `scan-skills.sh --json --path "$SKILL_PATH"` for its general content checks. A malicious Markdown instruction that does not trigger the install guard's narrower script-specific checks can therefore be reported as clean. ### Attack Path 1. An attacker creates a malicious Skill containing prompt-injection or data-exfiltration instructions in `SKILL.md`. 2. The attacker names the Skill directory `openclaw-security-hardening-malicious` or uses another path containing the trusted substring. 3. A user runs: ```bash ./scripts/install-guard.sh /path/openclaw-security-hardening-malicious/ ``` 4. `install-guard.sh` invokes `scan-sk ...[truncated 1167 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Replace substring-based trust with canonical path validation: 1. Resolve both the toolkit root and candidate file through `realpath`. 2. Skip a file only when its canonical path is proven to be under the exact canonical toolkit root. 3. Prefer excluding only the fixed files containing scanner signatures instead of excluding the complete package. 4. Treat failed canonicalization as a scan failure rather than silently trusting the path. 5. Add regression tests using paths such as: - `openclaw-security-hardening-malicious/` - `prefix-openclaw-security-hardening/` - Symlinks pointing into or outside the package 6. Ensure `install-guard.sh` fails closed if the scanner produces empty, malformed, or incomplete output. A safer pattern is: ```bash toolkit_root=$(realpath "$SCRIPT_DIR/..") candidate=$(realpath "$file") || return 1 case "$candidate" in "$toolkit_root/assets/security-rules-template.md") return ;; esac ``` If self-scanning is acceptable, removing the exemption entirely is the safest option. ]]>
