Knowledge Base Guide

Seguridad PrestaShop: La lista de verificación completa

Guía de seguridad para tiendas PrestaShop — protección del servidor, administración segura, auditoría de módulos, seguridad de base de datos y respuesta ante incidentes.

Blindaje de Seguridad para PrestaShop: La Lista de Verificación Completa

Cada semana, miles de tiendas PrestaShop son comprometidas. Los propietarios se enteran cuando Google marca su sitio, cuando los clientes reportan tarjetas robadas, o cuando la página de inicio redirige a spam. El daño es real: pérdida de ingresos, confianza destruida, responsabilidad bajo el RGPD y semanas de reparación.

Esta guía proviene de años de limpiar tiendas hackeadas. Cada recomendación aborda una vulnerabilidad real que hemos visto explotada en producción. Sígala de arriba a abajo.

1. Por qué las tiendas PrestaShop son hackeadas

Inyección SQL en módulos de terceros

Este es el vector de ataque número uno, y por amplio margen. Los módulos de desarrolladores sin experiencia a menudo pasan la entrada del usuario directamente a las consultas SQL. Un atacante envía una solicitud manipulada al controlador frontal de un módulo y extrae toda su base de datos. La vulnerabilidad casi nunca está en el núcleo de PrestaShop — está en los módulos.

Fuerza bruta en el panel de administración

PrestaShop no tiene limitación de intentos integrada. Un atacante que conozca el nombre de su directorio de administración puede ejecutar miles de combinaciones de contraseñas por minuto. Cualquier cuenta que use admin123 o el nombre de la empresa será descifrada en minutos.

Vulnerabilidades de carga de archivos

Algunos módulos permiten la carga de archivos sin validación adecuada. Un atacante sube un shell PHP disfrazado de imagen, accede a él a través del navegador y obtiene control total del servidor.

PHP y software desactualizados

Las versiones de PHP fuera de soporte tienen vulnerabilidades documentadas públicamente con exploits funcionales. Lo mismo aplica a versiones desactualizadas de PrestaShop, Apache y MySQL.

Archivos de configuración expuestos

Los servidores mal configurados sirven archivos .env, directorios .git y configuraciónes YAML a cualquiera que los solicite — revelando credenciales de base de datos y secretos de cifrado.

Revisión de realidad: La mayoría de los propietarios piensan “mi tienda es demasiado pequeña para ser un objetivo”. A los escáneres automatizados no les importa el tamaño. Escanean cada IP en internet. Si usted ejecuta PrestaShop, es un objetivo.

2. Seguridad a nivel de servidor

Versión y configuración de PHP

Ejecute la versión más reciente de PHP que su PrestaShop soporte — PHP 8.1+ para PS 8.x, PHP 8.1-8.4 para PS 9.x. Nunca ejecute una versión fuera de soporte.

Blindaje clave de php.ini:

disable_functions = exec,passthru,shell_exec,system,proc_open,popen
expose_php = Off
allow_url_include = Off
display_errors = Off
log_errors = On
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1
session.cookie_samesite = Lax
open_basedir = /var/www/html:/tmp:/usr/share/php
Nota: Algunos módulos necesitan exec() para el procesamiento de imágenes o la generación de PDF. Si un módulo deja de funcionar, reactive únicamente la función específica que requiere.

Permisos de archivos

  • Directorios: 755 — propietario lectura/escritura/ejecución, otros lectura/ejecución
  • Archivos: 644 — propietario lectura/escritura, otros solo lectura
  • Archivos de configuración: 400app/config/parameters.php debe ser solo lectura para el propietario
chown -R www-data:www-data /var/www/html/prestashop
find /var/www/html/prestashop -type d -exec chmod 755 {} \;
find /var/www/html/prestashop -type f -exec chmod 644 {} \;
chmod 400 /var/www/html/prestashop/app/config/parameters.php

