Il primo utente: bootstrap sicuro senza seed di default — articolo

> Il primo utente: bootstrap sicuro senza seed di default

Quick note sulla rimozione del seeder admin e il flusso di registrazione iniziale blindato lato server.

Luigi Iadicola
~3 min lettura
#Security #Auth #Bootstrap
Il primo utente: bootstrap sicuro senza seed di default
Il primo utente: bootstrap sicuro senza seed di default

L'admin di default e un buco di sicurezza

Molti framework includono un seeder per l'utente admin con credenziali di default: admin@example.com / password. E comodo per lo sviluppo, ma e anche il primo vettore di attacco su un deploy dimenticato. Se il seeder viene eseguito in produzione e nessuno cambia la password, l'applicazione e aperta a chiunque conosca le credenziali di default.

Questo non e un rischio teorico. Le credenziali di default sono nella top 10 delle vulnerabilita OWASP (A07:2021 - Security Misconfiguration). Bot automatizzati provano combinazioni note come admin/admin, admin/password, root/root su ogni applicazione esposta. Un seeder con credenziali hardcoded e un invito a nozze per questi attacchi.

La soluzione: registrazione iniziale blindata

In Soft PHP MVC, il seeder admin e stato rimosso. Il login ora reindirizza alla pagina di registrazione iniziale quando non esiste alcun utente nel database. La registrazione del primo account e blindata lato server: se esiste gia un utente, la route POST viene rifiutata — non c'e modo di creare un secondo account attraverso quel flusso, nemmeno con una richiesta diretta.

Il flusso di bootstrap in dettaglio

Il flusso di primo avvio dell'applicazione segue una sequenza precisa:

  • Accesso a /admin/login — il controller verifica se esistono utenti nel database
  • Nessun utente — redirect a /admin/setup con form di registrazione (nome, email, password con requisiti minimi)
  • Invio del form — validazione server-side completa, hashing della password con password_hash() e algoritmo bcrypt
  • Utente creato — redirect al login con flash message di successo
  • Accessi successivi a /admin/setup — se esiste gia un utente, la route restituisce 403 Forbidden

Il FirstUserSetupService

Il FirstUserSetupService, con test unitari dedicati, gestisce questo bootstrap. E un componente che si usa una sola volta — alla prima installazione — e poi diventa inattivo. Ma quella singola esecuzione deve essere impeccabile, perche definisce chi ha il controllo del sistema.

La classe segue il pattern make() del framework ed espone metodi chiari:

  • needsSetup(): bool — verifica se il database ha zero utenti
  • createFirstUser(array $data): User — crea l'utente con validazione e hashing, solo se needsSetup() e true

La semplicita dell'interfaccia e intenzionale. Un servizio che fa due cose — verificare e creare — e un servizio facile da testare, facile da capire, facile da auditare. Non c'e logica nascosta, non ci sono side effect inattesi.

Il valore dei test per il codice di sicurezza

I test del FirstUserSetupService coprono esplicitamente i casi critici: che la creazione fallisca se un utente esiste gia, che la password venga hashata correttamente, che i dati vengano validati prima dell'inserimento. Per il codice di sicurezza, i test non sono un nice-to-have: sono un requisito. Un bug nel flusso di autenticazione ha conseguenze diverse da un bug nel layout — puo compromettere l'intera applicazione.

La scelta di eliminare il seeder admin e piccola ma filosoficamente significativa. E il passaggio da "fiducia nell'utente" (speriamo che cambi la password) a "fiducia nel sistema" (il sistema non permette stati insicuri). In sicurezza informatica, la fiducia nell'utente e sempre mal riposta — i sistemi devono essere sicuri by design, non by speranza.

altri articoli