La checklist di sicurezza PrestaShop 2026 che uso sugli shop in produzione
Undici controlli di sicurezza su un PrestaShop 8.x che vende: advisory dei moduli, permessi, backup, log da leggere e cosa fare dopo un sospetto.
Le guide sulla sicurezza PrestaShop funzionano quasi tutte allo stesso modo: ti spaventano per tre paragrafi e poi ti vendono un modulo. Questa no. Qui sotto ci sono i controlli che faccio davvero su un PrestaShop 8.x che sta vendendo, in ordine di quanto contano, con per ognuno due cose: perché serve e come si verifica in pratica. Se un controllo non lo sai fare da solo, almeno saprai cosa chiedere a chi ti gestisce lo shop.
Un avvertimento onesto prima di partire: non troverai nomi di moduli di sicurezza consigliati. Consiglio un modulo solo dopo averne letto il codice, e per questa categoria non ho ancora fatto quel lavoro. Un modulo che promette sicurezza e che nessuno ha auditato è codice in più che gira con i privilegi del tuo shop: è esattamente la superficie che stiamo cercando di ridurre.
⚠️ Da dove si entra davvero in un PrestaShop
Il core di PrestaShop è software maturo, con un processo di sicurezza pubblico e patch regolari. La statistica che conta, per chi gestisce shop veri, è un’altra: gli avvisi di sicurezza che escono ogni mese riguardano in stragrande maggioranza moduli di terze parti, spesso moduli comprati anni fa, installati una volta e mai più toccati.
Le pubblica FriendsOfPresta, il gruppo che raccoglie e coordina le segnalazioni della community. È l’unica fonte che tengo monitorata in automatico su PrestaShop insieme alle release ufficiali: quando esce un avviso su un modulo, la domanda è sempre la stessa, “quello sta girando su uno dei negozi che seguo?”.
Il tuo shop non viene bucato perché sei importante.
Viene bucato perché uno scanner automatico ha trovato un modulo con un CVE noto e la tua versione era quella vecchia.
Questo cambia anche la priorità delle cose da fare. Prima di irrobustire l’irrobustibile, si chiude quello che è già pubblicamente noto.
✅ 1. Core e moduli aggiornati (e sapere quali hai davvero)
Perché: un avviso pubblico su un modulo è un’istruzione operativa consegnata anche a chi ti attacca. Da quel momento il costo dell’attacco è cercare, non trovare.
Come si verifica: parti dall’inventario, non dagli aggiornamenti. Ti serve l’elenco dei moduli installati e attivi con la loro versione. La strada ufficiale è il back office, in Moduli: la console di PrestaShop 8 espone prestashop:module solo per agire su un modulo (install, uninstall, enable, disable, reset, upgrade, configure), non per elencarli. Se hai accesso al server, l’elenco reale lo dai in due righe:
ls -1 modules/ # cosa sta davvero sul disco
# e dal database, gli installati con versione e stato
# (prefisso ps_ di default, controlla il tuo):
# SELECT name, version, active FROM ps_module ORDER BY name;
Poi confronta quella lista con gli avvisi pubblicati. Il feed degli advisory è leggibile a mano, ma il controllo che regge nel tempo è automatico: io lo tengo dentro il monitoraggio, così quando esce un avviso lo leggo lo stesso giorno invece di scoprirlo tra sei mesi.
Sul core, la regola è meno drammatica di come la raccontano: restare su una versione ancora supportata. Se sei fermo a una 1.6 o 1.7, il problema non è “un aggiornamento in ritardo”, è che le patch di sicurezza per te non escono più. In quel caso il primo controllo di sicurezza è aggiornare alla 8, e va pianificato come una migrazione, non come un clic.
⚠️ 2. Moduli abbandonati: disinstallare, non disattivare
Perché: un modulo abbandonato è la combinazione peggiore. Nessuno gli manda patch e il codice resta a disco. E qui c’è la trappola che vedo più spesso: disattivare un modulo non ne rimuove i file. I suoi controller front, se raggiungibili via URL, in diversi casi rispondono lo stesso. Un modulo “spento” può restare perfettamente sfruttabile.
Come si verifica: fai l’elenco dei moduli e per ognuno chiediti quando è uscita l’ultima versione e se il tuo shop lo usa ancora davvero. Su uno shop che ho ereditato, il back office mostrava da mesi un avviso del fornitore che diceva che il modulo marketplace installato sarebbe presto diventato obsoleto: nessuno lo aveva letto, e la stessa integrazione teneva in piedi il sync degli ordini Amazon ed eBay. Quello è un rischio di sicurezza e, insieme, un problema di fatturato.
Chi non serve più si disinstalla (che rimuove hook e tabelle) e poi si verifica che la cartella sotto modules/ sia sparita.
✅ 3. La cartella admin rinominata (e cosa non risolve)
Perché: PrestaShop rinomina la cartella di amministrazione all’installazione proprio perché /admin sia un bersaglio in meno per gli scanner automatici. Sugli shop che seguo la cartella ha un suffisso casuale (admin + stringa random) e va tenuta così.
Come si verifica: chiama https://iltuoshop.it/admin/ e assicurati che risponda 404, non un redirect al login. Poi controlla che il nome vero non sia scritto da qualche parte in chiaro nel front: capita che un tema o uno script custom lo espongano in un commento HTML o in un file JavaScript.
Se puoi, aggiungi un secondo livello davvero utile: limitare l’accesso alla cartella admin a una lista di IP, o metterla dietro autenticazione HTTP a livello di server. Su uno shop con dipendenti che entrano tutti dalla stessa linea di ufficio è una regola di tre righe nel .htaccess.
🛠️ 4. Permessi dei file: scrivibile solo quello che deve esserlo
Perché: il danno di una vulnerabilità che permette di scrivere un file dipende quasi interamente da dove si può scrivere. Se 755 sulle cartelle e 644 sui file sono la norma e solo poche directory sono scrivibili, molte tecniche non arrivano a nulla.
Come si verifica: le directory che PrestaShop ha bisogno di scrivere sono note e limitate (var/, img/, upload/, download/, translations/, config/themes/, le cache dei temi). Tutto il resto non deve essere scrivibile dal processo web. Il controllo veloce, via SSH:
# file o cartelle scrivibili da tutti: non dovrebbero esistere
find . -perm -o+w -not -path "./var/*" | head -50
# file PHP con data di modifica recente fuori dai percorsi attesi
find . -name "*.php" -mtime -7 -not -path "./var/*"
Il secondo comando è quello che mi ha salvato più volte: un file PHP modificato o creato di recente in un punto dove non hai messo mano tu è il segnale più concreto che ci sia, e non richiede nessuno strumento a pagamento per essere letto.
✅ 5. Backup che qualcuno ha provato a ripristinare
Perché: il backup è l’unico controllo di questa lista che trasforma un disastro in una nottata storta. Ed è anche quello dove trovo più illusioni: backup che girano da anni e che nessuno ha mai riaperto.
Come si verifica: una volta, davvero, prendi l’ultimo backup e ripristinalo su un ambiente di staging. Devi poter rispondere a quattro domande: ogni quanto gira, quanti giorni di storico tiene, se comprende file e database (non solo uno dei due), e quanto ci metti a rimettere online lo shop. Se una di queste risposte è “non lo so”, non hai un backup, hai una speranza.
Aggiungo un requisito che sembra pedante e non lo è: i backup non devono stare solo sullo stesso server dello shop. Vale per i ransomware, ma vale ancora di più per il caso banale, che è di gran lunga il più frequente: il fornitore hosting che ha un problema e ti porta via tutto insieme.
✅ 6. Utenti del back office: chi entra, da dove, e chi non c’è più
Perché: la via d’ingresso più semplice non è un exploit, è un account. Il consulente di due anni fa, il tirocinante, l’agenzia precedente: tutti profili che spesso sono ancora attivi, spesso con permessi da SuperAdmin.
Come si verifica: apri l’elenco dei dipendenti nel back office e per ognuno rispondi a “questa persona lavora ancora con noi e le serve questo livello?”. Chi non serve si disattiva, non si cancella soltanto, se ci sono azioni storiche legate al suo profilo.
Poi vai a guardare da dove entrano. PrestaShop registra nei log applicativi la riga “Connessione al back office da …”: è il dato che ti dice quanti profili entrano davvero, con che frequenza e da quali indirizzi. Su uno shop mi è servito esattamente a questo, e mi ha permesso di scoprire in mezz’ora che tre dipendenti su quattro entravano tutti dalla stessa linea di ufficio ogni mattina alle 8:30: una volta saputo, la regola per limitare l’accesso admin diventa scrivibile senza rischiare di tagliare fuori qualcuno.
Sull’igiene delle credenziali basta poco e non serve teoria: password lunghe e diverse per ogni servizio, e nessuna condivisa in chat. Il secondo fattore per il login al back office non è incluso in PrestaShop 8: il supporto nativo è ancora una pull request aperta sul repository del progetto, quindi oggi va aggiunto da fuori. Se lo vuoi, valutalo a monte del web server (autenticazione HTTP o accesso dietro VPN) prima che con un modulo.
🛠️ 7. I log: quattro file, non uno
Perché: praticamente ogni incidente che ho diagnosticato era già scritto in un log che nessuno stava leggendo. La sicurezza operativa, su un e-commerce, è al 90% “guardare le cose giuste una volta ogni tanto”.
Come si verifica: sono quattro fonti diverse e servono a cose diverse.
| Log | Dove sta | Cosa ci trovi |
|---|---|---|
| Log applicativo PrestaShop | tabella ps_log, back office in Parametri avanzati | connessioni al back office, errori dei moduli, eventi di sistema |
| Log PHP | error_log nella webroot, o dove lo mette l’hosting | eccezioni, fatal error, righe di codice che rompono |
| Access log HTTP | log del dominio sull’hosting | chi ti chiama, con che user agent, quali URL, quanti 404 |
| Log dei cron e degli import | dipende dagli script | job fermi in silenzio, sync che non gira più |
Se l’hosting non ti dà SSH, questi log si leggono lo stesso dal pannello e via FTP: il percorso passo per passo l’ho messo in diagnosi PrestaShop senza SSH.
Nell’access log il pattern che cerco per primo sono i 404 di massa su percorsi che non esistono: /wp-admin, /wp-login.php, .env, /vendor/phpunit/.... Su un PrestaShop sono tutti tentativi ciechi contro software che non hai, quindi innocui in sé, ma dicono quanto sei battuto e servono come rumore di fondo di riferimento. Quello che va guardato con attenzione sono invece i 200 anomali: una URL strana che risponde, un file PHP che non riconosci servito con successo.
Il secondo pattern è il volume. Su uno shop che seguo, l’access log ha mostrato 97.000 richieste al giorno che arrivavano da circa 93.000 indirizzi IP diversi, tutte sulla stessa pagina categoria con i filtri applicati. Non era un attacco mirato: era una botnet che macinava la ricerca a faccette e con quello mandava in ginocchio PHP e MySQL. Non si tratta di una falla di sicurezza, ma il risultato per chi vende è identico a un attacco: shop inutilizzabile. Si è chiusa a monte, con una regola nel .htaccess che rimanda quelle richieste alla pagina pulita servita dalla cache, senza toccare PHP.
⚠️ 8. Il codice su misura è superficie d’attacco quanto un modulo
Perché: override e moduli custom sono la parte del tuo shop che nessuno auditerà mai al posto tuo. Non compaiono in nessun advisory perché esistono solo da te.
Come si verifica: il controllo che dà più risultati per minuto speso è cercare i parametri che entrano dalla richiesta e finiscono in una query senza essere sanificati. In PrestaShop il valore in arrivo si legge con Tools::getValue() e va sempre passato a pSQL() (o castato, se è un numero) prima di entrare in SQL:
grep -rn "Tools::getValue" override/ modules/<tuo-modulo>/ | grep -v "pSQL\|(int)\|(bool)\|(float)"
Su uno shop che ho preso in carico questo controllo ha trovato una SQL injection reale in un override della ricerca prodotti: un parametro della querystring finiva dritto nella WHERE senza pSQL(). Il file era stato scritto anni prima da chi gestiva il sito e da allora nessuno lo aveva più riletto. Fix da una riga, ma il punto sta altrove: nessuno strumento automatico lo avrebbe segnalato, perché quel codice non appartiene a nessun vendor.
Stessa logica per l’output verso il browser (le variabili in Smarty vanno escapate) e per gli upload, dove il file va validato per contenuto e la cartella di destinazione non deve poter eseguire PHP.
⚠️ 9. Verifica che la configurazione che hai scritto sia quella che gira
Questa non è una voce che troverai nelle altre checklist e per me sta tra le più importanti, perché l’ho presa in faccia sul mio stesso sito.
A luglio ho fatto un audit di sicurezza completo del sito che leggi adesso. Gli header di sicurezza erano configurati, il codice era giusto, tutto committato. In produzione non arrivavano. Motivo: il .htaccess che il server leggeva davvero non era quello del repository, era una copia messa a mano nella document root mesi prima, che da allora divergeva in silenzio. Ogni regola aggiunta dopo quella data era lettera morta, e niente lo segnalava: né la build, né i test, né un errore.
Una configurazione di sicurezza non verificata dall’esterno
è una configurazione che non sai se esiste.
Come si verifica: dall’esterno, con una richiesta vera, non leggendo i tuoi file. Gli header di risposta si guardano in un colpo:
curl -sI https://iltuoshop.it/ | grep -iE "strict-transport|content-security|x-frame|x-content-type|referrer-policy"
Stesso principio per tutto il resto: che HTTPS sia forzato per davvero (http:// deve rispondere 301), che i cookie di sessione abbiano Secure e HttpOnly, che i file che non devono essere pubblici non lo siano. Questi tre valgono un test ciascuno, non un’assunzione:
curl -sI https://iltuoshop.it/.env
curl -sI https://iltuoshop.it/app/config/parameters.php
curl -sI https://iltuoshop.it/.git/config
Devono rispondere 403 o 404. Se uno dei tre risponde 200, hai trovato il problema più grave della giornata.
✅ 10. Ambiente: PHP supportato, e lo stesso ovunque
Perché: una versione di PHP fuori supporto non riceve più patch, e il resto della checklist non compensa. Ma c’è un caso meno ovvio e più insidioso: web e cron che girano su versioni diverse.
Come si verifica: leggi la versione dal browser (nel back office, in Informazioni di configurazione) e poi da riga di comando dentro un cron. Su uno shop che ho ereditato le due non coincidevano: il PHP dei cron era già stato migrato dall’hosting, quello del web no. Non riguarda solo la sicurezza, è una fonte di bug che sembrano stregoneria, perché lo stesso codice si comporta in due modi diversi a seconda di chi lo esegue.
Sempre qui: la modalità debug deve essere spenta in produzione (_PS_MODE_DEV_ a false in config/defines.inc.php). Con il debug acceso, un errore mostra al pubblico percorsi assoluti, query e a volte credenziali.
🛠️ 11. Cosa fare DOPO un sospetto
Il momento in cui si fanno i danni più grossi sono i minuti dopo aver visto qualcosa di strano: una pagina che non è quella, un file che non riconosci, il dubbio che il PrestaShop sia stato hackerato. L’istinto è cancellare e ripulire. È l’ordine sbagliato: se cancelli, perdi le prove e con quelle la risposta alla domanda che conta, cioè da dove è entrato. Se non lo sai, dopo la pulizia rientra dalla stessa porta.
L’ordine che seguo, tarato su un incidente vero.
- Congela le prove, non purgare. Su uno shop mi sono ritrovato con 109 entry di cache avvelenate che servivano JSON grezzo al posto delle pagine categoria, in cinque lingue, memorizzate con una durata di sette giorni. La cosa veloce sarebbe stata un purge totale della cache. Invece le ho spostate in una cartella di quarantena mantenendo i percorsi relativi: lo shop è tornato a servire pagine buone subito (le voci mancanti si rigenerano da sole al primo accesso), e il materiale è rimasto lì da analizzare. È dai timestamp di quei file che sono venute fuori la finestra temporale dell’attacco e la firma di chi la stava sfruttando.
- Delimita: quanto e da quando. Guarda le date di modifica dei file, gli access log nella finestra individuata, i log applicativi. Il primo giro non li trova quasi mai tutti: sullo stesso incidente, un secondo passaggio il giorno dopo ha trovato altre 85 voci che il primo criterio di ricerca non prendeva, ed erano quelle a lasciare ancora qualche pagina bianca.
- Chiudi il buco, poi pulisci. Se rimuovi gli effetti senza chiudere la causa, tornano. In quel caso la causa era un modulo che marcava come cacheabile qualunque risposta, JSON incluso: la correzione è stata un controllo a monte, “se la risposta non è HTML, non salvarla”.
- Cambia le credenziali, tutte. Utenti del back office, database, FTP e SSH, API dei moduli. Le chiavi API dei servizi di pagamento e dei marketplace si rigenerano dai rispettivi pannelli. Farlo a metà equivale a non farlo.
- Ripristina da un backup precedente all’incidente, se il codice è stato toccato. Prima della finestra che hai delimitato al punto 2: qui si vede se il punto 5 della checklist era vero o era una speranza.
- Metti una sentinella. Dopo quell’incidente ho aggiunto al cruscotto di controllo dello shop un check che riscansiona periodicamente i file di cache e conta le voci anomale. Non previene niente, ma trasforma il prossimo incidente da “un cliente ci ha scritto che vede una pagina strana” a una riga in un report.
✅ La checklist, in breve
[ ] core su una versione ancora supportata
[ ] moduli aggiornati e confrontati con gli advisory pubblicati
[ ] moduli inutili disinstallati (non solo disattivati), cartelle rimosse
[ ] cartella admin rinominata, /admin risponde 404, nome non esposto nel front
[ ] permessi: scrivibile solo il necessario, nessun file PHP recente inatteso
[ ] backup file + database, fuori dal server, ripristinato almeno una volta
[ ] utenti back office ripuliti, accessi verificati dai log
[ ] log letti: applicativo, PHP, access HTTP, cron
[ ] override e moduli custom: nessun getValue senza pSQL o cast
[ ] header di sicurezza e file sensibili verificati con curl dall'esterno
[ ] PHP supportato, stessa versione su web e cron, debug spento
[ ] piano scritto per il "dopo": quarantena, credenziali, ripristino
Nessuna di queste voci richiede un modulo a pagamento. Richiedono un’ora, una volta ogni tanto, e la volontà di aprire dei log. È la stessa lista che passo quando faccio l’audit tecnico di un sito e-commerce, solo che lì la percorro io e ti consegno i risultati in ordine di gravità.
✅ Ti serve una verifica vera
Se hai letto fin qui e su tre o quattro voci la risposta è “non lo so”, quello non è un problema di sicurezza: è un problema di visibilità sul tuo negozio, ed è risolvibile in poche ore. Passo questa lista sul tuo shop e ti dico cosa si chiude subito e cosa si può pianificare, con i comandi che ho usato per arrivarci; per gli interventi continuativi fa parte del mio servizio di assistenza PrestaShop. Scrivimi da uno dei canali qui sotto, dicendomi versione di PrestaShop e hosting: ti dico in giornata se c’è qualcosa da guardare con urgenza.
❓ Domande frequenti
Ogni quanto vanno fatti questi controlli su un PrestaShop?
Serve un modulo di sicurezza per PrestaShop?
Rinominare la cartella admin serve davvero a qualcosa?
Come capisco se il mio shop è stato compromesso?
Ho un sospetto: la prima cosa da fare è pulire tutto?
Sono ancora su PrestaShop 1.6 o 1.7: quanto è grave?
Fonti: advisory di sicurezza FriendsOfPresta, pagina sicurezza del progetto PrestaShop, release ufficiali PrestaShop. Gli episodi citati vengono da interventi reali su shop che gestisco, riportati senza riferimenti ai clienti.
Hai un progetto in testa?
Raccontami cosa ti serve o cosa non funziona. Rispondo entro 24 ore, senza preventivi a scatola chiusa.