# Writable directories PrestaShop needs
chmod -R 775 /var/www/html/prestashop/var/cache
chmod -R 775 /var/www/html/prestashop/var/logs
chmod -R 775 /var/www/html/prestashop/img
chmod -R 775 /var/www/html/prestashop/upload
chmod -R 775 /var/www/html/prestashop/download

Nunca establezca nada en 777. Si un tutorial le dice que ejecute chmod 777, busque un tutorial mejor.

Configuración de SSL/TLS

Active SSL en PrestaShop (Parámetros de la tienda > General), luego añada las cabeceras HSTS:

# Apache .htaccess
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
# Nginx
server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$server_name$request_uri;
}
server {
    listen 443 ssl http2;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}

Desactivar el listado de directorios y blindar .htaccess

Añada estas reglas a su .htaccess raíz:

Options -Indexes

# Block sensitive file types
<FilesMatch "\.(env|yml|yaml|log|sql|bak|old|orig|save|swp|dist|config|ini|phps)$">
    Require all denied
</FilesMatch>

# Block hidden files and directories (.git, .env, etc.)
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule (^\.|/\.) - [F]
</IfModule>

# Block composer files
<FilesMatch "^(composer\.json|composer\.lock)$">
    Require all denied
</FilesMatch>

# Block config, vendor, and log directories
<IfModule mod_rewrite.c>
    RewriteRule ^config/ - [F]
    RewriteRule ^vendor/ - [F]
    RewriteRule ^var/logs/ - [F]
    RewriteRule ^app/config/ - [F]
</IfModule>

# Block PHP execution in upload directories
<Directory "/var/www/html/prestashop/upload">
    <FilesMatch "\.ph(p[3457]?|t|tml)$">
        Require all denied
    </FilesMatch>
</Directory>

<Directory "/var/www/html/prestashop/img">
    <FilesMatch "\.ph(p[3457]?|t|tml)$">
        Require all denied
    </FilesMatch>
</Directory>

Equivalente en Nginx:

location ~* \.(env|yml|yaml|log|sql|bak|old|swp|dist|config|ini)$ { deny all; return 404; }
location ~ /\. { deny all; return 404; }
location ~* ^/(upload|img|download)/.*\.php$ { deny all; return 404; }
location ~* ^/(config|vendor|var/logs|app/config)/ { deny all; return 404; }
autoindex off;
Pruébelo: Después de añadir estas reglas, intente acceder a https://yourshop.com/.env y https://yourshop.com/app/config/parameters.php en su navegador. Debería obtener 403 o 404 — nunca el contenido real.

3. Seguridad del panel de administración de PrestaShop

Renombrar el directorio de administración

PrestaShop genera un nombre aleatorio para el directorio de administración durante la instalación. Nunca lo renombre a admin, backoffice o panel. Si es predecible, cámbielo:

mv /var/www/html/prestashop/admin /var/www/html/prestashop/admin-x7k9m2p4
rm -rf /var/www/html/prestashop/var/cache/*

Use al menos 10 caracteres aleatorios. Guarde la URL en marcadores — no necesita ser fácil de recordar.

Contraseñas robustas y 2FA

Cada cuenta de administración debe usar una contraseña única de 16 o más caracteres generada por un gestor de contraseñas. Sin excepciones.

Active la autenticación de dos factores para todas las cuentas (Parámetros avanzados > Administración). PrestaShop 1.7.6+ soporta Google Authenticator de forma nativa. Esta única medida detiene la gran mayoría de los ataques de fuerza bruta.

Limitar el acceso de administración por IP

Si su equipo trabaja desde IPs fijas, restrinja el acceso de administración en consecuencia:

# .htaccess inside admin directory
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REMOTE_ADDR} !^203\.0\.113\.10$
    RewriteCond %{REMOTE_ADDR} !^198\.51\.100\.20$
    RewriteRule .* - [F,L]
</IfModule>

Si utiliza una VPN, restrinja a la IP de la VPN — los empleados trabajan desde cualquier lugar manteniéndose restringidos por IP.

Desactivar cuentas de empleados innecesarias

Audite las cuentas de empleados regularmente (Parámetros avanzados > Equipo > Empleados):

  • Elimine las cuentas de exempleados y contratistas
  • Elimine las cuentas de prueba de la configuración inicial
  • Asegúrese de que cada empleado tenga el perfil mínimo necesario — el personal de almacén no necesita SuperAdmin

Monitoreo de inicio de sesión de administración

Configure fail2ban para protección contra fuerza bruta:

# /etc/fail2ban/filter.d/prestashop-admin.conf
[Definition]
failregex = ^<HOST> -.*"POST .*/admin.*/index\.php\?controller=AdminLogin.*" (200|302)

