Qué buscan realmente los atacantes de PrestaShop: 1,1 millones de ataques reales, analizados

La mayoría de los consejos sobre “seguridad en PrestaShop” se escriben desde la imaginación del defensor: una lista de cosas que podrían salir mal. Nosotros queríamos lo contrario: una medición de lo que le ocurre realmente a una tienda PrestaShop en vivo, en la práctica, ahora mismo. Así que instrumentamos nuestra propia flota y contamos.
Gestionamos y defendemos varias tiendas PrestaShop en producción y, a lo largo de más de una década, hemos creado y mantenido un amplio catálogo de módulos para PrestaShop. Eso nos dio algo que la mayoría de los análisis de seguridad no tienen: un conjunto de escaparates reales y con tráfico, y permiso para observar cada petición hostil que reciben. Durante seis semanas registramos cada petición maliciosa: no solo las que tuvieron éxito, ni solo las dirigidas al software que realmente usamos. Si un bot sondeaba un módulo que ni siquiera tenemos instalado, lo registrábamos igualmente, porque el objetivo era una imagen honesta y completa de la presión a la que está sometida una tienda normal.
El total ascendió a alrededor de 1,1 millones de peticiones maliciosas desde más de 13.300 direcciones IP distintas. Esto es lo que los atacantes buscaban realmente y, para cada hallazgo, exactamente qué hacer al respecto.
Cómo lo medimos
Gestionamos y defendemos una flota de tiendas PrestaShop en producción, y creamos y mantenemos más de cien módulos para PrestaShop. Durante seis semanas registramos cada petición que activó una firma de ataque en el perímetro del servidor web — en varias tiendas en vivo — en una única base de datos estructurada, deduplicada por identidad de ataque, de modo que un escáner que golpea mil URL cuenta como una campaña, no como mil incidentes. Lo importante: registramos sondeos contra software que ni siquiera usamos, para que la imagen no quede sesgada por nuestra propia infraestructura. Cada cifra siguiente está agregada y totalmente anonimizada: no se publica ningún dato de tienda, cliente, credencial ni exploit.
Primera verdad: cerca del 99% es ruido
Lo más importante que hay que entender es la forma del tráfico. La inmensa mayoría — muy por encima de un millón de peticiones — es reconocimiento automatizado: escáneres masivos que recorren internet, lanzando las mismas cargas prefabricadas contra cada IP a la que llegan, sin importar si usas PrestaShop, WordPress o una aplicación Java.
Eso es tranquilizador y peligroso a la vez. Tranquilizador, porque casi todo rebota en una tienda parcheada y bien configurada. Peligroso, porque ese muro de ruido es exactamente donde se esconde un intento dirigido. La parte genuinamente afilada es real pero pequeña — del orden de 34.000 sondeos de inyección SQL y un par de miles de intentos de ejecutar código directamente en el servidor — una fina porción enterrada dentro de un millón de peticiones de estática de fondo. Si revisas los registros de acceso a ojo, nunca detectarás de forma fiable la única petición que importa. Ese es todo el argumento a favor de la detección estructurada frente al “ya miraré los registros si algo me da mala espina”.
Aquí está la misma imagen desglosada por objetivo.
| Qué buscaban | Volumen | Qué es en realidad |
|---|---|---|
| Reconocimiento y escaneo automatizados | ~99% | Escáneres masivos que caracterizan toda internet, sin importar lo que uses |
| Descargas de archivos secretos y de configuración | 220.000+ | .env, .git, configuración del framework — robo de credenciales sin necesidad de exploit |
| Un solo módulo de blog abandonado (LFI) | ~32.000 | Un único módulo de terceros sin mantenimiento — más que todos los demás fallos de módulos juntos |
| Sondeos de inyección SQL | ~34.000 | Sobre todo contra viejos complementos de terceros de formulario de contacto, boletín y búsqueda |
| Exploits para la pila equivocada (WordPress, Java, ASP.NET) | decenas de miles | Lanzados a ciegas contra tiendas PHP que jamás podrían ser vulnerables a ellos |
| Intentos de ejecución remota de código (RCE) | ~2.300 | La parte genuinamente afilada — el 1% que convierte un fallo en control total (los webshells se cuentan por separado) |
Van primero a por tus secretos
Por puro volumen, el objetivo individual más ruidoso no era la explotación en absoluto. Era el robo de credenciales a paladas: más de 220.000 peticiones intentando descargar archivos secretos — .env y su docena de variantes (.env.local, .env.production, .env.backup, /api/.env, y así sin parar), además de .git/config, archivos de configuración del framework y credenciales en caché.
La lógica es brutalmente eficiente. ¿Para qué escribir un exploit cuando un servidor mal configurado simplemente te entrega la contraseña de la base de datos, la clave de la API de pagos y las credenciales de correo en un archivo de texto plano? Un solo .env filtrado suele significar el fin de la partida — sin necesidad de ninguna vulnerabilidad, solo un directorio que nunca debió ser público pero lo es.
Qué hacer: asegúrate por completo de que tu servidor web se niega a servir archivos ocultos (dotfiles) y de configuración. Deben devolver un 403 o un 404 desde el perímetro, no su contenido. Es un cambio de cinco minutos que neutraliza el objetivo más común que registramos:
# Place these ABOVE your generic PHP handler - nginx matches location blocks in order
# Never serve dotfiles (except ACME) or config/secret files
location ~ /\.(?!well-known/) { deny all; }
location ~* \.(env|git|bak|old|dist|sql|log|lock)$ { deny all; }
location ~* /(composer\.(json|lock)|package(-lock)?\.json|yarn\.lock)$ { deny all; }
# PrestaShop config/credential files (all supported versions)
location ~* /(settings\.inc\.php|parameters\.(php|ya?ml))$ { deny all; }# Block dotfiles and config/secret files
RedirectMatch 404 /\.(?!well-known)
<FilesMatch "\.(env|git|bak|old|dist|sql|log|lock)$">
Require all denied
</FilesMatch>
<FilesMatch "^(composer\.(json|lock)|package(-lock)?\.json|yarn\.lock)$">
Require all denied
</FilesMatch>
# PrestaShop config/credential files (all supported versions)
<FilesMatch "^(settings\.inc\.php|parameters\.(php|ya?ml))$">
Require all denied
</FilesMatch>
Verifícalo
Desde fuera del servidor, solicita /.env y /.git/config por HTTPS. Quieres un 403 o un 404 — si obtienes el contenido de algún archivo, o incluso un 200 vacío, arréglalo antes que nada en esta lista.
El componente más atacado: un módulo abandonado
Cuando filtramos hasta quedarnos con los ataques dirigidos a PrestaShop específicamente, un objetivo eclipsaba a todos los demás: un fallo de inclusión de archivos local (LFI) en un antiguo módulo de blog que ya no recibe mantenimiento — unos 32.000 intentos, más que todas las demás vulnerabilidades de módulos juntas.
Este es el patrón que arruina tiendas en silencio. Casi nunca es el núcleo de PrestaShop lo que deja entrar a los atacantes. Es el módulo de terceros que instalaste hace tres años, dejaste de actualizar y olvidaste que tenías. Los atacantes mantienen listas curadas de estos — nombre del módulo, ruta vulnerable, exploit listo para usar — y los rocían por toda internet en bucle.
Más abajo en la lista estaban los sospechosos habituales: sondeos de inyección SQL contra módulos de formulario de contacto y de boletín, una vulnerabilidad conocida en un módulo de lista de deseos y un puñado de complementos de carrusel y de búsqueda. Todos de terceros. Todos del tipo de cosa que se acumula en una tienda con los años y luego se queda ahí, sin parchear, mucho después de que nadie recuerde haberla instalado.
Qué hacer: haz inventario de tus módulos y elimina los que no uses — un módulo instalado pero sin usar es pura superficie de ataque sin ningún beneficio. Parchea los que conserves y, si el desarrollador ha desaparecido, reemplaza el módulo en lugar de confiar en la suerte. Si estás atascado en una versión que no puedes actualizar con seguridad, nuestra guía para proteger una tienda que no puedes actualizar explica cómo parchear virtualmente exactamente este tipo de agujero.
El kit de intrusión: webshells y backdoors
Más allá del reconocimiento y la caza de secretos está la parte afilada. Los atacantes intentaron repetidamente colocar o localizar webshells — las herramientas que convierten una sola vulnerabilidad en control remoto total. Los nombres de archivo son casi una firma en sí mismos: adminer.php, alfa.php, wso.php, sondeos sueltos de phpinfo y scripts de gestor de bases de datos dejados atrás por un compromiso anterior.
También captamos algo más preciso que el escaneo genérico. Cuando una tienda de un grupo se ve comprometida, los atacantes toman la carga exacta que funcionó allí y la rocían contra cada tienda relacionada que encuentran, apostando a que el mismo backdoor sigue instalado en otra. La persistencia da resultados: un backdoor enterrado en un archivo que rara vez se inspecciona puede sobrevivir a varias “limpiezas” superficiales y seguir reinfectando una tienda durante semanas. Si alguna vez limpiaste un compromiso eliminando solo el JavaScript malicioso visible y volvió, esta es la razón — recorrimos exactamente ese fallo en nuestra anatomía de un skimmer al estilo Magecart.
Qué hacer: deniega la ejecución de PHP en todo directorio que solo deba contener subidas, imágenes, caché o herramientas. Si un bot consigue escribir shell.php en tu carpeta de imágenes, la diferencia entre un mal día y una brecha total es simplemente si el servidor lo ejecuta:
# Put this ABOVE your existing "location ~ \.php$" block - nginx is first-match-wins
# A bot that writes shell.php into an image folder must never get it executed
location ~* ^/(img|upload|uploads|cache|var|download)/.*\.(php|phar|phtml|php[0-9])$ {
deny all;
}# Drop this .htaccess inside an uploads folder: turn PHP off for the whole tree
<FilesMatch "\.(php|phar|phtml|php[0-9])$">
Require all denied
</FilesMatch>
Tras cualquier sospecha de compromiso, da por hecho que hay persistencia
Eliminar el síntoma visible no es remediación. Busca archivos ejecutables en rutas editables, rota cada credencial que estuviera en un archivo de configuración legible y reconstruye desde una copia de seguridad que sepas que está limpia en lugar de limpiar sobre la marcha.
Ni siquiera comprueban qué estás usando
Una ilustración reveladora de lo automatizado que es todo esto: registramos decenas de miles de intentos de exploit dirigidos a pilas tecnológicas completamente distintas — cargas de Java y JSF, exploits de plugins de WordPress, trucos de ASP.NET — todos lanzados a ciegas contra tiendas PHP que jamás podrían ser vulnerables a ellos.
La conclusión no es “ja, fallaron”. Es lo contrario: te atacan constantemente atacantes que ni saben ni les importa qué usas. No hace falta ser un objetivo para ser una víctima. Basta con ser accesible y estar desactualizado.
Comprueba tu propia tienda ahora mismo
Una cosa es leer sobre ello; aquí tienes cuatro comprobaciones que puedes ejecutar contra tu propia tienda en los próximos cinco minutos. Se corresponden directamente con lo que buscan los atacantes que hemos visto arriba.
1. ¿Son tus secretos realmente accesibles? Desde tu propia máquina, pide los archivos que piden los escáneres. Cada línea debería devolver 403 o 404 — nunca 200 con contenido:
# From your own machine: 403/404 = safe, 200 = exposed, 000 or 3xx = check by hand
for f in .env .git/config app/config/parameters.php composer.json; do
printf '%s -> ' "$f"
curl -s -o /dev/null --connect-timeout 5 --max-time 15 -w '%{http_code}\n' "https://your-store.com/$f"
done2. ¿Hay PHP escondido donde solo debería haber recursos? Por SSH, desde la raíz de tu tienda, busca archivos ejecutables en carpetas que solo deberían contener subidas e imágenes. Esto no debería imprimir nada:
# PHP hiding in folders that should only hold assets (a clean store prints nothing)
find img upload uploads download -type f \
\( -iname '*.php' -o -iname '*.php[0-9]' -o -iname '*.phtml' -o -iname '*.phar' \) \
! -iname index.php 2>/dev/null3. ¿Qué ha cambiado recientemente? Una puerta trasera recién colocada es un archivo PHP modificado hace poco que tú no tocaste. Enumera los cambios de la última semana y revisa con atención cualquier cosa que no reconozcas:
# PHP changed in the last 7 days, cache excluded (GNU/Linux find) - review anything unfamiliar
find . \( -path ./var/cache -o -path ./cache \) -prune -o \
-type f -iname '*.php' -mtime -7 -printf '%TY-%Tm-%Td %p\n' | sort4. ¿Quién puede acceder a tu back office? Cada cuenta es una llave de la puerta de entrada. Investiga a cualquier empleado que no reconozcas y a cualquiera que no haya iniciado sesión en meses:
-- Back-office accounts: investigate any you do not recognise
-- Run in phpMyAdmin or the mysql client; change the ps_ prefix if yours differs
SELECT id_employee, email, active, last_connection_date
FROM ps_employee
ORDER BY last_connection_date DESC;
¿Prefieres una comprobación con un solo clic?
Hemos convertido estas mismas comprobaciones en herramientas. Nuestro Security Scan gratuito y de código abierto examina tu tienda en busca justo de estas exposiciones — archivos de configuración y de copia de seguridad expuestos, PHP suelto en tus carpetas de recursos, módulos con CVE conocidos, el modo de depuración y un endurecimiento deficiente — y te entrega un informe priorizado, sin coste alguno. Para una protección continua, Security Revolution añade un cortafuegos de peticiones, limitación de frecuencia, cabeceras de seguridad, monitorización de cambios en archivos y análisis de vulnerabilidades, todo desde tu back office. Y si prefieres delegarlo por completo, nuestra Security & Hardening Audit es una revisión llave en mano a cargo de nuestro equipo.
Lo que hacemos de verdad en nuestras propias tiendas
Como estos también son nuestros escaparates, la lista defensiva anterior no es teórica. En las tiendas de este estudio bloqueamos dotfiles y archivos de configuración en el perímetro, denegamos la ejecución de PHP en toda ruta editable, mantenemos deliberadamente una huella de módulos pequeña y eliminamos todo lo que no se usa, imponemos la autenticación de dos factores en el administrador y colocamos todo el conjunto tras una capa perimetral que limita la tasa de los escáneres y descarta las cargas de inyección evidentes. Y mantenemos el registrador en marcha — el mismo registro a nivel de petición que produjo este artículo — para que un intento genuinamente dirigido salga a la superficie en lugar de ahogarse en el 99% de ruido. Nada de esto es exótico. Todo es aburrido, y lo aburrido es lo que funciona.
- Bloquea los archivos secretos en el perímetro.
.env,.git,composer.jsony los archivos de configuración deben devolver 403/404 — nunca su contenido. - Poda tus módulos. Elimina todo lo que no uses; un módulo sin usar es pura superficie de ataque.
- Parchea o reemplaza lo que conserves. Especialmente los complementos de terceros de blog, carrusel, formularios y búsqueda.
- Deniega PHP en las carpetas editables. Subidas, imágenes, caché y tmp nunca deberían ejecutar código.
- Blinda el acceso al administrador. Credenciales fuertes y únicas, y autenticación de dos factores.
- Mantente en una versión con soporte. Una plataforma al final de su vida útil viene con un juego permanente de llaves conocidas.
- Pon detección entre tú y el ruido para que el 1% que importa no pueda esconderse en el 99% que no.
Preguntas frecuentes
¿Es seguro PrestaShop?
El núcleo de PrestaShop se mantiene de forma activa y rara vez es la vía de entrada. En nuestros datos, casi nada apuntaba al núcleo — los ataques con aspecto de éxito se dirigen a módulos de terceros, servidores mal configurados que filtran archivos secretos e instalaciones al final de su vida útil. Una tienda PrestaShop parcheada y bien configurada en una versión actual es un objetivo difícil. Una descuidada no lo es.
¿Cómo sé si mi tienda ya ha sido comprometida?
Busca archivos PHP en directorios que solo deberían contener imágenes o subidas, empleados de administración inesperados, archivos .htaccess o index.php modificados y tareas programadas desconocidas. Un backdoor suele sobrevivir a una “limpieza” que solo eliminó el JavaScript malicioso visible — si una infección sigue reapareciendo, aún hay un archivo ejecutable en algún lugar del disco. Para una autocomprobación estructurada, nuestra guía sobre las señales de que una tienda necesita una auditoría de seguridad es un buen siguiente paso.
¿Qué módulos son los más peligrosos?
Cualquier módulo de terceros que ya no actualices — sobre todo los complementos antiguos de blog, carrusel, formulario de contacto, boletín, lista de deseos y búsqueda, que tienen exploits públicos muy conocidos. El componente más atacado de nuestra flota fue un módulo de blog abandonado. Si el desarrollador ha desaparecido, trata el módulo como un riesgo y reemplázalo.
¿Necesito Cloudflare o un WAF?
Una capa perimetral capaz de bloquear las peticiones a dotfiles, limitar la tasa de los escáneres y filtrar las cargas de inyección evidentes absorbe buena parte de este ruido antes de que llegue a PHP. No sustituye al parcheo ni a la eliminación de módulos sin usar, pero reduce la presión de forma notable y te da tiempo.
Estoy en una versión antigua de PrestaShop que no puedo actualizar con seguridad. ¿Y ahora qué?
Reduce la superficie de ataque de forma agresiva: elimina todos los módulos sin usar, bloquea los archivos secretos y la ejecución de PHP en las carpetas de recursos a nivel de servidor, y parchea virtualmente los agujeros conocidos en el perímetro. Nuestra guía para proteger una tienda que no puedes actualizar lo cubre en detalle.
¿Con qué frecuencia se ataca de verdad a una tienda normal?
Constantemente. En nuestra flota eso supuso aproximadamente un millón de peticiones maliciosas en seis semanas. La inmensa mayoría es automatizada e inofensiva frente a una tienda mantenida — pero nunca se detiene, y basta con una sola puerta descuidada.
En resumen
Quita el volumen y la imagen es sencilla. Los ataques que tienen éxito casi nunca dependen de algún zero-day exótico. Dependen de lo aburrido: un archivo secreto que quedó legible, un módulo de terceros sin parchear o abandonado, un directorio que ejecutará un archivo PHP subido, un acceso de administrador con una contraseña débil o reutilizada, una plataforma desactualizada. Nada de esto es difícil de arreglar. Todo son cosas que una tienda mantenida hace bien y una descuidada no. Los atacantes han automatizado la búsqueda del descuido — un millón de veces en seis semanas. La única defensa real es no estar descuidado: parchea, poda, cierra las puertas evidentes y pon detección real entre tú y ese muro de ruido.
Nota metodológica: las cifras están agregadas a partir del registro de ataques a nivel de petición en varias tiendas en producción durante una ventana de aproximadamente seis semanas que finaliza en julio de 2026. Todos los datos están anonimizados; no se incluye ningún detalle de tienda, cliente ni credencial, y no se publican datos concretos de exploits.
Comentarios
Aún no hay comentarios. ¡Sé el primero!
Sé el primero en hacer una pregunta o compartir una opinión útil.
Dejar un comentario
Comparte una pregunta, un detalle de instalación o una opinión que pueda ayudar a otro lector.