Add lightweight pre-commit secret scanning
This commit is contained in:
77
scripts/scan-secrets.sh
Executable file
77
scripts/scan-secrets.sh
Executable file
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Lightweight staged-file secret scan for local git hygiene.
|
||||
# Focus: obvious high-risk mistakes, not exhaustive DLP.
|
||||
|
||||
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
echo "Not inside a git work tree" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
staged_files=$(git diff --cached --name-only --diff-filter=ACMR)
|
||||
|
||||
if [[ -z "${staged_files}" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
fail=0
|
||||
|
||||
# High-signal patterns only. Avoid noisy generic matches.
|
||||
patterns=(
|
||||
'AKIA[0-9A-Z]{16}'
|
||||
'AIza[0-9A-Za-z\-_]{35}'
|
||||
'ghp_[0-9A-Za-z]{36}'
|
||||
'github_pat_[0-9A-Za-z_]{20,}'
|
||||
'xox[baprs]-[0-9A-Za-z-]{10,}'
|
||||
'-----BEGIN (RSA|DSA|EC|OPENSSH|PGP)? ?PRIVATE KEY-----'
|
||||
'AIzaSy[0-9A-Za-z\-_]+'
|
||||
)
|
||||
|
||||
while IFS= read -r file; do
|
||||
[[ -f "$file" ]] || continue
|
||||
|
||||
# Skip common binary assets.
|
||||
if file "$file" 2>/dev/null | grep -qiE 'image|font|audio|video|compressed|archive|executable'; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Scan staged content, not working tree content.
|
||||
staged_content=$(git show ":$file" 2>/dev/null || true)
|
||||
[[ -n "$staged_content" ]] || continue
|
||||
|
||||
for pattern in "${patterns[@]}"; do
|
||||
if printf '%s' "$staged_content" | grep -nE "$pattern" >/tmp/openclaw-secret-scan-match.$$ 2>/dev/null; then
|
||||
echo "Potential secret detected in staged file: $file" >&2
|
||||
sed 's/^/ /' /tmp/openclaw-secret-scan-match.$$ >&2 || true
|
||||
fail=1
|
||||
fi
|
||||
done
|
||||
|
||||
# Heuristic: suspicious assignments for secret-ish variable names with inline values.
|
||||
if printf '%s' "$staged_content" | grep -nE '(^|[[:space:]])(API_KEY|TOKEN|SECRET|PASSWORD|PASSWD|PRIVATE_KEY)[[:space:]]*[:=][[:space:]]*[^[:space:]]+' >/tmp/openclaw-secret-scan-heuristic.$$ 2>/dev/null; then
|
||||
echo "Suspicious inline credential assignment in staged file: $file" >&2
|
||||
sed 's/^/ /' /tmp/openclaw-secret-scan-heuristic.$$ >&2 || true
|
||||
fail=1
|
||||
fi
|
||||
|
||||
done <<< "$staged_files"
|
||||
|
||||
rm -f /tmp/openclaw-secret-scan-match.$$ /tmp/openclaw-secret-scan-heuristic.$$ 2>/dev/null || true
|
||||
|
||||
if [[ "$fail" -ne 0 ]]; then
|
||||
cat >&2 <<'EOF'
|
||||
Commit blocked by lightweight secret scan.
|
||||
|
||||
If this is a false positive:
|
||||
- inspect the staged diff carefully
|
||||
- remove/redact the sensitive-looking value if needed
|
||||
- re-stage and commit again
|
||||
- or bypass once with: git commit --no-verify
|
||||
|
||||
Use --no-verify sparingly.
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user