T09 · Insecure Skill Coding Practices
- Location
INTEGRATION.md:14- Finding
Shell Command Injection Through Untrusted Job Description Interpolation
- Content
View full analysis
Vulnerability Details
File Location:
INTEGRATION.md:14
Vulnerability Type: Shell command injection
Risk Level: HighVulnerable 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.jsonly 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
- An attacker creates a job description containing shell syntax, such as
$(attacker_command), backticks, or an embedded quote followed by command separators. - A user supplies that description to an agent configured with the documented FreelancePilot protocol.
- Following
INTEGRATION.md, the agent interpolates the complete text into:sh node freelance-pilot/index.js scan-job "[job text]" - The agent executes the generated command through a shell.
- The shell evaluates the injected syntax before or while launching Node.js.
- The injected command runs with the operating-system privileges and environment available to the agent process.
Impact Assessment
Succ ...[truncated 566 chars]
- An attacker creates a job description containing shell syntax, such as
- Remediation
View 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 withshell: 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.