# /etc/fail2ban/jail.d/prestashop.conf
[prestashop-admin]
enabled = true
filter = prestashop-admin
logpath = /var/log/apache2/access.log
maxretry = 5
findtime = 600
bantime = 3600

4. Seguridad de módulos

Los módulos son la mayor superficie de ataque en cualquier instalación de PrestaShop. Trate cada módulo como un riesgo potencial hasta que se demuestre lo contrario.

Instale solo desde fuentes confiables

Fuentes seguras: PrestaShop Addons Marketplace, desarrolladores establecidos con trayectoria comprobada y módulos de código abierto bien mantenidos en GitHub.

Nunca instale módulos de sitios “nulled” o de “descarga gratuita”, de desarrolladores desconocidos o de publicaciones aleatorias en foros.

Advertencia: Los módulos nulled (pirateados) son la forma más rápida de ser hackeado. Los atacantes inyectan puertas traseras en módulos legítimos y los distribuyen gratuitamente. La puerta trasera les da control sobre cada tienda que lo instale. Lo hemos visto cientos de veces. No hay excepciones.

Audite el código de los módulos

Antes de instalar cualquier módulo, busque estas señales de alerta:

# Dangerous — arbitrary code execution
eval($variable)
eval(base64_decode($something))
assert($user_input)

# Dangerous — remote code loading
file_get_contents('http://external-domain.com/...')
include('http://...')

# Dangerous — unsanitized SQL
"SELECT * FROM ps_table WHERE id = " . $_GET['id']
Db::getInstance()->execute("... " . $_POST['value'] . " ...")

El código seguro utiliza consultas parametrizadas y los métodos de validación de PrestaShop:

// SAFE: Cast to integer, use pSQL()
$id = (int)Tools::getValue('id');
$name = pSQL(Tools::getValue('name'));

Mantenga los módulos actualizados

  • Compruebe las actualizaciones al menos semanalmente
  • Suscríbase a los boletines de seguridad de los desarrolladores
  • Siga los avisos de seguridad de Friends of Presta para CVEs de módulos de PrestaShop
  • Siempre haga una copia de seguridad antes de actualizar

Elimine los módulos no utilizados completamente

Desactivar un módulo no es suficiente. Los archivos de un módulo desactivado siguen existiendo en su servidor y sus controladores frontales permanecen accesibles mediante URL directa. Si tiene una vulnerabilidad, desactivarlo no proporciona ninguna protección.

# Uninstall via Back Office, then delete the files
rm -rf /var/www/html/prestashop/modules/unused_module

Revise su lista de módulos ahora. Si instaló algo para probar hace seis meses — elimínelo. Cada módulo no utilizado es superficie de ataque innecesaria.

Audite los permisos de los módulos

find /var/www/html/prestashop/modules -type d -exec chmod 755 {} \;
find /var/www/html/prestashop/modules -type f -exec chmod 644 {} \;

5. Seguridad de la base de datos

Nunca use root para la aplicación

Cree un usuario dedicado con permisos mínimos:

CREATE USER 'prestashop_user'@'localhost' IDENTIFIED BY 'long-random-password';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER,
      CREATE TEMPORARY TABLES, LOCK TABLES
      ON prestashop_db.* TO 'prestashop_user'@'localhost';
FLUSH PRIVILEGES;

