Mi sono dimenticato di aggiornare Livewire. E mi hanno hackerato
La versione breve: Qualcuno ha sfruttato una versione obsoleta di Livewire su un mio side project dormiente. Hanno rubato il mio file .env, hanno usato le chiavi API di Mailcoach per inviare 50.000 email di spam, e ho passato una notte nel panico a rovistare in ogni progetto che possiedo cercando di risalire alla fonte.
Ecco la storia completa, cosa ho imparato e perché Docker mi ha salvato da un esito molto peggiore.
Era mercoledì 20 maggio. Ero a lezione quando il telefono ha vibrato con un'email da Mailcoach:
I tuoi invii sono stati bloccati a causa di un alto tasso di bounce o di segnalazioni di spam.
L'ho letta. Ho sentito quella fitta fredda allo stomaco. E poi ho dovuto mettere via il telefono e finire la lezione.
C'è un tipo speciale di angoscia che nasce dal sapere che qualcosa non va senza poterci guardare. Ho passato il resto della mia lezione di giapponese con metà del cervello che elaborava gli scenari peggiori.
Verso le 18:00 ho finalmente aperto il portatile.
Il momento del terrore
Ho fatto login su Mailcoach e il cuore mi si è fermato. Erano state inviate oltre 50.000 email dal mio account. Tutte spam. Link di phishing. Spedite a nome mio.
Non avevo mai vissuto niente del genere. Ero scioccato. La mia reazione immediata è stata eliminare ogni singolo token API su Mailcoach e i miei token API di GitHub. Poi ho scritto al loro team di supporto chiedendo aiuto per capire come fosse successo.
La lunga notte
Ho passato le nove ore successive a esaminare ogni progetto che possiedo.
danielpetrica.com. laraplugins.io. adventcalendar.tech. E altri progetti più piccoli e inutilizzati. Ogni piccolo sito demo, ogni esperimento, ogni progetto dormiente che sta sul mio server. Ho controllato i log, controllato i permessi dei file, controllato qualsiasi cosa insolita. Niente.
Per peggiorare le cose, quello stesso giorno Symfony ha annunciato 19 CVE nei suoi progetti. Il mio cervello è andato subito lì. Era Symfony? Uno dei miei siti girava su una versione vulnerabile? Mi sono infilato in quella tana del coniglio per un bel po'.
Niente.
Alle 3 del mattino ho dovuto prendere una decisione. Ho messo in sicurezza quello che potevo, ho cambiato quello che potevo e sono andato a dormire. Ero frustrato. Ero stanco. E non avevo ancora idea di cosa fosse successo.
Trovare la fonte
Il giorno dopo ho continuato a scavare. Progetto dopo progetto. E poi l'ho trovato.
Un piccolo side project. Una di quelle cose che costruisci, lanci e dimentichi. Girava su una versione obsoleta di Livewire con una CVE pubblica. Non l'avevo aggiornata. È stata colpa mia.
L'attaccante l'ha trovato tramite scansione automatizzata. Questi bot scansionano il web in cerca di vulnerabilità note nelle applicazioni esposte. Hanno trovato Livewire, hanno trovato la CVE ed erano dentro nel giro di poche ore. Hanno caricato uno script di web admin che permetteva loro di leggere qualsiasi cosa l'utente Apache potesse raggiungere all'interno di quel container Docker.
Incluso il mio file .env. Che conteneva le mie chiavi API di Mailcoach.
La benedizione di Docker
Ecco il punto in cui le cose sarebbero potute andare molto peggio.
Quel side project girava dentro un container Docker. L'attaccante aveva accesso a quel container, ma non poteva uscirne. Non poteva raggiungere i miei altri progetti, i miei altri database o il sistema host stesso. Il raggio d'azione era limitato a quel singolo servizio.
All'inizio avevo configurato Docker Compose solo per comodità mia. Sul momento non l'ho mai considerato una misura di sicurezza. Ma alla fine è stato il muro che ha impedito all'attacco di diffondersi.
Le prove che ho perso
Questa parte fa ancora male.
Quando ho finalmente identificato il container compromesso, ho fatto la cosa naturale. L'ho abbattuto: docker compose down -v. Volumi inclusi.
E così, i file dell'attaccante erano spariti. La web shell, i log di quello che avevano fatto, qualsiasi indizio sul loro punto di ingresso, tutto cancellato.
Ho capito il mio errore più tardi. Avrei dovuto copiare lo storage del container prima di ucciderlo. Avrei dovuto preservare le prove. Ma in quel momento il mio unico pensiero era: "Spegnilo subito."
Ho poi passato le ore successive a esaminare invece i log del mio reverse proxy. Quelli erano sopravvissuti. Mostravano chiaramente il pattern dell'attaccante. Gli scanner automatizzati colpivano il sito ripetutamente. Una volta confermata la vulnerabilità di Livewire, la compromissione vera e propria è avvenuta nel giro di poche ore. Non è stato un attacco mirato contro di me. Ero solo un altro dominio su una lista.
Quello che mi ha spaventato di più è stata la velocità con cui è successo tutto. La scansione, l'exploit, la raccolta delle credenziali, la campagna di spam. Sembrava automatizzato dall'inizio alla fine. Se l'AI sta rendendo questi attacchi più rapidi ed efficienti, dovremo tutti essere molto più proattivi su monitoraggio e manutenzione. Me compreso.
Il lato positivo
Mailcoach ha gestito la situazione meglio di quanto potessi sperare.
Hanno notato il picco di spam prima di me. Hanno sospeso i miei invii in modo proattivo. Quando li ho contattati, hanno collaborato con me alle indagini. E quando la polvere si è posata, hanno eliminato del tutto dalla mia fattura gli addebiti per quelle oltre 50.000 email.
È quel tipo di comportamento da parte di un provider che crea fedeltà a vita.
Grazie al team di Mailcoach.
Cosa ho cambiato
Da quando è successo, ho apportato alcune modifiche:
- Ho impostato avvisi automatici di aggiornamento delle dipendenze per ogni progetto, inclusi quelli dormienti. Se un progetto ha un
composer.json, ricevo una notifica quando le sue dipendenze sono obsolete. - Ho fatto una revisione di tutti i miei side project. Alcuni sono stati aggiornati. Alcuni archiviati. Alcuni chiusi del tutto.
- Ho rivisto la mia strategia di token API. Ora i token hanno scope rigorosi e durate più brevi dove possibile.
- Sto anche esaminando strategie di gestione delle variabili d'ambiente e cercando di allinearle meglio al mio setup Docker.
- Ho accettato di aver bisogno di un monitoraggio migliore. Un avviso delle 15:52 su cui non posso agire prima delle 18:00 è inutile se non ho un piano per quel lasso di tempo.
La verità scomoda
È successo perché ho commesso un errore. Avevo un sito pubblico e dormiente con una dipendenza obsoleta. Lo sapevo bene; semplicemente non l'ho considerato una priorità finché non mi sono dimenticato del sito del tutto.
Ma la lezione non è solo "stai più attento". È che il nostro settore ha una lunga coda di progetti dimenticati che sono bombe a orologeria. Ogni sviluppatore che conosco ha side project che prendono polvere su un server da qualche parte. Sono esattamente quello che gli scanner cercano.
Vai ad aggiornare le tue dipendenze. Oppure chiudi quello che non mantieni. Perché i bot non aspetteranno che tu abbia tempo. L'ho imparato a mie spese.
Divertiti a costruire. E aggiorna Livewire, per favore.
P.S. Ne ero già convinto prima, ma ora ne sono certo: Mailcoach è il miglior strumento di email per campagne ed email transazionali. Andate a dare un'occhiata qui (link di referral).
Altri articoli recenti
Laravel AI 1.1 e 1.2: Agent Skills, Cohere e structured output più solidi
Le release 1.1.0 e 1.2.0 di laravel/ai portano gli Agent Skills, l'approvazione obbligatoria per i tool built-in e nuovi provider come Cohere e Laya self-hosted. Sul fronte qualità arrivano i fix allo structured output per Bedrock e il supporto alle provider options. Aggiornati anche i modelli di default, con Claude 4.7+ che ignora i sampling params.
Laravel 13.35.0: scheduler più controllabile, code più flessibili e response Markdown
Laravel 13.35.0 porta Schedule::alwaysOnOneServer(), il supporto a schedule:interrupt per i comandi di lunga durata, --memory in percentuale per queue:work e il nuovo metodo markdown() sulla response factory. Tante piccole migliorie anche a test, view compilate in parallelo e dischi local.
BashBox: un interprete Bash in sandbox per agenti AI in PHP
BashBox è un interprete bash scritto in puro PHP che permette di eseguire gli script generati dagli agenti AI senza mai ricorrere a proc_open, exec o shell_exec. Ogni comando è una classe PHP che lavora su un filesystem virtuale, con limiti di esecuzione, quote disco e accesso di rete configurabili. Ideale per chi sviluppa agenti con il Laravel AI SDK o altre librerie simili.