T09 · Insecure Skill Coding Practices
Warning
- Location
- lib/search.js:137
- Finding
- Shell Command Injection Through Unquoted Indexed Documentation Paths## Vulnerability Details **File Location**: `lib/search.js`, lines 137-138 **Vulnerability Type**: Shell command injection through unsafe command generation **Risk Level**: Medium **Vulnerable Code**: ```javascript lines.push(`💡 Read with:`); lines.push(` cat ${best.path}`); ``` ### Technical Analysis The application interpolates `best.path` directly into a suggested shell command without quoting, escaping, or using the `--` option delimiter. This path originates from Markdown filenames discovered recursively during indexing and stored in the SQLite database. Although the application does not execute the generated command itself, its documented workflow directs an AI agent or user to execute the returned `cat` command. A filename containing shell metacharacters such as command substitution, semicolons, redirection operators, or spaces can alter the command's meaning when the suggestion is copied into a shell. Exploitation requires an attacker to control a Markdown filename in the indexed documentation tree or tamper with the local index. For example, a path containing shell command-substitution syntax could cause the shell to execute the embedded command when the generated output is followed. ### Attack Path 1. An attacker gains the ability to add or rename a Markdown file under the configured documentation directory, which defaults to `/usr/lib/node_modules/openclaw/docs`. 2. The attacker gives the file a name containing shell metacharacters or command-substitution syntax. 3. The victim runs `node scripts/docs-index.js rebuild`, causing the path to be stored in the documentation index. 4. A search returns the attacker-controlled file as the best result. 5. The application prints the path as an unquoted `cat` command. 6. A user or AI agent follows the documented workflow and executes the generated command in a shell. 7. The injected shell syntax runs with the privileges of that user or agent process. ### Impac ...[truncated 612 chars]
- Remediation
- ## Remediation Suggestions - Do not format search results as executable shell commands. Return the path as plain data and instruct callers to use a trusted filesystem-reading API or tool. - If a shell command must be displayed, apply robust POSIX shell quoting to the complete path and use an option delimiter: ```text cat -- 'properly escaped path' ``` - Never implement escaping by only replacing spaces; correctly escape embedded single quotes and all other shell-significant characters. - Consider validating indexed paths with `fs.realpathSync()` and confirming that they remain inside the configured documentation root. - Treat index contents as untrusted when loading paths from SQLite, since a local attacker could tamper with the index independently of the source documents.
