Files
anoracleofra-code 668ce16dc7 v0.9.6: InfoNet hashchain, Wormhole gate encryption, mesh reputation, 16 community contributors
Gate messages now propagate via the Infonet hashchain as encrypted blobs — every node syncs them
through normal chain sync while only Gate members with MLS keys can decrypt. Added mesh reputation
system, peer push workers, voluntary Wormhole opt-in for node participation, fork recovery,
killwormhole scripts, obfuscated terminology, and hardened the self-updater to protect encryption
keys and chain state during updates.

New features: Shodan search, train tracking, Sentinel Hub imagery, 8 new intelligence layers,
CCTV expansion to 11,000+ cameras across 6 countries, Mesh Terminal CLI, prediction markets,
desktop-shell scaffold, and comprehensive mesh test suite (215 frontend + backend tests passing).

Community contributors: @wa1id, @AlborzNazari, @adust09, @Xpirix, @imqdcr, @csysp, @suranyami,
@chr0n1x, @johan-martensson, @singularfailure, @smithbh, @OrfeoTerkuci, @deuza, @tm-const,
@Elhard1, @ttulttul
2026-03-26 05:58:04 -06:00

122 lines
5.5 KiB
Bash

#!/usr/bin/env bash
# scan-secrets.sh — Catch keys, secrets, and credentials before they hit git.
#
# Usage:
# ./backend/scripts/scan-secrets.sh # Scan staged files (pre-commit)
# ./backend/scripts/scan-secrets.sh --all # Scan entire working tree
# ./backend/scripts/scan-secrets.sh --staged # Scan staged files only (default)
#
# Exit code: 0 = clean, 1 = secrets found
set -euo pipefail
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m'
MODE="${1:---staged}"
FOUND=0
# ── Get file list based on mode ─────────────────────────────────────────
if [[ "$MODE" == "--all" ]]; then
FILELIST=$(mktemp)
{ git ls-files 2>/dev/null; git ls-files --others --exclude-standard 2>/dev/null; } > "$FILELIST"
echo -e "${YELLOW}Scanning entire working tree...${NC}"
else
FILELIST=$(mktemp)
git diff --cached --name-only --diff-filter=ACMR 2>/dev/null > "$FILELIST" || true
if [[ ! -s "$FILELIST" ]]; then
echo -e "${GREEN}No staged files to scan.${NC}"
rm -f "$FILELIST"
exit 0
fi
echo -e "${YELLOW}Scanning $(wc -l < "$FILELIST" | tr -d ' ') staged files...${NC}"
fi
# ── Check 1: Dangerous file extensions ──────────────────────────────────
KEY_EXT='\.key$|\.pem$|\.p12$|\.pfx$|\.jks$|\.keystore$|\.p8$|\.der$'
SECRET_EXT='\.secret$|\.secrets$|\.credential$|\.credentials$'
HITS=$(grep -iE "$KEY_EXT|$SECRET_EXT" "$FILELIST" 2>/dev/null || true)
if [[ -n "$HITS" ]]; then
echo -e "\n${RED}BLOCKED: Key/secret files detected:${NC}"
echo "$HITS" | while read -r f; do echo -e " ${RED}$f${NC}"; done
FOUND=1
fi
# ── Check 2: Dangerous filenames ────────────────────────────────────────
RISKY='id_rsa|id_ed25519|id_ecdsa|private_key|private\.key|secret_key|master\.key'
RISKY+='|serviceaccount|gcloud.*\.json|firebase.*\.json|\.htpasswd'
HITS=$(grep -iE "$RISKY" "$FILELIST" 2>/dev/null || true)
if [[ -n "$HITS" ]]; then
echo -e "\n${RED}BLOCKED: Risky filenames detected:${NC}"
echo "$HITS" | while read -r f; do echo -e " ${RED}$f${NC}"; done
FOUND=1
fi
# ── Check 3: .env files (not .env.example) ──────────────────────────────
HITS=$(grep -E '(^|/)\.env(\.[^e].*)?$' "$FILELIST" 2>/dev/null | grep -v '\.example' || true)
if [[ -n "$HITS" ]]; then
echo -e "\n${RED}BLOCKED: Environment files detected:${NC}"
echo "$HITS" | while read -r f; do echo -e " ${RED}$f${NC}"; done
FOUND=1
fi
# ── Check 4: _domain_keys directory (project-specific) ──────────────────
HITS=$(grep '_domain_keys/' "$FILELIST" 2>/dev/null || true)
if [[ -n "$HITS" ]]; then
echo -e "\n${RED}BLOCKED: Domain keys directory detected:${NC}"
echo "$HITS" | while read -r f; do echo -e " ${RED}$f${NC}"; done
FOUND=1
fi
# ── Check 5: Content scan for embedded secrets (single grep pass) ───────
# Build one mega-pattern and run grep once across all files (fast!)
SECRET_REGEX='PRIVATE KEY-----|'
SECRET_REGEX+='ssh-rsa AAAA[0-9A-Za-z+/]|'
SECRET_REGEX+='ssh-ed25519 AAAA[0-9A-Za-z+/]|'
SECRET_REGEX+='ghp_[0-9a-zA-Z]{36}|' # GitHub PAT
SECRET_REGEX+='github_pat_[0-9a-zA-Z]{22}_[0-9a-zA-Z]{59}|' # GitHub fine-grained
SECRET_REGEX+='gho_[0-9a-zA-Z]{36}|' # GitHub OAuth
SECRET_REGEX+='sk-[0-9a-zA-Z]{48}|' # OpenAI key
SECRET_REGEX+='sk-ant-[0-9a-zA-Z-]{90,}|' # Anthropic key
SECRET_REGEX+='AKIA[0-9A-Z]{16}|' # AWS access key
SECRET_REGEX+='AIzaSy[0-9A-Za-z_-]{33}|' # Google API key
SECRET_REGEX+='xox[bpoas]-[0-9a-zA-Z-]+|' # Slack token
SECRET_REGEX+='npm_[0-9a-zA-Z]{36}|' # npm token
SECRET_REGEX+='pypi-[0-9a-zA-Z-]{50,}' # PyPI token
# Filter to text-like files only (skip binaries by extension + skip this script)
TEXT_FILES=$(grep -ivE '\.(png|jpg|jpeg|gif|ico|svg|woff2?|ttf|eot|pbf|zip|tar|gz|db|sqlite|xlsx|pdf|mp[34]|wav|ogg|webm|webp|avif)$' "$FILELIST" | grep -v 'scan-secrets\.sh$' || true)
if [[ -n "$TEXT_FILES" ]]; then
# Use grep with file list, skip missing/binary, limit output
CONTENT_HITS=$(echo "$TEXT_FILES" | xargs grep -lE "$SECRET_REGEX" 2>/dev/null || true)
if [[ -n "$CONTENT_HITS" ]]; then
echo -e "\n${RED}BLOCKED: Embedded secrets/tokens found in:${NC}"
echo "$CONTENT_HITS" | while read -r f; do
echo -e " ${RED}$f${NC}"
# Show first matching line for context
grep -nE "$SECRET_REGEX" "$f" 2>/dev/null | head -2 | while read -r line; do
echo -e " ${YELLOW}$line${NC}"
done
done
FOUND=1
fi
fi
rm -f "$FILELIST"
# ── Result ──────────────────────────────────────────────────────────────
echo ""
if [[ $FOUND -eq 1 ]]; then
echo -e "${RED}Secret scan FAILED. Add these to .gitignore or remove them before committing.${NC}"
echo -e "${YELLOW}If intentional (e.g. test fixtures): git commit --no-verify${NC}"
exit 1
else
echo -e "${GREEN}Secret scan passed. No keys or secrets detected.${NC}"
exit 0
fi