Sin impuesto Con impuesto

Hackeos en PrestaShop: skimmers, desvíos de pago y puertas traseras que hemos visto

Formularios de tarjeta falsos en el pago, cobros que se van a la cuenta de otro, puertas traseras escondidas en módulos que nadie usa. Contamos, sin decir de quién, lo que hemos encontrado al limpiar tiendas PrestaShop, cómo trabajamos un incidente y por qué una tienda sin actualizar es la que acaba en esta lista.

Equipo Rekire
Actualizado: 26/10/2026 99
Hackeos en PrestaShop: skimmers, desvíos de pago y puertas traseras que hemos visto
Compartir:

Una tienda online no se hackea como en las películas. No hay pantallas en rojo ni calaveras en la portada. Lo normal es justo lo contrario: la tienda funciona perfectamente, los pedidos entran, los clientes pagan y el dueño no nota nada. Mientras tanto, alguien está copiando las tarjetas en el paso de pago, cobrando en una cuenta que no es la tuya o guardando una puerta trasera para volver cuando quiera.

En Rekire limpiamos tiendas PrestaShop comprometidas con más frecuencia de la que nos gustaría. Este artículo reúne lo que hemos visto en esos trabajos. Los casos son reales, pero los contamos de forma que sea imposible saber de qué tienda se trata: sin sector, sin ciudad, sin fechas, sin cifras y sin detalles que permitan buscarla. Lo que importa no es quién, sino cómo, porque el cómo se repite.

Es un artículo largo a propósito. Si tienes una tienda en una versión antigua de PrestaShop, te pedimos que lo leas entero.

Qué es un skimmer y por qué es el ataque favorito contra una tienda

Un skimmer (también llamado clonador de tarjetas o ataque tipo Magecart) es un trozo de JavaScript que se mete en tu tienda y roba los datos de tarjeta en el momento en que el cliente los escribe. Número, caducidad, CVV y nombre del titular salen hacia un servidor del atacante, y el pedido sigue su curso normal.

Es el ataque más rentable que existe contra una tienda online por tres motivos:

  • No rompe nada. El cliente compra, tú cobras, nadie se queja. Los datos robados se usan semanas después, en otro sitio, y cuando el banco del cliente detecta el fraude nadie relaciona la tarjeta con tu tienda.
  • No necesita que tu pasarela sea vulnerable. Da igual que uses el TPV de tu banco, Stripe o PayPal. El skimmer no ataca la pasarela: ataca la página donde está el cliente.
  • Escala. Una tienda con tráfico normal entrega decenas de tarjetas por semana sin que el atacante tenga que hacer nada más.
«Mi pasarela es una página del banco, a mí no me afecta.» Es lo que más oímos, y es falso. Si el pago se hace en una página externa, el skimmer pinta antes un formulario de tarjeta falso dentro de tu checkout, se queda con los datos y luego deja que el cliente siga hacia el banco. El cliente escribe su tarjeta dos veces y piensa que algo ha fallado. Tú no ves nada.

Caso 1: el formulario de tarjeta que no existía

La primera señal fue un aviso automático de nuestro módulo de seguridad: una plantilla del paso de pago del tema había cambiado sin que nadie hubiera tocado el tema.

Al tirar del hilo apareció la secuencia completa, reconstruida con los registros del servidor:

  1. Alguien entró en el panel del hosting con el usuario y la contraseña correctos. No fue un fallo de PrestaShop: la contraseña estaba filtrada.
  2. Desde el gestor de ficheros del panel, escribió unos 60 KB de JavaScript en un fichero del propio tema que hasta entonces estaba vacío. Un fichero con nombre aburrido, de los que nadie abre.
  3. Añadió una sola línea al final de la plantilla del paso de pago: un <script src> que cargaba ese fichero. Desde el mismo dominio de la tienda, así que ningún filtro de «dominios externos» lo habría marcado.
  4. Subió un pequeño PHP para vaciar la caché de plantillas, lo ejecutó y se fue. Todo en menos de veinte minutos.

El JavaScript no hacía nada mientras el cliente navegaba. Solo se activaba cuando el cliente marcaba la opción de pago con tarjeta. En ese momento pintaba un formulario de tarjeta idéntico al de la tienda y, al rellenarlo, enviaba los datos codificados con navigator.sendBeacon a otra tienda online, también hackeada, que hacía de buzón. Usar la web de otra víctima como destino es habitual: un dominio comercial normal no levanta sospechas.

