Files
ECC/scripts/codex-git-hooks/pre-commit
T
Geronimo 27667bc746 fix(security): harden worker approval, hook traversal, MCP exec, install scripts, git hooks
- orchestrate-codex-worker: drop yolo, default never approval, worktree containment
- run-with-flags-shell: add path traversal containment mirroring JS guard
- mcp-health-check: gate workspace probe, denylist dangerous env, shell-free reconnect with opt-in
- install.sh/ps1: add --ignore-scripts to block postinstall RCE
- git hooks: refuse global hooksPath clobber, remove file disable bypass, gate pre-push repo script execution
- claw.js: remove Windows shell:true, validate model token
- tests: opt into new secure defaults, quote-aware reconnect parsing
2026-09-14 13:24:58 +05:30

79 lines
2.3 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
# ECC Codex Git Hook: pre-commit
# Blocks commits that add high-signal secrets.
if [[ "${ECC_SKIP_GIT_HOOKS:-0}" == "1" || "${ECC_SKIP_PRECOMMIT:-0}" == "1" ]]; then
printf '[ECC pre-commit] WARNING: hook bypassed via env (ECC_SKIP_*=1)\n' >&2
exit 0
fi
# NOTE: file-based disables (.ecc-hooks-disable) were removed — a malicious
# repo could ship that file and silently turn off secret scanning exactly
# where it is most needed. Use the env bypass above (audible warning) instead.
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
exit 0
fi
staged_files="$(git diff --cached --name-only --diff-filter=ACMR || true)"
if [[ -z "$staged_files" ]]; then
exit 0
fi
has_findings=0
scan_added_lines() {
local file="$1"
local name="$2"
local regex="$3"
local added_lines
local hits
added_lines="$(git diff --cached -U0 -- "$file" | awk '/^\+\+\+ /{next} /^\+/{print substr($0,2)}')"
if [[ -z "$added_lines" ]]; then
return 0
fi
if hits="$(printf '%s\n' "$added_lines" | rg -n --pcre2 "$regex" 2>/dev/null)"; then
printf '\n[ECC pre-commit] Potential secret detected (%s) in %s\n' "$name" "$file" >&2
printf '%s\n' "$hits" | head -n 3 >&2
has_findings=1
fi
}
while IFS= read -r file; do
[[ -z "$file" ]] && continue
case "$file" in
*.png|*.jpg|*.jpeg|*.gif|*.svg|*.pdf|*.zip|*.gz|*.lock|pnpm-lock.yaml|package-lock.json|yarn.lock|bun.lockb)
continue
;;
esac
scan_added_lines "$file" "OpenAI key" 'sk-[A-Za-z0-9]{20,}'
scan_added_lines "$file" "GitHub classic token" 'ghp_[A-Za-z0-9]{36}'
scan_added_lines "$file" "GitHub fine-grained token" 'github_pat_[A-Za-z0-9_]{20,}'
scan_added_lines "$file" "AWS access key" 'AKIA[0-9A-Z]{16}'
scan_added_lines "$file" "private key block" '-----BEGIN (RSA|EC|OPENSSH|DSA|PRIVATE) KEY-----'
scan_added_lines "$file" "generic credential assignment" "(?i)\\b(api[_-]?key|secret|password|token)\\b\\s*[:=]\\s*['\\\"][^'\\\"]{12,}['\\\"]"
done <<< "$staged_files"
if [[ "$has_findings" -eq 1 ]]; then
cat >&2 <<'EOF'
[ECC pre-commit] Commit blocked to prevent secret leakage.
Fix:
1) Remove secrets from staged changes.
2) Move secrets to env vars or secret manager.
3) Re-stage and commit again.
Temporary bypass (not recommended):
ECC_SKIP_PRECOMMIT=1 git commit ...
EOF
exit 1
fi
exit 0