Si un atacante explota una inyección SQL, un usuario limitado restringe el daño. Root puede acceder a otras bases de datos, leer archivos del servidor y ejecutar comandos del sistema.

Copias de seguridad regulares

# Crontab entries
# Database backup — daily at 3 AM
0 3 * * * mysqldump -u backup_user -p'password' prestashop_db | gzip > /backups/db/ps_$(date +\%Y\%m\%d).sql.gz

# File backup — daily at 3:30 AM
30 3 * * * tar -czf /backups/files/ps_files_$(date +\%Y\%m\%d).tar.gz /var/www/html/prestashop/

# Cleanup backups older than 30 days
0 4 * * * find /backups/ -name "*.gz" -mtime +30 -delete

Reglas críticas:

  • Almacene las copias de seguridad fuera del servidor — si el servidor es comprometido, las copias locales también lo están
  • Pruebe sus copias de seguridad mensualmente — restaure en un entorno de prueba y verifique que el sitio funcione
  • Cifre antes de transferir externamente — los volcados contienen datos personales de clientes
  • Conserve más de 30 días de copias diarias — algunos compromisos no se descubren de inmediato

Asegurar phpMyAdmin (o eliminarlo)

La opción más segura: no instale phpMyAdmin en producción. Use túneles SSH en su lugar:

# From your LOCAL machine
ssh -L 3307:localhost:3306 user@yourserver.com
# Then connect your local MySQL client to localhost:3307

Si debe ejecutar phpMyAdmin: restrinja por IP, use una ruta URL aleatoria, active la autenticación HTTP Basic y desactive el inicio de sesión como root:

$cfg['Servers'][$i]['AllowRoot'] = false;
$cfg['Servers'][$i]['AllowNoPassword'] = false;

6. Monitoreo y detección

Monitoreo de integridad de archivos

Los atacantes modifican archivos — inyectando puertas traseras, añadiendo shells en directorios de carga o alterando .htaccess. Detecte cambios con una tarea cron diaria:

#!/bin/bash
# /usr/local/bin/prestashop-integrity-check.sh
SHOP_DIR="/var/www/html/prestashop"
BASELINE="/var/backups/prestashop-file-hashes.txt"
CURRENT="/tmp/prestashop-file-hashes-current.txt"
ALERT_EMAIL="admin@yourdomain.com"

find "$SHOP_DIR" -type f \
    -not -path "*/var/cache/*" \
    -not -path "*/var/logs/*" \
    -not -path "*/img/p/*" \
    -not -path "*/img/c/*" \
    -exec md5sum {} \; | sort > "$CURRENT"

if [ -f "$BASELINE" ]; then
    DIFF=$(diff "$BASELINE" "$CURRENT")
    if [ -n "$DIFF" ]; then
        echo "$DIFF" | mail -s "ALERT: PrestaShop files modified" "$ALERT_EMAIL"
    fi
fi

Genere la línea base después de un despliegue limpio, y este script le enviará un correo cada vez que los archivos cambien inesperadamente.

Monitoreo de registros

Escanee los registros de acceso en busca de patrones de ataque:

# SQL injection attempts
grep -iE "(union\s+select|or\s+1=1|information_schema)" /var/log/apache2/access.log

# File inclusion attempts
grep -iE "(etc/passwd|\.\.\/\.\.\/)" /var/log/apache2/access.log

# Direct module file access (potential exploit attempts)
grep -E "modules/.*/ajax|modules/.*/api" /var/log/apache2/access.log

Configure resúmenes diarios de registros mediante cron, o alimente los registros en un sistema centralizado como Graylog o Papertrail para alertas en tiempo real.

Monitoreo de disponibilidad

  • Use UptimeRobot, Hetrix Tools o Uptime Kuma autoalojado
  • Monitoree tanto la página de inicio como la página de pago
  • Verifique el contenido específico de la página, no solo HTTP 200 — una página desfigurada también devuelve 200
  • Compruebe cada 1-5 minutos con alertas por correo electrónico, SMS o Slack

Alertas de inicio de sesión de administración