Estuvo activo alrededor de una semana. El trabajo posterior fue igual de importante que la limpieza: sacar la lista de pedidos y pagos de esos días para avisar a la entidad de pago, y valorar con el responsable de la tienda la notificación a la Agencia Española de Protección de Datos, que el RGPD (artículo 33) pide hacer en un máximo de 72 horas desde que se conoce la brecha.

Lo que apareció debajo

Revisando los empleados del back-office encontramos algo peor: más de una veintena de superadministradores falsos, todos con el mismo correo y el nombre «Prestashop Addons», creados en ráfagas de un segundo meses antes. Esa forma de crearlos —muchos a la vez, con el mismo correo— es la firma de una inyección SQL, no de alguien que entra por el formulario. El origen más probable era un controlador de un constructor de páginas de un tema comercial que respondía a cualquiera, sin comprobar sesión, y metía un parámetro sin filtrar dentro de una consulta.

Ninguna auditoría anterior los había visto. La tienda llevaba meses con la puerta abierta, y el skimmer fue solo lo que finalmente se notó.

Caso 2: los pagos que se iban a otra cuenta

Este es el caso que mejor explica por qué decimos que un ataque no se ve. La tienda vendía con normalidad. Los pedidos con tarjeta aparecían en el back-office como pagados, con su número de operación, su estado correcto y su factura. Todo cuadraba… salvo que ese dinero nunca llegó al banco de la tienda.

El atacante había sustituido el fichero principal del módulo de pago del banco por una copia modificada. La modificación hacía esto:

  • Cambiaba el pago con tarjeta por un formulario de una pasarela internacional conectada a una cuenta del atacante. Dejaba Bizum intacto y ocultaba otro método, para que el cliente fuera directo a la tarjeta.
  • Escribía en las tablas del módulo del banco un registro falso, de forma que el pedido parecía un pago normal en el back-office.
  • No se activaba para los empleados de la tienda ni para correos que parecían de pruebas o de la agencia que la mantenía. Quien probaba la tienda veía el pago de siempre.
  • Avisaba al atacante por Telegram de cada cobro.
  • Guardaba sus claves fuera de la carpeta web, en el directorio personal de la cuenta del hosting.
  • Y podía autodestruirse, restaurando los ficheros originales que había dejado guardados al lado.

La entrada fue por FTP, con la cuenta principal del hosting, la misma contraseña que la del panel. Los registros del FTP mostraban decenas de sesiones desde la misma dirección durante semanas, subiendo y retocando ficheros como si fuera un desarrollador más.

¿Y cómo se descubrió? Por un error del propio atacante, y aquí está la parte que nos interesa. La tienda acababa de migrar a PrestaShop 9. El código malicioso estaba escrito para la versión antigua, y al reinyectarlo el atacante subió los ficheros del módulo de pago de la tienda vieja. En PrestaShop 9 esos ficheros ya no funcionaban: la tienda se quedó en blanco. Sin ese fallo, el desvío habría seguido. Al cruzar los pedidos con la huella que dejaba el código falso aparecieron decenas de cobros desviados a lo largo de varios meses.

La lección de este caso: «los pedidos están pagados en el back-office» no es lo mismo que «el dinero está en mi cuenta». Concilia cada semana los cobros de la pasarela contra los pedidos. Es aburrido y es la única forma de detectar un desvío que está diseñado para no verse.

Caso 3: puertas traseras donde nadie mira

Un skimmer o un desvío necesitan que el atacante pueda escribir en tu tienda. Para volver cuando quiera, deja una web shell: un fichero PHP que, llamado por su URL, le permite ejecutar órdenes o escribir ficheros en tu servidor. Estas son algunas de las que hemos encontrado, y fíjate en dónde estaban:

  • Una línea de 30 bytes (eval de lo que llegue por la petición) dentro de la carpeta de un módulo que no estaba instalado. La carpeta estaba en el disco desde hacía años, nadie la revisaba y PrestaShop 1.7 ejecuta cualquier .php de modules/ si alguien lo pide por URL.
  • Un fichero de menos de 200 bytes, con un nombre que empezaba por punto, en la raíz de la tienda. Solo hacía una cosa: escribir en el servidor cualquier fichero que recibiera. Ningún escáner automático lo vio; apareció comparando la tienda, fichero a fichero, con una copia anterior.
  • Una shell completa de más de 80 KB (gestor de ficheros, ejecución de órdenes, subida de ficheros) dentro de la carpeta de un módulo nativo de PrestaShop, con la cabecera de licencia de PrestaShop, autor «PrestaShop» y funciones con nombres inocentes. Una copia exacta estaba en otro módulo abandonado, por si borraban la primera.
  • Un gestor de ficheros disfrazado de lector de códigos QR, escrito en PHP limpio y legible, dentro de un plugin de un WordPress que compartía hosting con la tienda. Desde ahí se reescribió el JavaScript del tema de PrestaShop sin tocar PrestaShop en ningún momento.
  • Una línea en la carpeta vendor/ de un módulo que incluía un fichero con extensión .jpeg… que era PHP. La tienda había pasado dos limpiezas con esa puerta abierta porque la herramienta que usaban excluía vendor/ por defecto.
  • Un cargador de 6 KB dentro de un módulo de transporte por lo demás legítimo, que abría un WebSocket y ejecutaba lo que le mandaran. En disco no había nada más: el código malicioso llegaba en cada visita y se dedicaba a llevarse la URL del back-office, con su token, a un dominio externo.

