Compare commits

...

1 Commits

Author SHA1 Message Date
Timmy
761ad313c7 fix(#1430): Prevent shell injection from commit messages
Some checks failed
CI / test (pull_request) Failing after 47s
CI / validate (pull_request) Failing after 40s
Review Approval Gate / verify-review (pull_request) Failing after 5s
Backticks in git commit -m messages can trigger shell expansion
during hook processing. This adds:

  - .githooks/pre-commit: warns when commit message contains
    backticks (reads COMMIT_EDITMSG, warns but does not block)
  - scripts/safe-commit.sh: safe commit wrapper using -F <file>
    instead of -m (prevents all shell expansion)
  - docs/SAFE_COMMIT_PATTERNS.md: documents safe patterns and
    what NOT to do

The repo hooks (pre-commit, stale-pr-closer) are already clean.
This is preventive hardening + documentation.

Fixes #1430
2026-04-17 01:28:44 -04:00
3 changed files with 127 additions and 1 deletions

View File

@@ -1,7 +1,8 @@
#!/usr/bin/env bash
# Pre-commit hook: enforce 10-line net addition limit
# Pre-commit hook: enforce 10-line net addition limit + sanitize commit message
# Install: git config core.hooksPath .githooks
# ── Line limit enforcement ──────────────────────────────────────
ADDITIONS=$(git diff --cached --numstat | awk '{s+=$1} END {print s+0}')
DELETIONS=$(git diff --cached --numstat | awk '{s+=$2} END {print s+0}')
NET=$((ADDITIONS - DELETIONS))
@@ -12,4 +13,19 @@ if [ "$NET" -gt 10 ]; then
exit 1
fi
# ── Commit message sanitization (#1430) ─────────────────────────
# Read the commit message from .git/COMMIT_EDITMSG
MSG_FILE="$(git rev-parse --git-dir)/COMMIT_EDITMSG"
if [ -f "$MSG_FILE" ]; then
MSG=$(cat "$MSG_FILE")
# Warn if message contains backticks (potential shell injection)
if echo "$MSG" | grep -q '`'; then
echo "⚠ WARNING: Commit message contains backticks."
echo " Backticks in 'git commit -m' can trigger shell expansion."
echo " Consider using: git commit -F <file> or ./scripts/safe-commit.sh"
echo " See: docs/SAFE_COMMIT_PATTERNS.md"
# Don't block — just warn. Blocking would be too aggressive.
fi
fi
echo "✓ Pre-commit: net $NET lines (limit: 10)"

View File

@@ -0,0 +1,69 @@
# Safe Commit Patterns
## Issue #1430
Backticks in `git commit -m` messages can trigger shell substitution
during hook processing. A commit message containing:
```
git commit -m "fix: update `connectMemPalace()` to use Fleet API"
```
may cause the shell to attempt executing `connectMemPalace()`.
## Safe Patterns
### 1. Use safe-commit.sh (recommended)
```bash
./scripts/safe-commit.sh "fix: update connectMemPalace() to use Fleet API"
```
This writes the message to a temp file and uses `git commit -F`,
which prevents shell expansion.
### 2. Use git commit -F directly
```bash
echo "fix: update \`connectMemPalace()\` to use Fleet API" > /tmp/msg.txt
git commit -F /tmp/msg.txt
```
### 3. Use single quotes (less reliable with hooks)
```bash
git commit -m 'fix: update `connectMemPalace()` to use Fleet API'
```
Single quotes prevent shell expansion in the commit command itself,
but hooks that read the message may still process backticks.
### 4. Use heredoc for multiline
```bash
git commit -F - <<'EOF'
fix: update `connectMemPalace()` to use Fleet API
The mock MCP server was overwriting the real Fleet API version.
EOF
```
## What NOT to do
```bash
# BAD — backticks trigger shell expansion
git commit -m "fix: update `connectMemPalace()` to use Fleet API"
# BAD — $(...) triggers command substitution
git commit -m "fix: update $(cat file.py) to use Fleet API"
# BAD — ! triggers history expansion
git commit -m "fix: this is not a joke! seriously"
```
## For agents
When committing code that contains backticks or special characters:
1. Always use `git commit -F <file>` or `safe-commit.sh`
2. Never interpolate user content into `-m` strings
3. Escape or remove backticks from commit messages when possible

41
scripts/safe-commit.sh Executable file
View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# ═══════════════════════════════════════════════════════════════
# safe-commit.sh — Commit with message from file (prevents shell injection)
#
# Issue #1430: Backticks in commit messages can trigger shell
# substitution during git hook processing. Using -F <file> instead
# of -m prevents this.
#
# Usage:
# ./scripts/safe-commit.sh "my commit message"
# ./scripts/safe-commit.sh -F message.txt
# echo "message" | ./scripts/safe-commit.sh --stdin
# ═══════════════════════════════════════════════════════════════
set -euo pipefail
TMPFILE=$(mktemp /tmp/commit-msg-XXXXXX)
trap "rm -f $TMPFILE" EXIT
if [ "${1:-}" = "-F" ] && [ -n "${2:-}" ]; then
# Use provided file
cp "$2" "$TMPFILE"
elif [ "${1:-}" = "--stdin" ]; then
# Read from stdin
cat > "$TMPFILE"
elif [ -n "${1:-}" ]; then
# Write argument to temp file (no shell expansion)
printf '%s' "$1" > "$TMPFILE"
else
echo "Usage: $0 <message> | $0 -F <file> | $0 --stdin"
echo ""
echo "Always uses git commit -F to prevent shell injection."
exit 1
fi
# Stage all changes
git add -A
# Commit using file (no shell expansion of message content)
git commit -F "$TMPFILE"
echo "✓ Committed safely (no shell expansion)"