Last active
November 13, 2024 15:08
-
-
Save hartfordfive/b6408e0018c11bf17c6b7f710018357a to your computer and use it in GitHub Desktop.
Git pre-commit hook to search for potentially sensitive data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# List of the patterns to search for | |
declare -a git_verification_patterns # Create an associative array | |
git_verification_patterns[0]="(\"|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)(\"|')?\s*(:|=>|=)\s*(\"|')?[A-Za-z0-9/\+=]{40}(\"|'|\s)?" | |
git_verification_patterns[1]="(\"|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)?_?(ID|id|Id)?(\"|')?\s*(:|=>|=)\s*(\"|')?[A-Za-z0-9/\+=]{20}(\"|'|\s)?" | |
git_verification_patterns[2]="(\s+|=|:)[a-z0-9]{64}(\s+|\|)" # DigitalOcean Personal Access Token | |
git_verification_patterns[3]='Authorization\s+"?Basic\s+[a-zA-Z0-9+/]+={0,2}' | |
git_verification_patterns[4]="BEGIN RSA PRIVATE KEY" | |
git_verification_patterns[5]="END RSA PRIVATE KEY" | |
# List of the pattern descriptions (in same order) | |
declare -a git_verification_patterns_desc | |
git_verification_patterns_desc[0]="AWS Secret Key, Github Personal Access Token" | |
git_verification_patterns_desc[1]="AWS Access Key ID" | |
git_verification_patterns_desc[2]="DigitalOcean Personal Access Token" | |
git_verification_patterns_desc[3]="Base64 Encoded HTTP Auth header" | |
git_verification_patterns_desc[4]="SSH Private Key File" | |
git_verification_patterns_desc[5]="SSH Private Key File" | |
# List of the white-list exceptions for the above patterns (in same order) | |
declare -a git_verification_patterns_whitelist | |
git_verification_patterns_whitelist[0]="(\s+|=)00000000000000000000(\s+|\|)" | |
git_verification_patterns_whitelist[1]="(\s+|=)0000000000000000000000000000000000000000(\s+|\|)" | |
git_verification_patterns_whitelist[2]="(\s+|=)0000000000000000000000000000000000000000000000000000000000000000(\s+|\|)" | |
git_verification_patterns_whitelist[3]='Authorization "Basic MDAwMDAwMDAwMDAwMDowMDAwMDAwMDAwMAo="' # 0000000000000:00000000000" | |
git_verification_patterns_whitelist[4]="" | |
git_verification_patterns_whitelist[5]="" | |
git_verification_patterns_ssh_key='^.{65}$' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
if git rev-parse --verify HEAD >/dev/null 2>&1 | |
then | |
against=HEAD | |
else | |
# Initial commit: diff against an empty tree object | |
EMPTY_TREE=$(git hash-object -t tree /dev/null) | |
against=$EMPTY_TREE | |
fi | |
# Redirect output to stderr. | |
exec 1>&2 | |
echo "=======================================================" | |
echo "Running Verification for tokens, secret keys, etc..." | |
echo "=======================================================" | |
echo "" | |
source ~/.git-verification-patterns | |
#FILES_MODIFIED=$(git diff --cached --name-only -z $against) | |
FILES_MODIFIED=$(git diff --cached --name-only) | |
NUM_FILES_CHECKED=0 | |
NUM_FILES_OFFENCES=0 | |
exec < /dev/tty | |
for F in $FILES_MODIFIED | |
do | |
for i in "${!git_verification_patterns[@]}"; do | |
MATCH=$(cat $F | egrep -i --line-number "${git_verification_patterns[$i]}") | |
if [ ! -z "$MATCH" ]; then | |
echo "\t FILE: $F" | |
echo "\tPATTERN: ${git_verification_patterns[$i]}" | |
echo "\t DESC: ${git_verification_patterns_desc[$i]}" | |
echo "\tLINE(S):" | |
for L in $MATCH; do | |
echo "\t\t$L" | |
done | |
while true; do | |
read -p "Commit file anyway? (y/N): " yn | |
case $yn in | |
[Yy] ) break;; | |
[Nn] ) NUM_FILES_OFFENCES=$((NUM_FILES_OFFENCES+1)); break;; | |
* ) echo "Answer y or n."; continue;; | |
esac | |
done | |
echo "\t---------------------------" | |
fi | |
done | |
# Now also do a verification pattern for an SSH private key file | |
MATCH=$(cat $F | egrep -i --line-number "${git_verification_patterns_ssh_key}") | |
NUM_SSH_PK_LINES_FOUND=$(cat $F | egrep -i --line-number ${git_verification_patterns_ssh_key} | wc -l | awk '{print $1}') | |
if (( $NUM_SSH_PK_LINES_FOUND >= 3 )); then | |
echo "\t FILE: $F" | |
echo "\tPATTERN: ${git_verification_patterns_ssh_key}" | |
echo "\t DESC: ${git_verification_patterns_desc[$i]}" | |
echo "\tLINE(S):" | |
for L in $MATCH; do | |
echo "\t\t$L" | |
done | |
while true; do | |
read -p "Commit file anyway? (y/N): " yn | |
case $yn in | |
[Yy] ) break;; | |
[Nn] ) NUM_FILES_OFFENCES=$((NUM_FILES_OFFENCES+1)); break;; | |
* ) echo "Answer y or n."; continue;; | |
esac | |
done | |
echo "\t---------------------------" | |
fi | |
NUM_FILES_CHECKED=$((NUM_FILES_CHECKED+1)) | |
done | |
exec <&- # Release input | |
echo "======================= SUMMARY =======================" | |
echo " Files Checked: $NUM_FILES_CHECKED" | |
echo " Num File Offences: $NUM_FILES_OFFENCES" | |
if [ $NUM_FILES_OFFENCES -gt 0 ]; then | |
echo " Status: FAIL" | |
else | |
echo " Status: OK" | |
fi | |
echo "-------------------------------------------------------" | |
echo "" | |
# Exit code based on if > 0 offences found | |
if [ $NUM_FILES_OFFENCES -gt 0 ]; then | |
exit 1 | |
else | |
exit 0 | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment