Files
rar-autopass/tools/restore_check.sh
Claude Agent 63b6cbc01d fix(securitate): hardening prod — headere, body-cap, non-root, backup
Findings security-review P1/P2 (2026-07-03):
- headere de securitate pe toate raspunsurile (nosniff, X-Frame-Options,
  Referrer-Policy, HSTS doar pe HTTPS) + teste
- body-cap global 10MB ca middleware ASGI pur (413 inainte de parserul
  multipart/JSON; verificarea per-endpoint ramane strat 2)
- imagine Docker non-root (uid 10001), port 8010 aliniat, loguri pe
  volumul /data
- fail-fast la boot cu rar_env=prod fara AUTOPASS_REQUIRE_API_KEY sau
  AUTOPASS_SESSION_SECRET
- compose: env-uri critice obligatorii (:?) ca api/worker sa nu diverga
  tacit; FORWARDED_ALLOW_IPS ca rate-limit-ul sa vada IP-ul real dupa
  Traefik
- signup fara PII in stdout: log_event in loc de print cu email (idem
  notify degradat)
- ratelimit: sterge cheile fara timestamp-uri valide (crestere monotona
  a memoriei pe IP-uri reale)
- backup criptat SQLite (backup online API, gpg AES256) + verificare
  restore + docs/backup.md

Suita completa verde: 1557 passed, 1 skipped (live).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 12:46:49 +00:00

113 lines
3.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Verificare de restaurare pentru backup-urile SQLite criptate (T2/P0-4).
#
# Un backup neverificat nu e backup: decripteaza + dezarhiveaza (intr-un fisier temporar,
# NU suprascrie baza vie) ultimul backup (sau cel indicat explicit) si ruleaza
# PRAGMA integrity_check + un SELECT count(*) FROM submissions. Iese cu cod != 0 daca
# ceva esueaza sau daca integritatea nu e "ok".
#
# Utilizare:
# AUTOPASS_BACKUP_PASSPHRASE_FILE=/run/secrets/backup_pass tools/restore_check.sh
# tools/restore_check.sh /data/backups/autopass-20260706-120000.db.gz.gpg
set -euo pipefail
BACKUP_DIR="${AUTOPASS_BACKUP_DIR:-/data/backups}"
log() { echo "[restore_check] $*"; }
err() { echo "[restore_check] EROARE: $*" >&2; }
CLEANUP_PATHS=()
cleanup() {
local p
for p in "${CLEANUP_PATHS[@]:-}"; do
[[ -n "$p" ]] && rm -rf "$p"
done
}
trap cleanup EXIT
if [[ -n "${AUTOPASS_BACKUP_PASSPHRASE_FILE:-}" ]]; then
if [[ ! -f "$AUTOPASS_BACKUP_PASSPHRASE_FILE" ]]; then
err "AUTOPASS_BACKUP_PASSPHRASE_FILE indica un fisier inexistent: $AUTOPASS_BACKUP_PASSPHRASE_FILE"
exit 1
fi
PASSPHRASE_FILE="$AUTOPASS_BACKUP_PASSPHRASE_FILE"
elif [[ -n "${AUTOPASS_BACKUP_PASSPHRASE:-}" ]]; then
PASSPHRASE_FILE="$(mktemp)"
chmod 600 "$PASSPHRASE_FILE"
CLEANUP_PATHS+=("$PASSPHRASE_FILE")
printf '%s' "$AUTOPASS_BACKUP_PASSPHRASE" > "$PASSPHRASE_FILE"
else
err "lipseste parola de decriptare."
err "seteaza AUTOPASS_BACKUP_PASSPHRASE_FILE (recomandat) sau AUTOPASS_BACKUP_PASSPHRASE."
exit 1
fi
if [[ "${1:-}" != "" ]]; then
TARGET="$1"
else
TARGET="$(ls -1t "$BACKUP_DIR"/autopass-*.db.gz.gpg 2>/dev/null | head -n1 || true)"
fi
if [[ -z "$TARGET" || ! -f "$TARGET" ]]; then
err "niciun backup gasit de verificat (director: $BACKUP_DIR)"
exit 1
fi
log "verific: $TARGET"
TMP_DIR="$(mktemp -d)"
CLEANUP_PATHS+=("$TMP_DIR")
GZ_FILE="$TMP_DIR/snapshot.db.gz"
DB_FILE="$TMP_DIR/snapshot.db"
log "decriptez (gpg)"
gpg --batch --yes --decrypt --passphrase-file "$PASSPHRASE_FILE" \
--output "$GZ_FILE" "$TARGET"
log "dezarhivez (gzip)"
gzip -d "$GZ_FILE"
if [[ ! -s "$DB_FILE" ]]; then
err "fisierul restaurat e gol sau lipseste: $DB_FILE"
exit 1
fi
log "PRAGMA integrity_check + count(submissions)"
set +e
RESULT="$(python3 - "$DB_FILE" <<'PYEOF'
import sqlite3
import sys
conn = sqlite3.connect(sys.argv[1])
try:
integrity = conn.execute("PRAGMA integrity_check").fetchone()[0]
try:
count = conn.execute("SELECT count(*) FROM submissions").fetchone()[0]
except sqlite3.OperationalError as exc:
print(f"integrity={integrity}")
print(f"eroare_count_submissions={exc}")
sys.exit(1)
print(f"integrity={integrity}")
print(f"count_submissions={count}")
finally:
conn.close()
PYEOF
)"
STATUS=$?
set -e
echo "$RESULT"
if [[ $STATUS -ne 0 ]]; then
err "verificare esuata (vezi mesajul de mai sus)"
exit 1
fi
if ! grep -q "^integrity=ok$" <<<"$RESULT"; then
err "PRAGMA integrity_check NU a raportat 'ok'"
exit 1
fi
log "backup valid: restaurabil, integritate ok."