T09 · Insecure Skill Coding Practices
- Location
index.js:31- Finding
Shell Command Injection Through Unquoted CDP Arguments
- Content
View full analysis
Vulnerability Details
File Location:
index.js, lines 31-36
Vulnerability Type: OS command injection caused by unsafe shell command construction
Risk Level: HighVulnerable Code
javascript const cmd = ['node', CDP_SCRIPT, command, ...args]; const output = execSync(cmd.join(' '), { cwd: CDP_DIR, encoding: 'utf8', timeout: 30000 });Technical Analysis
The
cdp()function combines an executable, script path, command, and caller-supplied arguments into a single string usingcmd.join(' '). It then passes that string toexecSync(), which evaluates the string through a system shell.Arguments reaching this sink include
targetId,selector,text,url, and JavaScriptexpressionvalues accepted by exported functions such asclick(),type(),navigate(), andevaluate(). These values are neither validated nor safely separated from the command line.Consequently, shell metacharacters such as semicolons, command substitutions, redirections, and pipelines can terminate or alter the intended Node.js command. The construction also handles legitimate arguments containing spaces or quotation marks incorrectly.
Attack Path
- An attacker influences an argument passed to an exported skill operation, such as the URL supplied to
navigate()or the expression supplied toevaluate(). - The exported operation forwards that value to
cdp()as an element ofargs. cdp()concatenates the argument into a shell command without quoting or escaping.execSync()invokes the system shell to interpret the resulting command string.- Shell syntax embedded in the attacker-controlled argument executes an additional operating-system command.
For example, an input structurally equivalent to:
javascript navigate('abc123', 'https://example.invalid; id > /tmp/cdp-command-output')causes the semicolon and following command to be interpreted by the shell rath ...[truncated 846 chars]
- An attacker influences an argument passed to an exported skill operation, such as the URL supplied to
- Remediation
View remediation
Remediation Suggestions
Avoid invoking a shell for argument-based process execution. Replace
execSync()withexecFileSync()orspawnSync()and pass each argument separately:javascript const { execFileSync } = require('child_process'); const output = execFileSync( process.execPath, [CDP_SCRIPT, command, ...args], { cwd: CDP_DIR, encoding: 'utf8', timeout: 30000, shell: false } );Additional hardening should include:
- Restrict
commandto an explicit allowlist such aslist,shot,snap,html,click,type,nav,eval, andnet. - Validate target identifiers against the exact format emitted by Chrome CDP.
- Apply reasonable length limits to selectors, text, URLs, and expressions to reduce denial-of-service exposure.
- Validate navigation URLs against the intended schemes and destination policy.
- Preserve arguments as discrete values; do not attempt to repair the issue solely through manual shell escaping.
- Return sanitized error details so command failures do not unnecessarily expose sensitive paths or process output.
- Add regression tests using spaces, quotation marks, semicolons, command substitutions, redirections, and newline characters.
- Restrict
