T09 · Insecure Skill Coding Practices
Error
- Location
- INTEGRATION.md:14
- Finding
- Shell Command Injection Through Untrusted Job Description Interpolation## Vulnerability Details **File Location**: `INTEGRATION.md:14` **Vulnerability Type**: Shell command injection **Risk Level**: High **Vulnerable Code:** ```markdown 1. **🔍 Analyze First (Don't just reply):** * Run `node freelance-pilot/index.js scan-job "[job text]"` to check for red flags. * If Risk Level is **HIGH**, warn me immediately. Start your reply with: "⚠️ **Caution: High Risk Job Detected**". ``` ### Technical Analysis The integration guide instructs an agent to substitute an untrusted job description directly into a shell command. Job descriptions may be controlled by arbitrary users or third-party job-post authors. Wrapping the input in double quotes does not provide safe shell escaping. Shell constructs such as `$(command)` and backtick command substitution can still be evaluated inside double quotes. An attacker can also use embedded quotes to terminate the intended argument and introduce additional shell syntax. Although `index.js` only treats the resulting values as command-line arguments, injection occurs before Node.js starts if the documented command is executed through a shell. The vulnerability therefore originates in the unsafe invocation pattern documented by the skill. ### Attack Path 1. An attacker creates a job description containing shell syntax, such as `$(attacker_command)`, backticks, or an embedded quote followed by command separators. 2. A user supplies that description to an agent configured with the documented FreelancePilot protocol. 3. Following `INTEGRATION.md`, the agent interpolates the complete text into: ```sh node freelance-pilot/index.js scan-job "[job text]" ``` 4. The agent executes the generated command through a shell. 5. The shell evaluates the injected syntax before or while launching Node.js. 6. The injected command runs with the operating-system privileges and environment available to the agent process. ### Impact Assessment Succ ...[truncated 566 chars]
- Remediation
- ## Remediation Suggestions - Do not interpolate job descriptions or other untrusted content into shell command strings. - Invoke Node.js with an argument-array API that bypasses shell parsing, such as `spawn`, `execFile`, or an equivalent tool interface configured with `shell: false`. - Prefer passing the job description through standard input or a structured JSON input channel, especially because descriptions can be long and contain arbitrary characters. - If a command-line argument is unavoidable, construct the process invocation directly rather than attempting manual shell escaping. - Update the integration instructions to explicitly prohibit executing job-post content as shell syntax. - A safe Node.js invocation pattern is: ```javascript const { spawn } = require('child_process'); const child = spawn( process.execPath, ['freelance-pilot/index.js', 'scan-job', jobText], { shell: false, stdio: ['ignore', 'pipe', 'pipe'] } ); ``` - Treat all job descriptions as attacker-controlled input and run the skill with least privilege in an isolated workspace without unnecessary credentials.
