T09 · Insecure Skill Coding Practices
- Location
skill.yaml:14- Finding
OS Command Injection Through Unsanitized Git Operation Parameters
- Content
View full analysis
Vulnerability Details
File Location:
skill.yaml, lines 14-17
Vulnerability Type: OS command injection
Risk Level: HighThe affected handlers directly interpolate caller-controlled parameters into shell commands:
javascript 'create-branch': async (name) => exec(`git checkout -b ${name}`), 'merge': async (source, target) => exec(`git merge ${source} into ${target}`), 'rebase': async (branch) => exec(`git rebase ${branch}`), 'cherry-pick': async (commit) => exec(`git cherry-pick ${commit}`),Technical Analysis
The
name,source,target,branch, andcommitvalues are inserted into command strings passed toexec(). This API normally executes the supplied string through a system shell. No validation, escaping, or separation between executable arguments and shell syntax is performed.Consequently, a parameter containing shell metacharacters such as semicolons, command substitutions, pipes, or redirection operators can alter the intended command and append arbitrary shell operations. For example, a branch parameter shaped like
main; idwould result in a shell command equivalent to:bash git rebase main; idThe merge implementation has an additional correctness issue: it generates
git merge <source> into <target>, which is not valid Git merge syntax. Moreover, the dispatcher passes onlyoptions.paramsto each handler, so the declaredtargetparameter may remain undefined. These defects do not prevent injection through the interpolatedsourcevalue.Attack Path
- An attacker or untrusted caller invokes the Skill through one of its exposed Git operation triggers.
- The caller selects a parameterized operation such as
create-branch,merge,rebase, orcherry-pick. - The caller supplies an operation parameter containing shell syntax, such as
main; id. - The handler inserts that value directly into a template literal.
exec()sends th ...[truncated 777 chars]
- Remediation
View remediation
Remediation Suggestions
-
Replace shell-string
exec()calls with a non-shell process API such asexecFile()orspawn(), passing every Git argument as a separate array element:javascript execFile('git', ['checkout', '-b', name]); execFile('git', ['rebase', branch]); execFile('git', ['cherry-pick', commit]); -
Validate branch and reference names before execution. Prefer invoking
git check-ref-format --branchwithout a shell, or enforce an equivalently strict validation policy. -
Restrict cherry-pick input to an expected Git object identifier or validated revision expression. If only commit hashes are required, use a strict hexadecimal length policy and verify the object through Git.
-
Reject control characters, whitespace where unnecessary, shell metacharacters, option-like values beginning with
-, and unexpected parameter types. Do not rely on shell escaping as the primary defense. -
Redesign the merge handler and its input contract. A standard merge normally requires only the source reference in the currently checked-out target branch. If a target branch is supported, check it out separately using argument-array execution and then merge the validated source.
-
Add tests using hostile inputs containing semicolons, command substitution, pipes, redirections, newlines, and leading hyphens. Verify that such input is rejected and cannot create files or execute secondary commands.
-
Run the Skill with the least-privileged operating-system account required for repository access to reduce the impact of any future command-execution defect.
-
