|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# |
| 4 | +# ⚠ USE WITH CAUTION ⚠ |
| 5 | +# |
| 6 | +# Pre-receive hook that will block any new commits that contain passwords, |
| 7 | +# tokens, or other confidential information matched by regex |
| 8 | +# |
| 9 | +# More details on pre-receive hooks and how to apply them can be found on |
| 10 | +# https://git.io/fNLf0 |
| 11 | +# |
| 12 | + |
| 13 | +# ------------------------------------------------------------------------------ |
| 14 | +# Variables |
| 15 | +# ------------------------------------------------------------------------------ |
| 16 | +# Count of issues found in parsing |
| 17 | +found=0 |
| 18 | + |
| 19 | +# Define list of REGEX to be searched and blocked |
| 20 | +regex_list=( |
| 21 | + # block any private key file |
| 22 | + '(\-){5}BEGIN\s?(RSA|OPENSSH|DSA|EC|PGP)?\s?PRIVATE KEY\s?(BLOCK)?(\-){5}.*' |
| 23 | + # block AWS API Keys |
| 24 | + 'AKIA[0-9A-Z]{16}' |
| 25 | + # block AWS Secret Access Key (TODO: adjust to not find validd Git SHA1s; false positives) |
| 26 | + '([^A-Za-z0-9/+=])?([A-Za-z0-9/+=]{40})([^A-Za-z0-9/+=])?' |
| 27 | + # block confidential content |
| 28 | + 'CONFIDENTIAL' |
| 29 | +) |
| 30 | + |
| 31 | +# Concatenate regex_list |
| 32 | +separator="|" |
| 33 | +regex="$( printf "${separator}%s" "${regex_list[@]}" )" |
| 34 | +# remove leading separator |
| 35 | +regex="${regex:${#separator}}" |
| 36 | + |
| 37 | +# Commit sha with all zeros |
| 38 | +zero_commit='0000000000000000000000000000000000000000' |
| 39 | + |
| 40 | +# ------------------------------------------------------------------------------ |
| 41 | +# Pre-receive hook |
| 42 | +# ------------------------------------------------------------------------------ |
| 43 | +while read oldrev newrev refname; do |
| 44 | + # # Debug payload |
| 45 | + # echo -e "${oldrev} ${newrev} ${refname}\n" |
| 46 | + |
| 47 | + # ---------------------------------------------------------------------------- |
| 48 | + # Get the list of all the commits |
| 49 | + # ---------------------------------------------------------------------------- |
| 50 | + |
| 51 | + # Check if a zero sha |
| 52 | + if [ "${oldrev}" = "${zero_commit}" ]; then |
| 53 | + # List everything reachable from newrev but not any heads |
| 54 | + span=`git rev-list $(git for-each-ref --format='%(refname)' refs/heads/* | sed 's/^/\^/') ${newrev}` |
| 55 | + else |
| 56 | + span=`git rev-list ${oldrev}..${newrev}` |
| 57 | + fi |
| 58 | + |
| 59 | + # ---------------------------------------------------------------------------- |
| 60 | + # Iterate over all commits in the push |
| 61 | + # ---------------------------------------------------------------------------- |
| 62 | + for sha1 in ${span}; do |
| 63 | + # Use extended regex to search for a match |
| 64 | + match=`git diff-tree -r -p --no-color --diff-filter=d ${sha1} | grep -nE "(${regex})"` |
| 65 | + |
| 66 | + # Verify its not empty |
| 67 | + if [ "${match}" != "" ]; then |
| 68 | + # # Debug match |
| 69 | + # echo -e "${match}\n" |
| 70 | + |
| 71 | + found=$((${found} + 1)) |
| 72 | + fi |
| 73 | + done |
| 74 | +done |
| 75 | + |
| 76 | +# ------------------------------------------------------------------------------ |
| 77 | +# Verify count of found errors |
| 78 | +# ------------------------------------------------------------------------------ |
| 79 | +if [ ${found} -gt 0 ]; then |
| 80 | + # Found errors, exit with error |
| 81 | + echo "[POLICY BLOCKED] You're trying to commit a password, token, or confidential information" |
| 82 | + exit 1 |
| 83 | +else |
| 84 | + # No errors found, exit with success |
| 85 | + exit 0 |
| 86 | +fi |
0 commit comments