diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 000000000..a2c9d2a40 --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,42 @@ +title = "Bambuddy gitleaks config" + +# Extend the built-in ruleset instead of replacing it. +[extend] +useDefault = true + +# ── Custom rules ───────────────────────────────────────────────────────── + +# Flag credentials embedded in URL userinfo, e.g. +# http://USERNAME:PASSWORD@host/ +# gitleaks' default ruleset does not catch these because plain alphanumeric +# passwords have no recognisable signature — only the URL structure does. +[[rules]] +id = "basic-auth-url" +description = "Credentials in HTTP(S) URL userinfo" +regex = '''https?://[^:/\s@]+:[^@/\s]{4,}@''' +tags = ["credentials", "url"] + +[rules.allowlist] +# Skip well-known dummy/example creds that legitimately appear in docs +# and test fixtures. Extend as new false positives show up. +regexes = [ + '''https?://user:pass(word)?@''', + '''https?://admin:admin@''', + '''https?://test:test@''', + '''https?://example:example@''', + '''https?://foo:bar@''', + '''https?://[^:]+:password@''', + '''https?://[^:]+:secret@''', +] + +# ── Global allowlist ───────────────────────────────────────────────────── + +[allowlist] +description = "Global paths and patterns that never contain real secrets" +paths = [ + '''(.*?)(png|jpg|jpeg|gif|svg|ico|webp|pdf)$''', + '''frontend/dist/.*''', + '''frontend/node_modules/.*''', + '''backend/tests/fixtures/.*''', + '''static/assets/.*''', # bundled frontend build output (minified JS/CSS) +] diff --git a/test_security.sh b/test_security.sh index 7757ff7ee..24e054cf4 100755 --- a/test_security.sh +++ b/test_security.sh @@ -20,11 +20,13 @@ # trivy-config Trivy Dockerfile/IaC scan only # pip-audit Python dependency vulnerability audit # npm-audit Frontend dependency vulnerability audit +# gitleaks Secrets scan across full git history (slow — only in --full or by name) # # Prerequisites: # pip install bandit[sarif] pip-audit # Python tools # gh extension install github/gh-codeql # CodeQL CLI # curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh # Trivy +# go install github.com/zricethezav/gitleaks/v8@latest # gitleaks (ensure ~/go/bin on PATH) # set -uo pipefail @@ -208,6 +210,19 @@ scan_npm_audit() { (cd frontend && npm audit --audit-level=high) 2>&1 } +scan_gitleaks() { + local bin + if check_command gitleaks; then + bin="gitleaks" + elif [ -x "$HOME/go/bin/gitleaks" ]; then + bin="$HOME/go/bin/gitleaks" + else + echo "SKIP: 'gitleaks' not found. Install: go install github.com/zricethezav/gitleaks/v8@latest" + return 2 + fi + "$bin" detect --source . --redact --no-banner --verbose 2>&1 +} + # ── Job launcher (streams output live with prefix, captures to log) ────── launch_scan() { @@ -363,13 +378,13 @@ SCANS_TO_RUN=() if [ $# -eq 0 ]; then SCANS_TO_RUN=(bandit pip-audit npm-audit) elif [ "$1" = "--full" ]; then - SCANS_TO_RUN=(bandit pip-audit npm-audit codeql-actions codeql-python codeql-js trivy-image trivy-config) + SCANS_TO_RUN=(bandit pip-audit npm-audit codeql-actions codeql-python codeql-js trivy-image trivy-config gitleaks) else for scan in "$@"; do case "$scan" in codeql) SCANS_TO_RUN+=(codeql-actions codeql-python codeql-js) ;; trivy) SCANS_TO_RUN+=(trivy-image trivy-config) ;; - bandit|codeql-actions|codeql-python|codeql-js|trivy-image|trivy-config|pip-audit|npm-audit) + bandit|codeql-actions|codeql-python|codeql-js|trivy-image|trivy-config|pip-audit|npm-audit|gitleaks) SCANS_TO_RUN+=("$scan") ;; *) echo -e "${RED}Unknown scan: $scan${NC}" @@ -391,6 +406,7 @@ for scan in "${SCANS_TO_RUN[@]}"; do trivy-config) launch_scan "trivy-config" scan_trivy_config ;; pip-audit) launch_scan "pip-audit" scan_pip_audit ;; npm-audit) launch_scan "npm-audit" scan_npm_audit ;; + gitleaks) launch_scan "gitleaks" scan_gitleaks ;; esac done