Los sabotajes de un solo carácter

El caso que más nos enseñó fue una tienda donde, además de las puertas traseras, el atacante había tocado dos ficheros del núcleo de PrestaShop. En uno, una expresión regular que limpia etiquetas HTML quedó relajada para que dejara de limpiar. En el otro, quitó el cierre del índice de clases que PrestaShop genera, de forma que cualquier cosa añadida al final se ejecutaba como código: reinfección automática sin necesidad de ningún fichero propio.

Ninguna regla de búsqueda de patrones habría visto eso. Lo encontró la comparación byte a byte con el ZIP oficial de PrestaShop de esa misma versión.

Por dónde entran (casi siempre)

Con todos los casos encima de la mesa, las vías de entrada se repiten:

Vía de entradaQué hemos vistoQué la cierra
Contraseña de panel o FTP filtradaLogin correcto en el panel del hosting o en el FTP principal, sin ningún fallo técnicoContraseñas únicas, 2FA en el panel, SFTP, cuentas FTP mínimas y rotación tras cualquier incidente
Módulo con inyección SQLSuperadministradores creados en ráfaga; controladores públicos que no comprueban nadaMódulos actualizados, retirar los que no se usan, revisar periódicamente la lista de empleados
Ficheros PHP accesibles en modules/Web shells en módulos desinstalados o abandonadosPrestaShop 9 (lo deniega de serie) o un .htaccess con excepciones medidas
Otra web en el mismo hostingUn WordPress sin mantener usado para escribir en la tiendaSeparar cuentas de hosting o mantener las dos webs igual de actualizadas
El equipo de quien administraProgramas que roban contraseñas guardadas en el navegador y en el cliente FTPNo guardar contraseñas del FTP en el cliente, gestor de contraseñas, 2FA

Fíjate en que solo una de las cinco es un fallo de programación «puro». Las demás son mantenimiento: lo que hay instalado, lo que sobra y quién tiene llaves.

Por qué casi todas las tiendas hackeadas eran antiguas

No es casualidad. En casi todos los incidentes que hemos trabajado, la tienda estaba en PrestaShop 1.6 o 1.7, con PHP 7.x y con módulos que no se habían actualizado en años. Eso suma riesgos que se multiplican entre sí:

  • PHP 7.4 dejó de recibir parches de seguridad a finales de 2022, y las versiones anteriores, antes. Un fallo nuevo en PHP no se va a corregir nunca para tu servidor.
  • Las ramas antiguas de PrestaShop ya no reciben correcciones, y muchos módulos de terceros han dejado de publicar versiones para ellas. Cuando se publica una vulnerabilidad de un módulo popular, la corrección sale para la versión actual. Si no puedes instalarla porque tu tienda es demasiado vieja, la vulnerabilidad es pública y tu tienda sigue abierta.
  • Las tiendas antiguas acumulan módulos huérfanos: carpetas de módulos probados y desinstalados hace años que siguen en el disco y que, en 1.7, se pueden ejecutar por URL. En PrestaShop 9, el .htaccess de modules/ ya deniega la ejecución directa de PHP.
  • Cuanto más vieja es la tienda, más miedo da tocarla. Y lo que no se toca no se revisa.

Actualizar no es una garantía absoluta: la tienda del caso 2 ya estaba en PrestaShop 9, pero el atacante había entrado antes, con la contraseña del hosting. Lo que sí hace una tienda actualizada es cerrar las vías de entrada conocidas y hacer que cualquier cambio raro se note. Una tienda vieja es una tienda donde las vías conocidas siguen abiertas y donde nadie compara nada con nada.

Qué hacemos en Rekire cuando una tienda está hackeada

