T09 · Insecure Skill Coding Practices
- Location
scripts/git_extras.sh:56- Finding
Unsafe Processing of Attacker-Controlled Git Filenames
- Content
View full analysis
Vulnerability Details
File Location:
scripts/git_extras.sh, line 56
Vulnerability Type: Option injection and unsafe filename parsing
Risk Level: MediumVulnerable Code
bash echo " Lines of code: $(git ls-files 2>/dev/null | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}')"Technical Analysis
The
statscommand obtains tracked filenames fromgit ls-filesand passes them toxargs wc -l. Repository filenames are attacker-controlled when the skill is run against an untrusted repository.The pipeline has two security defects:
- It uses newline-delimited output instead of the NUL-delimited interfaces provided by
git ls-files -zandxargs -0. Filenames containing spaces, quotes, backslashes, or newlines can therefore be split or interpreted incorrectly. - It does not place the
--end-of-options marker before filenames. A tracked filename beginning with-may consequently be interpreted as awcoption rather than as a path.
On implementations of
wcsupporting file-list options, a specially named tracked file such as--files0-from=payloadcan instructwcto obtain additional paths from an attacker-prepared repository file. This may cause files outside the repository to be opened and counted.There is no shell-command substitution or direct arbitrary command execution through this line because
xargsinvokeswcdirectly. The demonstrated risk is argument/option injection, unintended local-file access, malformed processing, and denial of service.Attack Path
- An attacker creates or supplies an untrusted Git repository.
- The attacker commits a specially named file whose name is interpreted by
wcas an option. - Where supported, the attacker also commits a payload file containing references to local paths that may exist on the victim's system.
- A victim or automated agent runs
scripts/git_extras.sh statsinside that repository. git ls-filesemits the attacker-controlled filenames.
...[truncated 1027 chars]
- It uses newline-delimited output instead of the NUL-delimited interfaces provided by
- Remediation
View remediation
Remediation Suggestions
Use NUL-delimited filename handling and explicitly terminate option parsing:
bash echo " Lines of code: $(git ls-files -z 2>/dev/null | xargs -0 -r wc -l -- 2>/dev/null | tail -1 | awk '{print $1}')"Additional hardening measures should include:
- Verify that the deployed
wcimplementation honors--before relying on this construction. - Prefer processing each NUL-delimited path through controlled logic if cross-platform behavior is required.
- Reject paths outside the intended repository worktree after canonicalization.
- Test the command with filenames containing spaces, quotes, newlines, leading hyphens, and option-like strings.
- Consider implementing line counting in a language or API that opens filenames as data rather than converting them into command-line arguments.
- Verify that the deployed
