T09 · Insecure Skill Coding Practices
- Location
scripts/prepare-diff.sh:10- Finding
Git Option Injection Through the Unvalidated Diff Range Argument
- Content
View full analysis
Vulnerability Details
File Location:
scripts/prepare-diff.sh, lines 10-11 and 34-40
Vulnerability Type: Git argument and option injection
Risk Level: HighVulnerable Code
bash REPO="${1:-.}" RANGE="${2:-}" cd "$REPO" # ... if [ -n "$RANGE" ]; then git diff --stat "$RANGE" 2>/dev/null echo "" echo "=== DIFF ===" git diff "$RANGE" 2>/dev/nullTechnical Analysis
The script treats its second argument as a Git revision range but passes it directly to
git diffwithout validating its syntax or preventing it from being interpreted as a command-line option.Shell quoting prevents shell metacharacter injection, but it does not prevent option injection into Git. For example, an argument beginning with
-, such as--output=/attacker/chosen/path, is processed by Git as an option rather than as a revision range. The twogit diffinvocations can consequently create or overwrite the specified file using the permissions of the account running the Skill.Other accepted Git options could alter diff processing. In environments containing attacker-controlled Git configuration or configured external diff helpers, options that enable external diff behavior may also expand the impact. This is not direct shell command injection by itself, but it exposes unsafe Git functionality through an input documented as a revision range.
Attack Path
-
An attacker controls or influences the revision-range value supplied to the Skill, such as through a review request or copied command.
-
The attacker supplies a value beginning with a Git option, for example:
text --output=/path/writable/by/the-victim/target-file -
The Skill invokes
scripts/prepare-diff.shwith that value as its second argument. -
The script passes the argument directly to both
git diffcommands. -
Git interprets the argument as an option and writes diff output to the selected path.
...[truncated 974 chars]
-
- Remediation
View remediation
Remediation Suggestions
-
Reject any range argument beginning with
-before invoking Git:bash if [[ -n "$RANGE" && "$RANGE" == -* ]]; then echo "Error: diff range must not begin with '-'" >&2 exit 2 fi -
Validate that the input contains only supported revision syntax. Prefer a narrow policy, such as a single commit or a two-endpoint
A..BorA...Brange, rather than accepting arbitrarygit diffsyntax. -
Resolve each revision endpoint with
git rev-parse --verifybefore passing it togit diff. On supported Git versions, use--end-of-optionswhile resolving revisions:bash git rev-parse --verify --end-of-options "${REV}^{commit}" -
After validation, terminate revision processing with
--when invoking the diff so subsequent values cannot be interpreted as options or ambiguous path specifications:bash git diff --stat "$VALIDATED_RANGE" -- git diff "$VALIDATED_RANGE" -- -
Do not attempt to fix this solely through shell quoting; quoting addresses shell parsing but not Git's own option parser.
-
Run reviews of untrusted repositories in a sandbox with limited filesystem access, no sensitive credentials, and external Git diff execution disabled.
-