Cuando nos llega una tienda comprometida seguimos siempre el mismo orden. El orden importa: borrar el fichero malo lo primero es la forma más rápida de que el atacante vuelva por el mismo sitio una semana después.

  1. Copia forense antes de tocar nada. Ficheros y base de datos, guardados fuera de la web. Si borras sin copiar, pierdes la prueba de qué pasó, desde cuándo y qué datos han quedado expuestos.
  2. Trabajar sobre una copia aislada. Traemos la tienda a nuestro entorno, sin salida a Internet, con el correo capturado y las pasarelas desactivadas, para analizarla sin riesgo de que escriba a clientes o haga cobros.
  3. Comparar con algo conocido. El núcleo, contra el ZIP oficial de la misma versión de PrestaShop. Los módulos, contra su paquete original. La tienda entera, contra una copia anterior si existe. Lo que cambia sin motivo es el primer sospechoso.
  4. Revisar lo que no son ficheros. Empleados y perfiles, cuentas de webservice y sus permisos, tareas programadas del servidor, claves de configuración de las pasarelas, JavaScript dentro de páginas CMS, de la configuración o de las descripciones de producto.
  5. Encontrar la vía de entrada. Registros de acceso web, del FTP y del panel. Sin saber por dónde entraron, la limpieza es provisional.
  6. Cerrar la entrada y luego limpiar. Corregir o retirar el módulo vulnerable, blindar las carpetas, quitar cuentas FTP sobrantes. Después, cuarentena de lo malicioso, que se guarda como evidencia en lugar de borrarse.
  7. Rotar todas las credenciales. Panel, FTP, base de datos, empleados, claves de API de pasarelas y servicios. Y cerrar todas las sesiones abiertas del back-office.
  8. Medir el daño. Qué pedidos y pagos pasaron por la tienda mientras el código estuvo activo, para avisar a la entidad de pago y decidir con el responsable del tratamiento la notificación a la AEPD.
  9. Dejar vigilancia. Una línea base limpia y avisos que salten en el mismo momento en que algo vuelva a cambiar.
  10. Proponer la salida de fondo. Si la tienda está en una versión sin soporte, el plan de migración. Limpiar una tienda vieja sin migrarla es comprar tiempo, no resolver.

RKR Security Alert: el módulo que sale de todo esto

Cada incidente de los que contamos aquí nos obligó a hacer a mano comprobaciones que se podían automatizar. De ahí salió RKR Security Alert, el módulo de seguridad que hemos desarrollado en Rekire y que usamos en nuestras propias auditorías. Funciona en PrestaShop 1.7.6 a 9.2, precisamente porque las tiendas que más lo necesitan son las que todavía no han migrado.

Qué vigila

  • Los datos de pago y la configuración. Guarda una foto de la configuración, los módulos, los empleados, las URL de la tienda y las cuentas de webservice, y la compara con el estado actual. No depende de los eventos de PrestaShop: si alguien cambia algo por SQL directo, saltándose el back-office, el cambio aparece igual. Los cambios en pasarelas de pago se marcan como críticos.
  • Los empleados. Altas, cambios y bajas, destacando las cuentas de superadministrador. Los administradores falsos del caso 1 habrían avisado el mismo día en que se crearon.
  • Los accesos. Entrada al back-office desde una IP nueva, con país, ciudad y aviso si es un proxy, una VPN o un centro de datos.
  • Las plantillas del pago. Huella de todas las plantillas del checkout de todos los temas instalados, no solo del activo. Que una de ellas cambie ya es el aviso: es exactamente lo que delató el caso 1.
  • Los módulos por versión. Si los ficheros de un módulo cambian sin que haya cambiado su versión, o aparece uno nuevo, se avisa. Es lo que habría delatado la sustitución del módulo de pago del caso 2.
  • Las tareas programadas y el blindaje de las carpetas.

Qué busca en los ficheros

  • Clonadores de pago, puertas traseras y web shells, ejecución de órdenes, ofuscación, JavaScript inyectado y código escondido en imágenes.
  • Web shells reconocidas por lo que saben hacer y no solo por firmas: listar, escribir y borrar ficheros con una ruta recibida por parámetro. Así se cazan las que están escritas en PHP limpio, como el falso lector de QR del caso 3.
  • Comparación del núcleo con el ZIP oficial de PrestaShop, que es lo único que detecta un cambio de un solo carácter en un fichero legítimo.
  • Un hallazgo crítico no se puede ocultar con un patrón de ruta: lo aprendimos de la tienda que pasó dos limpiezas con un cargador en vendor/.

El escaneo va por partes y se reanuda, así que no se cae por el límite de tiempo del servidor, y cada hallazgo trae la prueba: qué ha encontrado, en qué línea y desde dónde se alcanza.

