#!/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 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 | $0 -F | $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)"