- LICENSE: texto integro de la GPL-3.0 - docs/publicacion-anonima.md: politica de publicacion sin datos reales (nombres, rutas con usuario, dominios, IPs, credenciales) y checklist - tools/verificar-anonimato.sh: chequeo automatico de PII y archivos sensibles trackeados, con salida por codigo (0 limpio / 1 con hallazgos) - README: seccion 'Publicacion anonima' y licencia GPL-3.0 - .env.global: ruta base sin nombre de usuario - README ejemplo: nombres de proyecto genericos (miapp) en lugar de reales
135 lines
5.0 KiB
Bash
Executable File
135 lines
5.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# ==============================================================================
|
|
# verificar-anonimato.sh
|
|
# ==============================================================================
|
|
# Escanea el contenido versionado de un repositorio buscando datos que NO
|
|
# deben publicarse: nombres de personas, rutas con usuario, IPs reales,
|
|
# dominios reales, credenciales y archivos sensibles sin trackear.
|
|
#
|
|
# Uso:
|
|
# ./tools/verificar-anonimato.sh # revisa el repo actual
|
|
# ./tools/verificar-anonimato.sh /ruta/repo # revisa otro repo
|
|
#
|
|
# Salida: 0 = sin hallazgos | 1 = hay hallazgos
|
|
# ==============================================================================
|
|
set -uo pipefail
|
|
|
|
REPO="${1:-.}"
|
|
cd "$REPO" || { echo "No se pudo acceder a: $REPO"; exit 1; }
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BOLD='\033[1m'
|
|
NC='\033[0m'
|
|
|
|
FINDINGS=0
|
|
|
|
section() {
|
|
printf '\n%s== %s ==%s\n' "$BOLD" "$1" "$NC"
|
|
}
|
|
|
|
hit() {
|
|
printf ' %s[%s]%s %s\n' "$RED" "$2" "$NC" "$1"
|
|
FINDINGS=$((FINDINGS + 1))
|
|
}
|
|
|
|
printf '%s=== Verificación de anonimato ===%s\n' "$BOLD" "$NC"
|
|
printf 'Repositorio: %s\n' "$(pwd)"
|
|
|
|
# -----------------------------------------------------------------------------
|
|
section "Archivos sensibles trackeados"
|
|
SENSITIVE=$(git ls-files 2>/dev/null | grep -Ei \
|
|
'(^|/)\.env($|\.)|\.pem$|\.key$|\.crt$|acme\.json$|\.sql$|\.dump$|\.p12$|\.pfx$' \
|
|
| grep -vE '\.env\.(example|sample|template|global|dist)$' || true)
|
|
|
|
if [ -n "$SENSITIVE" ]; then
|
|
while IFS= read -r f; do
|
|
hit "$f" "CRÍTICO"
|
|
done <<< "$SENSITIVE"
|
|
else
|
|
printf ' %s✓%s ninguno\n' "$GREEN" "$NC"
|
|
fi
|
|
|
|
# -----------------------------------------------------------------------------
|
|
section "Dependencias y artefactos pesados"
|
|
HEAVY=$(git ls-files 2>/dev/null | grep -E '^(vendor/|node_modules/)' | head -10 || true)
|
|
if [ -n "$HEAVY" ]; then
|
|
hit "$(echo "$HEAVY" | wc -l) archivos en vendor/ o node_modules/ deben excluirse" "ALTO"
|
|
else
|
|
printf ' %s✓%s ninguno\n' "$GREEN" "$NC"
|
|
fi
|
|
|
|
# -----------------------------------------------------------------------------
|
|
section "Rutas con nombre de usuario"
|
|
PATHS=$(git grep -nE '/home/[a-zA-Z0-9._-]+/' -- . 2>/dev/null | grep -vE 'docker|/home/runner' | head -10 || true)
|
|
if [ -n "$PATHS" ]; then
|
|
while IFS= read -r l; do hit "$l" "MEDIO"; done <<< "$PATHS"
|
|
else
|
|
printf ' %s✓%s ninguna\n' "$GREEN" "$NC"
|
|
fi
|
|
|
|
# -----------------------------------------------------------------------------
|
|
section "Direcciones IP"
|
|
IPS=$(git grep -nE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' -- . 2>/dev/null \
|
|
| grep -vE '(0\.0\.0\.0|127\.0\.0\.1|255\.|192\.0\.2\.|198\.51\.100\.|203\.0\.113\.|192\.168\.|10\.[0-9]+\.|172\.(1[6-9]|2[0-9]|3[01])\.|1\.1\.1\.1|8\.8\.8\.8)' \
|
|
| head -10 || true)
|
|
if [ -n "$IPS" ]; then
|
|
while IFS= read -r l; do hit "$l" "MEDIO"; done <<< "$IPS"
|
|
else
|
|
printf ' %s✓%s ninguna (solo rangos de documentación)\n' "$GREEN" "$NC"
|
|
fi
|
|
|
|
# -----------------------------------------------------------------------------
|
|
section "Credenciales en texto"
|
|
CREDS=$(git grep -nEi \
|
|
'(password|passwd|secret|api[_-]?key|access[_-]?token)[[:space:]]*[:=][[:space:]]*["'"'"']?[A-Za-z0-9/+_-]{6,}' \
|
|
-- . 2>/dev/null | grep -vE '\$\{|CHANGEME|changeme|<[^>]+>|password: *\$|PASSWORD=\$|example' | head -10 || true)
|
|
if [ -n "$CREDS" ]; then
|
|
while IFS= read -r l; do hit "$l" "ALTO"; done <<< "$CREDS"
|
|
else
|
|
printf ' %s✓%s ninguna\n' "$GREEN" "$NC"
|
|
fi
|
|
|
|
# -----------------------------------------------------------------------------
|
|
section "Emails y dominios"
|
|
MAILS=$(git grep -nEi '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}' -- . 2>/dev/null \
|
|
| grep -vEi '@(localhost|example\.(com|org|net)|gnu\.org|fsf\.org|w3\.org|iana\.org|localhost\.localdomain)' \
|
|
| head -10 || true)
|
|
if [ -n "$MAILS" ]; then
|
|
while IFS= read -r l; do hit "$l" "MEDIO"; done <<< "$MAILS"
|
|
else
|
|
printf ' %s✓%s ninguno\n' "$GREEN" "$NC"
|
|
fi
|
|
|
|
# -----------------------------------------------------------------------------
|
|
section "Licencia"
|
|
if [ -f LICENSE ] || [ -f LICENSE.md ] || [ -f COPYING ]; then
|
|
printf ' %s✓%s presente\n' "$GREEN" "$NC"
|
|
else
|
|
printf ' %s[!]%s falta un archivo LICENSE\n' "$YELLOW" "$NC"
|
|
FINDINGS=$((FINDINGS + 1))
|
|
fi
|
|
|
|
# -----------------------------------------------------------------------------
|
|
section "Autores en el historial"
|
|
AUTHORS=$(git log --format='%an <%ae>' --all 2>/dev/null | sort -u | head -10 || true)
|
|
if [ -n "$AUTHORS" ]; then
|
|
printf ' %sAutores registrados:%s\n' "$YELLOW" "$NC"
|
|
while IFS= read -r a; do printf ' - %s\n' "$a"; done <<< "$AUTHORS"
|
|
printf ' %s Revisá que no expongan datos institucionales.%s\n' "$YELLOW" "$NC"
|
|
else
|
|
printf ' %s✓%s sin commits\n' "$GREEN" "$NC"
|
|
fi
|
|
|
|
# -----------------------------------------------------------------------------
|
|
printf '\n%s=== Resultado ===%s\n' "$BOLD" "$NC"
|
|
if [ "$FINDINGS" -eq 0 ]; then
|
|
printf '%s✓ Sin hallazgos: el repositorio puede publicarse.%s\n' "$GREEN" "$NC"
|
|
exit 0
|
|
fi
|
|
|
|
printf '%s✗ %d hallazgo(s). Corregí lo anterior antes de publicar.%s\n' "$RED" "$FINDINGS" "$NC"
|
|
exit 1
|