El centinela del navegador

Hay ataques que no dejan nada en el disco, como el cargador por WebSocket del caso 3, o que solo aparecen cuando el cliente hace algo, como el formulario falso del caso 1. Para esos, el módulo incluye un centinela que mira la página ya montada en el navegador: avisa si aparece un campo de tarjeta fuera de un iframe después de cargar la página, si el checkout envía datos a un dominio nuevo con sendBeacon, fetch o XHR, si se abre un WebSocket externo o si una página escribe en el portapapeles un comando de sistema sin que el usuario haya pulsado nada (la técnica del captcha falso conocida como ClickFix). El centinela nunca guarda el contenido de esas peticiones: en un checkout contendrían datos de tarjeta reales.

Pensado para tiendas que ya llegan tocadas

Se instala en modo primera auditoría: no da nada por «normal» hasta que revisas el informe. Si la tienda ya estaba infectada al instalarlo, la infección no entra en la línea base. Los avisos llegan por Telegram, clasificados por gravedad (puedes separar un grupo para lo importante y otro para lo informativo), y se quedan también en la bandeja del panel aunque no uses Telegram.

Y una decisión de diseño que nos parece importante: nada sale de tu tienda. El análisis se hace en tu servidor con reglas que viajan en el módulo. No se envía a nadie ningún fichero, fragmento ni dato de tu base de datos.

Lo que no es. RKR Security Alert no es un cortafuegos ni un antivirus que bloquee ataques. Detecta y avisa, para que reacciones en horas y no en meses. Se complementa con lo básico: tienda y módulos actualizados, contraseñas únicas, accesos controlados y copias de seguridad.

Lista de comprobación para esta semana

Si has llegado hasta aquí, esto es lo que puedes hacer sin ayuda de nadie:

  1. Entra en Parámetros avanzados → Equipo y revisa cada empleado. Si hay uno que no reconoces, sobre todo con perfil de superadministrador, trata la tienda como comprometida.
  2. Concilia los cobros de la última semana en el panel de tu pasarela contra los pedidos pagados de la tienda.
  3. Haz una compra de prueba con un correo que no sea de la tienda, desde un navegador sin sesión de administrador, y fíjate en si el formulario de pago es el de siempre.
  4. Cambia la contraseña del panel del hosting y del FTP, que no se repita en ningún otro sitio, y activa la verificación en dos pasos del panel si tu proveedor la ofrece.
  5. Pide a tu hosting la lista de cuentas FTP y borra las que no uses.
  6. Mira en Módulos qué tienes instalado y en el FTP qué carpetas hay en modules/. Lo que esté en el disco y no en la lista sobra.
  7. Comprueba qué versión de PrestaShop y de PHP tienes. Si es PrestaShop 1.6 o 1.7, o PHP 7.x, ponle fecha a la migración.

Migrar no es un lujo: es la medida de seguridad más grande

Sabemos que migrar una tienda da pereza y respeto. Hay que revisar módulos, tema, URL, pagos, facturas. Pero después de ver por dentro todos estos casos, nuestra conclusión es clara: la tienda más cara de mantener es la que no se actualiza. Un incidente cuesta la limpieza, la notificación, el contracargo, el tiempo del equipo y, sobre todo, la confianza de los clientes cuyas tarjetas se usaron en otro sitio.

Una migración a PrestaShop 9 con PHP actual cierra de una vez las vías de entrada conocidas de las versiones viejas, te obliga a hacer inventario de lo que tienes instalado y te deja en una versión que sigue recibiendo correcciones. Si además vigilas lo que cambia, el siguiente intento se nota el mismo día.

Cómo resolverlo en PrestaShop

RKR Security Alert vigila configuración, pagos, empleados, accesos, plantillas del checkout y ficheros, compara el núcleo con el ZIP oficial y avisa por Telegram en cuanto algo cambia, en PrestaShop 1.7.6 a 9.2. RKR Sentinel te avisa de los errores de la web antes de que te los cuenten los clientes, y una tienda que de repente se queda en blanco, como la del caso 2, es un error que conviene ver al minuto. RKR Order Guard evita pedidos, estados de pago y facturas duplicados, para que lo que dice el back-office sea fiable cuando lo concilias con el banco.

Y si sospechas que tu tienda está comprometida o quieres migrarla antes de que lo esté, con los bonos de horas de soporte de Rekire hacemos la auditoría, la limpieza con el método de este artículo y la migración a PrestaShop 9.

Cargando...
Cookies
Volver arriba