-
Notifications
You must be signed in to change notification settings - Fork 1
fix: generated pre-commit diagnostic executes shell substitutions in project paths #782
Copy link
Copy link
Open
Labels
area:product-bugRuntime or CLI behavior is incorrectRuntime or CLI behavior is incorrectarea:securityIntegrity, authentication, supply-chain, or secret-handling riskIntegrity, authentication, supply-chain, or secret-handling riskarea:uxMessages, output, or next actions mislead or frustrateMessages, output, or next actions mislead or frustrateimpact:user-facingCan affect an end user or repository operator directlyCan affect an end user or repository operator directlypriority:p1Highest-impact or release-blocking riskHighest-impact or release-blocking riskscope:specsync-6Applies to current SpecSync 6 behavior or release contractApplies to current SpecSync 6 behavior or release contract
Description
Activity
Metadata
Metadata
Assignees
Labels
area:product-bugRuntime or CLI behavior is incorrectRuntime or CLI behavior is incorrectarea:securityIntegrity, authentication, supply-chain, or secret-handling riskIntegrity, authentication, supply-chain, or secret-handling riskarea:uxMessages, output, or next actions mislead or frustrateMessages, output, or next actions mislead or frustrateimpact:user-facingCan affect an end user or repository operator directlyCan affect an end user or repository operator directlypriority:p1Highest-impact or release-blocking riskHighest-impact or release-blocking riskscope:specsync-6Applies to current SpecSync 6 behavior or release contractApplies to current SpecSync 6 behavior or release contract
Problem
The generated pre-commit hook can execute shell command substitutions embedded in the project directory name when
specsync checkfails. The issue was reported during PR #774 review and remains in current main after that PR merged.Confirmed source:
src/hooks.rs, main inspected atba0df69360dadd20062bcb6d2ed9557ea8964ed5:PRE_COMMIT_HOOKfailure diagnostic around line 173:echo " Run 'specsync check' to see details."pre_commit_block, around lines 267–283, globally replacesspecsync checkwith a command containingshell_single_quote(&project_root).That substitution changes both the executable command and the diagnostic. Single quotes protect the directory in the command, but have no quoting effect once inserted inside the diagnostic's existing double quotes.
$()and backticks in the directory name are therefore evaluated by the shell on the failure path.Reproduction
I reproduced this at the template/substitution level using the exact PR template, the production replacement, a fake
specsyncexecutable that exits 1, and a harmless marker-file command in the root string. The hook exited 1 and created the marker. No credentials or network access were involved.The resulting vulnerable diagnostic has this shape:
Run that line only inside a disposable temporary directory: it creates
SPECSYNC_HOOK_MARKERinstead of merely printing the project path. A directory name is data and must never become executable shell text.Impact and conditions
This requires a project-root path containing shell metacharacters and a failing check. It is not execution from ordinary spec contents or every checkout. Under those conditions, directory-name content executes with the hook user's permissions. The executable check itself being single-quoted does not protect the later diagnostic.
Suggested fix
Generate the executable command and diagnostic independently, or restrict substitution to the exact executable template line. Keep paths out of the diagnostic, or render them as safely quoted arguments to a fixed-format
printf.Add an executable generated-hook regression covering:
$()and backticks in an actual project directory name;Validation must exercise the installed/generated hook, not only assert that its text contains quote characters.
Original scoped reproduction/review: #774 (review)