Reciba una notificación de cada inicio de sesión de administración con un hook sencillo:

public function hookActionAdminLoginControllerLoginAfter($params)
{
    $employee = $params['employee'];
    $ip = Tools::getRemoteAddr();

    Mail::Send(
        (int)Configuration::get('PS_LANG_DEFAULT'),
        'alert_admin_login',
        "Admin Login: {$employee->email} from {$ip}",
        ['{body}' => "Employee: {$employee->email}\nIP: {$ip}\nTime: " . date('Y-m-d H:i:s')],
        'security@yourdomain.com',
        'Security Alert'
    );
}

7. Qué hacer si ha sido hackeado

Respuesta inmediata (primeros 30 minutos)

  • No elimine nada todavía — necesita los archivos para el análisis forense
  • Ponga la tienda fuera de línea con una página de mantenimiento para detener el daño continuo
  • Cambie TODAS las contraseñas: SSH, FTP, base de datos, cuentas de administración, panel de hosting, claves de la pasarela de pago
  • Haga una copia de seguridad del estado comprometido — etíquétela como “comprometida” para análisis posterior
  • Notifique a su procesador de pagos si gestióna los pagos directamente
# Quick maintenance mode
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^YOUR\.IP\.ADDRESS$
RewriteCond %{REQUEST_URI} !^/maintenance\.html$
RewriteRule .* /maintenance.html [R=503,L]

Encontrar la puerta trasera

Los atacantes siempre dejan puertas traseras para volver a entrar. Limpiar el hackeo visible sin encontrar la puerta trasera significa ser comprometido de nuevo en cuestión de días.

# Search for backdoor patterns
grep -rn "eval(" /var/www/html/prestashop/ --include="*.php" | grep -v "vendor\|cache"
grep -rn "base64_decode" /var/www/html/prestashop/ --include="*.php" | grep -v "vendor\|cache"
grep -rn "shell_exec\|passthru\|system(" /var/www/html/prestashop/ --include="*.php" | grep -v "vendor\|cache"

# Find recently modified PHP files
find /var/www/html/prestashop/ -name "*.php" -mtime -7 -not -path "*/cache/*"

# Find PHP files in directories where they should not exist
find /var/www/html/prestashop/img/ -name "*.php"
find /var/www/html/prestashop/upload/ -name "*.php"

# Check for obfuscated code (very long single lines)
find /var/www/html/prestashop/ -name "*.php" -exec awk 'NR==1 && length>5000' {} +

Compruebe también la base de datos:

SELECT id_cms, meta_title FROM ps_cms_lang WHERE content LIKE '%<?php%' OR content LIKE '%eval(%';
SELECT * FROM ps_employee ORDER BY date_add DESC LIMIT 10;

Proceso de recuperación

  1. Determine el punto de entrada a partir de los registros de acceso — busque solicitudes POST inusuales a controladores de módulos alrededor del momento del compromiso
  2. Restaure desde una copia de seguridad limpia si está disponible. Verifique que la copia de seguridad sea anterior al compromiso.
  3. Si no existe una copia de seguridad limpia: reemplace todos los archivos del núcleo con una descarga nueva de su versión exacta de PS, reinstale todos los módulos desde las fuentes originales, conserve solo su tema y el directorio img/ (escanéelos exhaustivamente)
  4. Escanee la base de datos en busca de contenido inyectado en ps_configuration, ps_cms_lang y ps_meta_lang
  5. Actualice todo — núcleo, módulos, PHP, MySQL, sistema operativo

Prevención después de la limpieza

  • Elimine o parchee la vulnerabilidad específica que fue explotada
  • Monitoree intensivamente durante el primer mes — los atacantes a menudo intentan volver
  • Considere un WAF (nivel gratuito de Cloudflare, Sucuri o ModSecurity)
  • Si los datos de pago fueron potencialmente comprometidos, consulte a un abogado sobre las obligaciones de notificación del RGPD (plazo de 72 horas)
