You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(git-extension): avoid shell interpolation of generated commit messages
- Remove r -d '[:space:]' from commit_style parsing in auto-commit.sh:
it stripped ALL whitespace (not just leading/trailing), so
commit_style: con ventional was silently normalized to conventional
instead of being rejected as unknown (PowerShell version already
rejected it correctly).
- Add a file-based message-passing channel to both auto-commit scripts:
--message-file <path> (bash) / -MessageFile <path> (PowerShell).
Agent-generated commit messages may contain quotes, $(...), or
backticks; passing them as a shell argument risked command injection
if ever inlined into a shell command string. The new flag reads the
message from a file instead, so untrusted content never touches a
shell command line. The raw positional-argument form is kept for
backward compatibility.
- Update speckit.git.commit.md to instruct the agent to write the
generated message to a temp file (via its file-editing tool) and pass
the file path, explicitly warning against inlining the message into a
shell command string.
- Add test coverage: explicit commit_style: fixed (previously only the
absent-key default was tested), --message-file/-MessageFile success
path (including injection-shaped content), and missing-file error path,
for both bash and PowerShell suites.
Assisted-by: GitHub Copilot (model: claude-sonnet-5, autonomous)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copy file name to clipboardExpand all lines: extensions/git/commands/speckit.git.commit.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,18 +22,18 @@ This command is invoked as a hook after (or before) core commands. It:
22
22
Controlled by the `commit_style` key in `.specify/extensions/git/git-config.yml`:
23
23
24
24
-**`fixed`** (default): use the per-command `message` if configured, otherwise a generic `[Spec Kit] Auto-commit <phase> <command>` message.
25
-
-**`conventional`**: inspect the actual changes (`git diff` / `git status`) since the last commit and generate a single-line [Conventional Commit](https://www.conventionalcommits.org/) message (`type(scope): subject`, e.g. `feat: add OAuth specification` or `docs: update implementation plan`) that accurately summarizes the change. Pass this message as the script's second argument. The configured `message` values are ignored in this mode.
25
+
-**`conventional`**: inspect the actual changes (`git diff` / `git status`) since the last commit and generate a single-line [Conventional Commit](https://www.conventionalcommits.org/) message (`type(scope): subject`, e.g. `feat: add OAuth specification` or `docs: update implementation plan`) that accurately summarizes the change. Write this message to a temporary file and pass the file's path to the script (see Execution below). The configured `message` values are ignored in this mode.
26
26
27
27
## Execution
28
28
29
29
Determine the event name from the hook that triggered this command, then run the script:
Replace `<event_name>` with the actual hook event (e.g., `after_specify`, `before_plan`, `after_implement`). Only pass `<generated_message>` when `commit_style: conventional` is configured — first check `.specify/extensions/git/git-config.yml` for the value of `commit_style`:
34
+
Replace `<event_name>` with the actual hook event (e.g., `after_specify`, `before_plan`, `after_implement`). Only pass a generated message when `commit_style: conventional` is configured — first check `.specify/extensions/git/git-config.yml` for the value of `commit_style`:
35
35
36
-
- If `conventional`: inspect the diff, generate a Conventional Commit message, and pass it as the second argument.
36
+
- If `conventional`: inspect the diff and generate a Conventional Commit message. **Do not interpolate the generated message directly into a shell command string** — its content is derived from repository changes and may contain characters (quotes, `$(...)`, backticks) that a shell would execute or that would break command quoting. Instead, write the message to a temporary file using your file-editing tool (not a shell `echo`/`printf`), then pass that file's path via `--message-file <path>` (Bash) or `-MessageFile <path>` (PowerShell).
37
37
- If `fixed` or absent: run the script with just `<event_name>`; it uses the configured/static message.
_style_val=$(grep -m1 '^commit_style:'"$_config_file"2>/dev/null | sed 's/^commit_style:[[:space:]]*//'| sed 's/[[:space:]]\{1,\}#.*$//'| sed 's/[[:space:]]*$//'| sed 's/^["'\'']//'| sed 's/["'\'']*$//'| tr -d '[:space:]'| tr '[:upper:]''[:lower:]')
87
+
_style_val=$(grep -m1 '^commit_style:'"$_config_file"2>/dev/null | sed 's/^commit_style:[[:space:]]*//'| sed 's/[[:space:]]\{1,\}#.*$//'| sed 's/[[:space:]]*$//'| sed 's/^["'\'']//'| sed 's/["'\'']*$//'| tr '[:upper:]''[:lower:]')
59
88
if [ -n"$_style_val" ];then
60
89
case"$_style_val"in
61
90
fixed|conventional)
@@ -148,7 +177,7 @@ if [ "$_commit_style" = "conventional" ]; then
148
177
if [ -n"$GENERATED_MESSAGE" ];then
149
178
_commit_msg="$GENERATED_MESSAGE"
150
179
else
151
-
echo"[specify] Error: commit_style is 'conventional' but no generated commit message was supplied; aborting auto-commit (pass the generated message as arg 2, or set commit_style: fixed)">&2
180
+
echo"[specify] Error: commit_style is 'conventional' but no generated commit message was supplied; aborting auto-commit (pass --message-file <path>, or a raw message as arg 2, or set commit_style: fixed)">&2
@@ -168,7 +189,7 @@ if ($commitStyle -eq 'conventional') {
168
189
if ($GeneratedMessage) {
169
190
$commitMsg=$GeneratedMessage
170
191
} else {
171
-
Write-Warning"[specify] Error: commit_style is 'conventional' but no generated commit message was supplied; aborting auto-commit (pass the generated message as arg 2, or set commit_style: fixed)"
192
+
Write-Warning"[specify] Error: commit_style is 'conventional' but no generated commit message was supplied; aborting auto-commit (pass -MessageFile <path>, or a raw message as arg 2, or set commit_style: fixed)"
0 commit comments