97 lines
4.2 KiB
Bash
Executable File
97 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ==============================================================================
|
|
# Git Pre-Commit Hook: Anti-Data-Leak & Secrets Protection
|
|
# ==============================================================================
|
|
# Prevents accidental commits of personal media, child data, student UUIDs,
|
|
# local paths, and credentials before code is committed or pushed.
|
|
# ==============================================================================
|
|
|
|
set -eo pipefail
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BOLD='\033[1m'
|
|
NC='\033[0m'
|
|
|
|
ERRORS_FOUND=0
|
|
|
|
echo -e "${BOLD}🔍 Running pre-commit security & data leak checks...${NC}"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 1. Check for forbidden staged files (Media, Archives, Real Exports)
|
|
# ------------------------------------------------------------------------------
|
|
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
|
|
|
|
if [ -n "$STAGED_FILES" ]; then
|
|
while IFS= read -r file; do
|
|
[ -z "$file" ] && continue
|
|
|
|
# Check for forbidden export data files & raw media (allow screenshots/ and icons/)
|
|
if [[ "$file" =~ ^(screenshots/|icons/) ]]; then
|
|
: # Allowed store & UI asset directory
|
|
elif [[ "$file" =~ (activities\.csv|activities\.json|exporter_job_info\.json|\.zip$|\.crx$|\.mp4$|\.mov$|\.webm$|\.heic$|\.jpg$|\.jpeg$) ]]; then
|
|
echo -e "${RED}❌ [DATA LEAK BLOCKED] Staged forbidden export/media file:${NC} $file"
|
|
ERRORS_FOUND=$((ERRORS_FOUND + 1))
|
|
fi
|
|
|
|
# Check for forbidden folder names
|
|
if [[ "$file" =~ ^(emmy|exports|data|test_data)/ ]]; then
|
|
echo -e "${RED}❌ [DATA LEAK BLOCKED] Staged file from sensitive directory:${NC} $file"
|
|
ERRORS_FOUND=$((ERRORS_FOUND + 1))
|
|
fi
|
|
done <<< "$STAGED_FILES"
|
|
fi
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 2. Check diff content for sensitive patterns in staged changes
|
|
# (Excludes the pre-commit hook file itself from self-matching)
|
|
# ------------------------------------------------------------------------------
|
|
STAGED_DIFF=$(git diff --cached -U0 -- ':!.githooks/*' ':!.git/*' | grep -E "^\+[^+]" || true)
|
|
|
|
if [ -n "$STAGED_DIFF" ]; then
|
|
# 2a. Check for local machine paths (e.g. /Users/<username> or /home/<username>)
|
|
LOCAL_PATH_MATCH=$(echo "$STAGED_DIFF" | grep -En "(/Users/|/home/)[a-zA-Z0-9_\.-]+" || true)
|
|
if [ -n "$LOCAL_PATH_MATCH" ]; then
|
|
echo -e "${RED}❌ [DATA LEAK BLOCKED] Detected local machine path (/Users/... or /home/...):${NC}"
|
|
echo "$LOCAL_PATH_MATCH" | head -n 3
|
|
ERRORS_FOUND=$((ERRORS_FOUND + 1))
|
|
fi
|
|
|
|
# 2b. Check for student UUIDs (e.g. 8-4-4-4-12 hex format)
|
|
UUID_MATCH=$(echo "$STAGED_DIFF" | grep -En "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" || true)
|
|
if [ -n "$UUID_MATCH" ]; then
|
|
echo -e "${RED}❌ [DATA LEAK BLOCKED] Detected hardcoded student/record UUID in diff:${NC}"
|
|
echo "$UUID_MATCH" | head -n 3
|
|
ERRORS_FOUND=$((ERRORS_FOUND + 1))
|
|
fi
|
|
|
|
# 2c. Check for AWS / Token credentials
|
|
AWS_KEY_MATCH=$(echo "$STAGED_DIFF" | grep -En "AKIA[0-9A-Z]{16}" || true)
|
|
if [ -n "$AWS_KEY_MATCH" ]; then
|
|
echo -e "${RED}❌ [SECURITY LEAK BLOCKED] Detected potential AWS Access Key:${NC}"
|
|
echo "$AWS_KEY_MATCH" | head -n 3
|
|
ERRORS_FOUND=$((ERRORS_FOUND + 1))
|
|
fi
|
|
|
|
SESSION_TOKEN_MATCH=$(echo "$STAGED_DIFF" | grep -En "(_brightwheel_session=|Bearer[[:space:]]+[A-Za-z0-9_\-\.]{20,})" || true)
|
|
if [ -n "$SESSION_TOKEN_MATCH" ]; then
|
|
echo -e "${RED}❌ [SECURITY LEAK BLOCKED] Detected session token or bearer credential:${NC}"
|
|
echo "$SESSION_TOKEN_MATCH" | head -n 3
|
|
ERRORS_FOUND=$((ERRORS_FOUND + 1))
|
|
fi
|
|
fi
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 3. Verdict
|
|
# ------------------------------------------------------------------------------
|
|
if [ "$ERRORS_FOUND" -gt 0 ]; then
|
|
echo -e "\n${RED}${BOLD}🚨 COMMIT REJECTED:${NC} $ERRORS_FOUND security / data leak issue(s) detected."
|
|
echo -e "${YELLOW}Please remove sensitive files/tokens before committing.${NC}"
|
|
echo -e "${YELLOW}(If this is an intentional false positive, bypass with 'git commit --no-verify')${NC}\n"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${GREEN}✅ Pre-commit leak check passed! No sensitive data detected.${NC}"
|
|
exit 0
|