Vai al contenuto principale
enricomorano.it/blog/checklist-sicurezza-prestashop← ../
Sicurezza PrestaShop: la checklist 2026 per shop in produzione
▸ Assistenza PrestaShop

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.

12 settembre 2026agg. 25 settembre 2026#prestashop#sicurezza#manutenzione#ecommerce

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.

LogDove staCosa ci trovi
Log applicativo PrestaShoptabella ps_log, back office in Parametri avanzaticonnessioni al back office, errori dei moduli, eventi di sistema
Log PHPerror_log nella webroot, o dove lo mette l’hostingeccezioni, fatal error, righe di codice che rompono
Access log HTTPlog del dominio sull’hostingchi ti chiama, con che user agent, quali URL, quanti 404
Log dei cron e degli importdipende dagli scriptjob 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.

▸ Caso studio realePrestaShop lento e in 503 sotto i bot: era la cache5.047 errori 503 in 24 ore su una sola categoria. Non il server, non la versione: una cache LiteSpeed disallineata sotto il traffico dei crawler. Diagnosi dagli access log, fix senza scrivere codice.Leggi il caso →

⚠️ 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.

  1. 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.
  2. 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.
  3. 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”.
  4. 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.
  5. 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.
  6. 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?
Gli avvisi sui moduli vanno visti quando escono, quindi il controllo utile è automatico e continuo, non a calendario. La checklist completa una volta a trimestre è una cadenza sensata per uno shop che vende tutti i giorni, con un giro in più dopo ogni aggiornamento importante o dopo l'installazione di un modulo nuovo.
Serve un modulo di sicurezza per PrestaShop?
Non come primo passo, e non alla cieca. Un modulo che promette sicurezza è codice aggiuntivo che gira con i privilegi del tuo shop: se non è mantenuto e non lo ha auditato nessuno, aggiunge superficie invece di toglierla. Aggiornamenti, permessi corretti, backup verificati e log letti coprono la gran parte del rischio reale senza installare niente.
Rinominare la cartella admin serve davvero a qualcosa?
Serve a togliere il traffico automatico che tenta /admin alla cieca, e questo rende i log molto più leggibili. Non protegge da chi ha una credenziale valida né da una vulnerabilità in un modulo: va trattata come igiene di base, non come misura di difesa. Limitare l'accesso per IP o metterlo dietro autenticazione a livello di server vale molto di più.
Come capisco se il mio shop è stato compromesso?
I segnali più affidabili sono file PHP creati o modificati di recente in punti dove non hai messo mano, richieste con esito 200 su URL che non riconosci negli access log, utenti nuovi nel back office, redirect o contenuti che compaiono solo per certi visitatori o solo per i motori di ricerca, e mail in uscita dal server che non hai inviato tu.
Ho un sospetto: la prima cosa da fare è pulire tutto?
No. Se cancelli prima di aver capito da dove è entrato, perdi le prove e dopo la pulizia rientrano dalla stessa porta. L'ordine è: congelare quello che trovi spostandolo in quarantena invece di eliminarlo, delimitare la finestra temporale dai log, chiudere la causa, cambiare tutte le credenziali e solo allora ripristinare da un backup precedente all'incidente.
Sono ancora su PrestaShop 1.6 o 1.7: quanto è grave?
È il punto più critico della lista, perché sulle versioni non più supportate le patch di sicurezza semplicemente non escono. Nessuno degli altri controlli compensa quel buco. In quel caso il primo intervento di sicurezza è la migrazione a una versione supportata, pianificata in staging con backup verificato.

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.

Enrico Morano
Sviluppatore PrestaShop freelance da quasi 10 anni - debug, performance, moduli custom

Hai un progetto in testa?

Raccontami cosa ti serve o cosa non funziona. Rispondo entro 24 ore, senza preventivi a scatola chiusa.

Descrivi il tuo progetto →il form guidato, 2 minuti
Scrivimi una mailemail
Scrivimi su WhatsAppdi solito rispondo in giornata