54 lines
2.5 KiB
Bash
54 lines
2.5 KiB
Bash
|
|
#!/usr/bin/env bash
|
|||
|
|
set -euo pipefail
|
|||
|
|
|
|||
|
|
BASE="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|||
|
|
cd "$BASE"
|
|||
|
|
|
|||
|
|
mode="${1:---staged}"
|
|||
|
|
case "$mode" in
|
|||
|
|
--staged) revision="--cached" ;;
|
|||
|
|
--worktree) revision="" ;;
|
|||
|
|
--history) revision="--history" ;;
|
|||
|
|
*) echo "Usage: $0 [--staged|--worktree|--history]" >&2; exit 2 ;;
|
|||
|
|
esac
|
|||
|
|
|
|||
|
|
sensitive_names='(^|/)(\.env($|\.)|\.envrc$|\.netrc$|\.npmrc$|\.pypirc$|authorized_keys$|known_hosts$|id_(rsa|dsa|ecdsa|ed25519)(\.|$)|credentials([.-].*)?\.json$|service[-_]account.*\.json$|client[-_]secret.*\.json$|terraform\.tfstate|terraform\.tfvars)|\.(pem|key|p8|p12|pfx|jks|keystore|kdbx|age|gpg|sqlite3?|db|tfstate)(\.|$)'
|
|||
|
|
secret_content='AKIA[0-9A-Z]{16}|ASIA[0-9A-Z]{16}|gh[pousr]_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,}|glpat-[A-Za-z0-9_-]{20,}|sk-[A-Za-z0-9_-]{20,}|AIza[0-9A-Za-z_-]{30,}|xox[baprs]-[A-Za-z0-9-]{20,}|tail[0-9a-f]{6,}\.ts\.net|-----BEGIN ([A-Z0-9 ]+ )?PRIVATE KEY-----'
|
|||
|
|
|
|||
|
|
tracked_files() {
|
|||
|
|
if [[ "$mode" == "--staged" ]]; then
|
|||
|
|
git diff --cached --name-only --diff-filter=ACMR
|
|||
|
|
elif [[ "$mode" == "--worktree" ]]; then
|
|||
|
|
git ls-files --cached --others --exclude-standard
|
|||
|
|
else
|
|||
|
|
git log --all --pretty=format: --name-only
|
|||
|
|
fi
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
name_hits="$(tracked_files | sed '/^$/d' | sort -u | grep -E "$sensitive_names" | grep -Ev '(^|/)\.env\.example$' || true)"
|
|||
|
|
content_hits=""
|
|||
|
|
if [[ "$mode" == "--history" ]]; then
|
|||
|
|
while IFS= read -r commit; do
|
|||
|
|
hits="$(git grep -IlE -e "$secret_content" "$commit" -- . ':!tests/**' ':!scripts/check-secrets.sh' ':!frontend/package-lock.json' 2>/dev/null || true)"
|
|||
|
|
[[ -z "$hits" ]] || content_hits+="${hits}"$'\n'
|
|||
|
|
done < <(git rev-list --all)
|
|||
|
|
else
|
|||
|
|
grep_args=()
|
|||
|
|
if [[ "$mode" == "--worktree" ]]; then
|
|||
|
|
grep_args+=("--untracked" "--exclude-standard")
|
|||
|
|
elif [[ -n "$revision" ]]; then
|
|||
|
|
grep_args+=("$revision")
|
|||
|
|
fi
|
|||
|
|
content_hits="$(git grep "${grep_args[@]}" -IlE -e "$secret_content" -- . ':!tests/**' ':!scripts/check-secrets.sh' ':!frontend/package-lock.json' 2>/dev/null || true)"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
if [[ -n "$name_hits" || -n "$content_hits" ]]; then
|
|||
|
|
echo "ERREUR: contenu potentiellement confidentiel détecté dans Git." >&2
|
|||
|
|
[[ -z "$name_hits" ]] || { echo "Fichiers au nom sensible:" >&2; printf '%s\n' "$name_hits" >&2; }
|
|||
|
|
[[ -z "$content_hits" ]] || { echo "Fichiers au contenu sensible:" >&2; printf '%s\n' "$content_hits" | sort -u >&2; }
|
|||
|
|
echo "Aucune valeur secrète n’a été affichée. Retirez le fichier de Git et révoquez toute clé réellement exposée." >&2
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
echo "Contrôle des secrets réussi (${mode#--})."
|