T09 · Insecure Skill Coding Practices
- Location
lib/validate.js:146- Finding
OS Command Injection Through User-Controlled Validation Path
- Content
View full analysis
Vulnerability Details
File Location:
lib/validate.js:146-149
Vulnerability Type: OS command injection
Risk Level: HighVulnerable Code:
js const output = execSync( `bash "${enforcerScript}" "${targetPath}" current`, { encoding: 'utf8' } ).trim();Technical Analysis
targetPathis obtained from the command-line arguments and interpolated directly into a command executed by a shell. Although the value is surrounded by double quotes, shell command substitution constructs such as$(command)and backticks are still evaluated inside double-quoted strings. Embedded quotation marks may also terminate the intended argument and introduce additional shell syntax.The application does not validate or safely encode
targetPathbefore passing it toexecSync(). Consequently, path validation itself becomes a command-execution primitive.Attack Path
- An attacker supplies a crafted target path to
lib/validate.jsor causes another component to callvalidateWithEnforcer()with attacker-controlled input. - The crafted value contains shell syntax, such as command substitution.
validateWithEnforcer()concatenates the value into the shell command.execSync()invokes the shell, which evaluates the injected syntax before running the enforcer script.- The injected command executes under the identity and privileges of the Node.js process.
Impact Assessment
Successful exploitation permits arbitrary local command execution with all privileges available to the Agent or user running the skill. An attacker could read or modify accessible files, obtain locally available secrets, alter project contents, invoke other installed programs, or perform network operations where permitted.
The vulnerability does not independently escalate operating-system privileges, but its scope includes all resources accessible to the compromised process.
- An attacker supplies a crafted target path to
- Remediation
View remediation
Remediation Suggestions
Do not construct a shell command from
targetPath. Invoke the enforcer as an executable with an argument array and disable shell processing:js const { spawnSync } = require('child_process'); const result = spawnSync( enforcerScript, [targetPath, 'current'], { encoding: 'utf8', shell: false } ); if (result.error) { throw result.error; } if (result.status !== 0) { throw new Error(result.stderr || `Enforcer exited with status ${result.status}`); } const output = result.stdout.trim();Alternatively, use
execFileSync()with an argument array. Validate thattargetPathis a string, reject NUL and control characters, and resolve and canonicalize it before boundary enforcement. Do not attempt to fix the issue solely through shell escaping.
