#!/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/ or /home/) 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