Verdad dura: Si no puede determinar cómo entró el atacante, asuma que volverá a entrar. Una auditoría de seguridad profesional cuesta una fracción de lo que cuesta una segunda brecha.

8. Lista de verificación de seguridad

Imprima esta lista y trabaje en ella punto por punto. Cada elemento sin marcar es un punto de entrada potencial.

Servidor y PHP

  • La versión de PHP es actual y tiene soporte
  • Funciones PHP peligrosas desactivadas
  • expose_php = Off
  • display_errors = Off en producción
  • allow_url_include = Off
  • Cookies de sesión: HttpOnly, Secure, SameSite
  • open_basedir configurado
  • SO, MySQL y servidor web actualizados
  • Autenticación SSH por clave activada, autenticación por contraseña desactivada
  • Firewall configurado (solo puertos necesarios abiertos)

Sistema de archivos

  • Directorios: 755, Archivos: 644
  • parameters.php: 400
  • Ningún archivo con permisos 777
  • Ejecución de PHP bloqueada en upload/, img/, download/
  • Listado de directorios desactivado
  • Archivos .env, .git, YAML y de configuración bloqueados desde la web
  • vendor/ y var/logs/ bloqueados desde la web

SSL y HTTPS

  • Certificado SSL válido con renovación automática
  • Redirección de HTTP a HTTPS configurada
  • Cabecera HSTS configurada
  • SSL activado en PrestaShop (todas las páginas)
  • Sin advertencias de contenido mixto

Panel de administración

  • El directorio de administración tiene un nombre aleatorio
  • Todas las contraseñas de 16 o más caracteres generadas por un gestor de contraseñas
  • 2FA activado para todas las cuentas
  • Acceso de administración restringido por IP (si es viable)
  • Cuentas innecesarias eliminadas
  • Cada empleado tiene los permisos mínimos necesarios
  • Protección contra fuerza bruta (fail2ban o equivalente)

Módulos

  • Todos los módulos de fuentes confiables
  • Sin módulos nulled/pirateados
  • Todos los módulos actualizados
  • Módulos no utilizados eliminados (no solo desactivados)
  • Código de módulos auditado en busca de eval() y SQL sin sanitizar
  • Suscrito a avisos de seguridad

Base de datos

  • Usuario de base de datos dedicado (no root)
  • Permisos mínimos otorgados
  • Contraseña de base de datos robusta (20 o más caracteres)
  • MySQL vinculado solo a localhost
  • phpMyAdmin eliminado o restringido por IP
  • Prefijo de tablas cambiado del predeterminado ps_

Copias de seguridad

  • Copias de seguridad de base de datos automatizadas diariamente
  • Copias de seguridad de archivos automatizadas diariamente
  • Copias de seguridad almacenadas fuera del servidor
  • Copias de seguridad cifradas antes de la transferencia
  • Retención de más de 30 días
  • Restauración probada en los últimos 30 días

Monitoreo

  • Monitoreo de integridad de archivos activo
  • Registros de acceso monitoreados en busca de patrones de ataque
  • Monitoreo de disponibilidad con verificación de contenido
  • Alertas de inicio de sesión de administración activadas
  • Cabeceras de seguridad configuradas

Preparación ante incidentes

  • Plan de respuesta a incidentes documentado
  • Contactos de hosting y procesador de pagos accesibles
  • Proceso de notificación del RGPD documentado
  • Página de mantenimiento lista para desplegar
  • Todas las contraseñas críticas en un gestor de contraseñas

La seguridad es un proceso continuo, no una configuración única. Programe una revisión trimestral. El tiempo que invierta ahora es insignificante comparado con el costo de recuperarse de una brecha. Comience con los elementos de mayor impacto: actualice todo, active 2FA, elimine los módulos no utilizados y configure las copias de seguridad. Luego trabaje en el resto.

Sus clientes confían en usted con sus datos personales. Honre esa confianza.

More guides available

Browse our knowledge base for more practical PrestaShop tutorials, or reach out if you need help.

Cargando...
Volver arriba