T09 · Insecure Skill Coding Practices
- Location
scripts/generate-weekly.mjs:144- Finding
Shell Command Injection Through Git Collection Arguments
- Content
View full analysis
Vulnerability Details
File Location:
scripts/generate-weekly.mjs:144-147
Vulnerability Type: OS command injection
Risk Level: HighVulnerable Code:
js const output = execSync( `git -C "${gitPath}" log --since="${since} 00:00:00" --until="${until} 23:59:59" --format="${format}" --date=short`, { encoding: 'utf8', cwd: gitPath } );Technical Analysis
The values supplied through the
--git,--start, and--endcommand-line options are inserted directly into a command string passed toexecSync(). BecauseexecSync()executes the string through a system shell, shell metacharacters and command substitutions within these values can be interpreted as executable syntax.Enclosing the values in double quotes does not provide sufficient protection. On common shells, constructs such as command substitution remain active inside double-quoted strings. The script performs no strict date validation and does not safely separate executable arguments from the command itself.
Attack Path
- An attacker persuades a user or automated process to invoke the generator with a crafted
--start,--end, or--gitargument. parseArgs()stores the supplied value without validating it against an allowlist or strict format.generateReport()passes the values tocollectGitCommits().collectGitCommits()interpolates the values into a shell command.execSync()invokes the system shell.- The injected shell expression executes with the privileges of the user running the generator.
Exploitation requires the Git collection path to be reached, including a supplied
--gitpath that passes the existence check.Impact Assessment
Successful exploitation permits arbitrary command execution under the account that invokes the Skill. An attacker could read or modify files accessible to that account, execute local programs, access available environment data, alter repositories, ...[truncated 208 chars]
- An attacker persuades a user or automated process to invoke the generator with a crafted
- Remediation
View remediation
Remediation Suggestions
Replace shell-string execution with an API that passes arguments separately, such as
execFileSync()orspawnSync():js const output = execFileSync( 'git', [ '-C', gitPath, 'log', `--since=${since} 00:00:00`, `--until=${until} 23:59:59`, `--format=${format}`, '--date=short' ], { encoding: 'utf8', cwd: gitPath, shell: false } );Additionally:
- Validate
--startand--endagainst a strictYYYY-MM-DDformat and verify that they represent valid dates. - Resolve and validate
--gitas an existing directory before use. - Reject missing option values and unexpected command-line arguments.
- Avoid enabling shell execution for any subprocess call involving user-controlled data.
- Add regression tests using shell metacharacters and command-substitution syntax to confirm that arguments are treated only as data.
- Validate
