PHP2Shell: qué hacer en tu tienda PrestaShop ante CVE-2026-109618 y CVE-2026-109619, aunque no puedas actualizarla
El 21 de octubre de 2026, el proyecto PHP publicó una actualización de emergencia para dos vulnerabilidades críticas del propio PHP, conocidas ahora conjuntamente como PHP2Shell: CVE-2026-109618 y CVE-2026-109619. Ambas pueden permitir que un atacante ejecute código en un servidor web sin iniciar sesión y, en algunas configuraciones, antes de que se haya ejecutado una sola línea del código de tu tienda.
Para la mayoría de los sitios web, el consejo es breve: actualiza PHP y reinícialo. En las tiendas PrestaShop no es tan sencillo, y por eso hemos escrito este artículo. Todas las versiones de PrestaShop anteriores a la 9.0 admiten oficialmente PHP 8.1 como máximo, y ni PHP 8.1 ni las versiones anteriores recibieron una versión oficial corregida. Por eso, buena parte de las tiendas PrestaShop del mundo no pueden limitarse a «actualizar PHP» esta semana.
Esta guía explica en qué consisten las vulnerabilidades, cómo averiguar si tu tienda está realmente expuesta (el número de versión por sí solo no te lo dice), qué hacer en cada versión de PrestaShop y la solución provisional que utilizamos para las tiendas que no pueden actualizarse ahora: pasarlas a un PHP 7.4 parcheado por un proveedor, primero en una copia de staging, y corregir las partes del código que fallen. Es un puente, no un destino definitivo. También es mucho mejor que seguir expuesto o cerrar la tienda.
Cómo se verificó
Los detalles de las vulnerabilidades, las versiones corregidas y las medidas temporales siguen el aviso de seguridad del proyecto PHP. El estado de los paquetes de los proveedores procede de sus anuncios y de los artículos publicados sobre ellos y cambia de semana en semana, así que confirma el tuyo con tu hosting. Los rangos de PHP de PrestaShop proceden de sus requisitos del sistema, y los detalles de PrestaShop 1.6 que aparecen más abajo se comprobaron en el propio código fuente de 1.6.1.23.
Qué es PHP2Shell, explicado de forma sencilla
Ambos fallos están en el motor de PHP, la parte que recibe una petición web y la prepara antes de que empiece a ejecutarse el código de tu tienda. Por eso no puede corregirlos ninguna actualización de PrestaShop, ningún módulo ni ningún tema. Solo un PHP corregido puede hacerlo.
| CVE | Nombre | Qué falla |
|---|---|---|
| CVE-2026-109618 | RCE por corrupción al agotar la memoria (OOM) | Cuando PHP se queda sin memoria en un momento inoportuno, los datos de la petición quedan a medio preparar y la limpieza posterior los trata como válidos. Las peticiones grandes diseñadas para ello pueden desencadenar el fallo. |
| CVE-2026-109619 | RCE por estado global obsoleto | El estado interno de una petición persiste después de liberar su memoria, y una petición posterior atendida por el mismo proceso de PHP puede utilizarlo. |
Los investigadores también demostraron que un atacante puede leer la memoria de los procesos de PHP sin iniciar sesión. Esa memoria puede contener contraseñas, tokens de sesión y claves de API de las peticiones de otros visitantes. Por eso es importante el apartado de limpieza al final de esta guía, aunque nadie haya introducido nada en tu servidor.
El problema afecta a cualquier instalación de PHP que atienda peticiones web: PHP-FPM, Apache con mod_php, php-cgi, FrankenPHP y LiteSpeed. El proyecto PHP considera que el riesgo es mayor con mod_php, donde demostró un exploit que se activa antes de ejecutar cualquier código de la aplicación. Este detalle importa si tienes una tienda PrestaShop: el inicio de sesión del back office, el modo de mantenimiento y todos los módulos de seguridad se ejecutan después de que PHP haya analizado la petición, así que ninguno de ellos impide el ataque.
La protección tiene que estar delante de PHP. Todo lo que está dentro de PrestaShop se ejecuta cuando el daño ya está hecho.

¿Hasta qué punto debes preocuparte?
Los fallos son graves y los ataques no tardaron en aparecer: los honeypots de Amazon registraron un intento el 17 de octubre, cuatro días antes de la divulgación, y Cloudflare informó de ataques la mañana de la publicación. Al mismo tiempo, Sansec, empresa de seguridad para comercio electrónico, señala que los exploits públicos no funcionan contra una instalación de PHP con la configuración predeterminada y que, en general, necesitan un segundo fallo, como una vulnerabilidad de inclusión de archivos en la aplicación. Por eso considera menos probable una explotación masiva. Trátalo como algo urgente, sin entrar en pánico: el objetivo es que tu tienda funcione con un PHP corregido lo antes posible.
La cronología
| Fecha (2026) | Qué ocurrió |
|---|---|
| Agosto | Dos equipos de investigación descubren los fallos de forma independiente y los comunican a PHP. |
| 17 de octubre | Se registra el primer intento de explotación en la telemetría de los honeypots. |
| 20 de octubre | Se filtran los detalles. El proyecto PHP anuncia una actualización de seguridad crítica para el día siguiente. |
| 21 de octubre | Se publican PHP 8.5.12, 8.4.27, 8.3.36 y 8.2.35, además de backports mínimos, solo en código fuente, para 7.4, 8.0 y 8.1. Las distribuciones de Linux y los proveedores de soporte a largo plazo habían recibido los parches con antelación. Cloudflare implementa reglas WAF para los vectores de explotación conocidos. |
| 22 de octubre | CloudLinux publica compilaciones corregidas de sus versiones de PHP Selector, que abarcan PHP de 5.2 a 5.6, de 7.0 a 7.4 y de 8.0 a 8.5. |
Por qué las tiendas PrestaShop lo tienen más difícil
Esta es la tabla incómoda. Muestra la versión máxima de PHP que admite oficialmente cada rama de PrestaShop, según sus propios requisitos del sistema, e indica si existe una versión oficial de PHP corregida dentro de ese rango.
| PrestaShop | PHP compatible | ¿Hay un PHP oficial corregido dentro del rango? | Tu opción viable |
|---|---|---|---|
| 9.0 | 8.1 a 8.4 | Sí: 8.2.35, 8.3.36, 8.4.27 | Versión corregida de tu rama de PHP |
| 9.1 | 8.1 a 8.5 | Sí: también 8.5.12 | Versión corregida de tu rama de PHP |
| 8.0 a 8.2 | 7.2 a 8.1 | No | 7.4, 8.0 u 8.1 parcheado por un proveedor, o actualizar PrestaShop a la versión 9 |
| 1.7.8 | 7.1 a 7.4 | No | 7.4 parcheado por un proveedor |
| 1.7.7 | 7.1 a 7.3 | No | Compilación parcheada de tu rama si tu proveedor de hosting dispone de ella; si no, el puente a 7.4 |
| 1.7.5 y 1.7.6 | 5.6 a 7.2 | No | Compilación parcheada si tu proveedor de hosting dispone de ella; si no, el puente a 7.4 |
| 1.7.0 a 1.7.4 | hasta 7.1 | No | Compilación parcheada si tu proveedor de hosting dispone de ella; si no, el puente a 7.4 |
| 1.6.1.x | hasta 7.1 | No | Compilación parcheada si tu proveedor de hosting dispone de ella; si no, el puente a 7.4 |
Un «No» en la tercera columna no significa que no exista una corrección. Significa que tiene que venir de otro sitio que no sea php.net: una distribución de Linux, el fabricante del panel de hosting, un proveedor de soporte a largo plazo o un PHP que compiles desde el código fuente con el backport mínimo del proyecto PHP. Ahí es donde deben buscar esta semana la mayoría de las tiendas PrestaShop, y también donde están las buenas noticias.
Cada fila sin celda verde depende de un backport del proveedor o del puente con PHP 7.4.

Paso 1: averigua qué PHP utiliza realmente tu tienda
Hay dos trampas en las que cae casi todo el mundo.
Primera trampa: el PHP que ves por SSH no es necesariamente el que atiende tu tienda. Los servidores suelen tener varias versiones de PHP instaladas en paralelo, y la línea de comandos puede utilizar una distinta de la del servidor web. En PrestaShop, abre Parámetros avanzados, Información (Advanced Parameters > Information): la versión de PHP que aparece ahí es la que realmente atiende las peticiones de tu tienda. La configuración de PHP del dominio en tu panel de hosting debería indicar lo mismo.
Segunda trampa: el número de versión no te dice si ya tienes el parche. Las distribuciones y los proveedores de hosting incorporan las correcciones de seguridad mediante backports a la versión que ya tienes y conservan su número original. Un «PHP 7.4.33» puede estar totalmente corregido en un servidor y completamente expuesto en otro. La prueba está en el aviso del proveedor para tu paquete exacto o en una respuesta por escrito de tu proveedor de hosting.
# Opcional: algunos servidores muestran su versión de PHP. Esto no demuestra que tengan el parche.
curl -sS -I https://www.example-shop.com/ | grep -i '^X-Powered-By:'
# Indicios en los registros de cambios de los paquetes. Encontrar ambas CVE es buena señal.
# No encontrar nada no demuestra nada: algunos proveedores solo registran un cambio de versión. Pregúntales.
# Ajusta el nombre del paquete a la versión y al gestor de PHP que atiende tu tienda.
# Debian y Ubuntu
zgrep -E 'CVE-2026-10961[89]' /usr/share/doc/php7.4-fpm/changelog.Debian.gz
# PHP del sistema en RHEL, AlmaLinux, Rocky y CloudLinux
rpm -q --changelog php-fpm | grep -E 'CVE-2026-10961[89]'
# cPanel EasyApache (ea-php) y CloudLinux PHP Selector (alt-php)
rpm -q --changelog ea-php74-php-fpm | grep -E 'CVE-2026-10961[89]'
rpm -q --changelog alt-php74-common | grep -E 'CVE-2026-10961[89]'
Tu proveedor de hosting puede tener ya un PHP antiguo parcheado, incluso PHP 5
Esto es lo que desconoce la mayoría de quienes tienen tiendas antiguas. Varios proveedores de hosting distribuyen sus propias compilaciones de versiones antiguas de PHP y también las han parcheado:
- CloudLinux PHP Selector (alt-php): las compilaciones corregidas para PHP de 5.2 a 5.6, de 7.0 a 7.4 y de 8.0 a 8.5 llegaron a los repositorios estables el 22 de octubre, en CloudLinux 7, 8 y 9 (CloudLinux 10 las recibe a través del repositorio de TuxCare).
- Compilaciones de cPanel PHP de CloudLinux (ea-php): parcheadas desde ea-php52 hasta ea-php85, conservando los números de versión anteriores.
- EasyApache PHP del propio cPanel: versiones oficiales de 8.2 a 8.5 y backports para 8.1 (8.1.34-5), 8.0 (8.0.30-12) y 7.4 (7.4.33-19). Las compilaciones de 7.3 y anteriores del propio cPanel no recibieron ninguna corrección; cPanel remite a esos usuarios a TuxCare.
- Red Hat y sus distribuciones derivadas: las correcciones se publican por separado para cada flujo de paquetes. Consulta los avisos de corrección del flujo exacto de PHP que tenga habilitado tu servidor y no des por hecho que una simple actualización del sistema lo haya cubierto: los primeros informes indicaban que algunos flujos ya estaban corregidos y otros seguían pendientes.
- TuxCare Endless Lifecycle Support: soporte de pago a largo plazo con parches para versiones de PHP cuyo ciclo de vida ha terminado.
Así, la misma etiqueta, «PHP 7.1» en tu panel de hosting, puede significar que tienes el parche con un proveedor y que eres vulnerable con otro. Antes de planificar cambios en el código, hazle una pregunta concreta a tu proveedor de hosting. Puedes enviarle este mensaje tal cual:
Asunto: PHP2Shell (CVE-2026-109618, CVE-2026-109619) en mi cuenta
Hola:
Mi tienda utiliza PHP X.Y (gestor: PHP-FPM / mod_php / LiteSpeed) en tus servidores.
¿La compilación de PHP que atiende mi sitio incluye la corrección de CVE-2026-109618 y
CVE-2026-109619? Por favor, indícame la versión exacta del paquete y si los procesos
de PHP se han reiniciado desde su instalación. Si mi versión no tiene corrección,
¿a qué versiones de PHP parcheadas puedo cambiar con mi plan?
Gracias.
Si la respuesta es «sí, ambos fallos están corregidos y los procesos se han reiniciado», la parte urgente queda resuelta sin tocar una línea de código. Lee el apartado sobre cómo investigar una posible intrusión y después planifica la actualización con calma.
Sin reinicio, la corrección no está activa
Los procesos de PHP en ejecución conservan el código antiguo en memoria. Después de cualquier actualización, reinicia por completo PHP-FPM, LiteSpeed o Apache (una recarga gradual no basta con mod_php). Los contenedores deben reconstruirse a partir de una imagen parcheada, no basta con reiniciarlos. Si tu servidor obtiene PHP del repositorio Remi, mantenido por voluntarios, ten en cuenta que no había ninguna actualización el día de la publicación. Vuelve a comprobarlo antes de dar por hecho que estás cubierto.
Paso 2: elige la opción para tu versión de PrestaShop
Sea cual sea tu versión, la primera opción es la misma: un paquete corregido de la rama de PHP que ya utiliza tu tienda. Pasar a otra rama de PHP es un cambio mayor y siempre debe probarse primero en una copia de staging, con tus módulos, overrides y proceso de compra.
Pregunta a tu hosting antes de planificar cambios de código: la ruta más barata es una compilación parcheada que ya tienes disponible.

PrestaShop 9
Actualiza a la versión corregida de tu rama: 8.2.35, 8.3.36 o 8.4.27, o 8.5.12 en PrestaShop 9.1. Reinicia y confirma la versión en la página Información. Si tu tienda 9.0 sigue utilizando PHP 8.1, pasar a 8.2 o una versión posterior supone cambiar de rama: pruébalo primero en staging o utiliza mientras tanto un PHP 8.1 parcheado por un proveedor.
PrestaShop 8.0 a 8.2
Estas versiones admiten oficialmente PHP de 7.2 a 8.1, y ninguna de esas ramas tiene una versión corregida de php.net. Eso deja más opciones de proveedores de lo que parece: un PHP 8.1 parcheado (8.1.34-5 de cPanel, alt-php81 de CloudLinux, el paquete php8.1 de Ubuntu 22.04, TuxCare), pero también un PHP 8.0 o 7.4 parcheado de esos mismos proveedores, todos dentro del rango oficial de PrestaShop 8. Si no tienes acceso a ninguna compilación parcheada, la solución duradera es actualizar a PrestaShop 9. Hasta que dispongas de un entorno de ejecución corregido, aplica las medidas temporales que aparecen más abajo.
PrestaShop 1.7.8
PHP 7.4 es su límite oficial, y resulta relativamente fácil encontrar compilaciones de 7.4 parcheadas: cPanel 7.4.33-19, CloudLinux alt-php74, TuxCare y paquetes de distribuciones cuyos proveedores ya los hayan publicado. Si tu tienda utiliza un PHP anterior, pasarla a un 7.4 parcheado sigue estando dentro del rango oficial de PrestaShop 1.7.8. Aun así, pruébalo en staging.
PrestaShop 1.6.1.x y 1.7.0 a 1.7.7
Estas versiones llegan oficialmente hasta PHP 7.1, 7.2 o 7.3. Primero, pregunta a tu proveedor de hosting si existe una compilación parcheada de tu versión actual (consulta el apartado anterior). Si existe, pasa a ella y la parte urgente queda resuelta. Si no, aquí entra nuestra solución provisional.
La solución provisional que utilizamos: un puente con PHP 7.4 parcheado
Esto es lo que hacemos con las tiendas que mantenemos y que no pueden actualizarse este mes. La idea: hacer que la tienda funcione con un PHP 7.4 que un proveedor siga parcheando, aunque su versión de PrestaShop solo admita oficialmente versiones anteriores a 7.4, y corregir las partes del código que no sean compatibles. En nuestra experiencia, el núcleo de PrestaShop 1.6.1 y 1.7 genera sobre todo avisos y advertencias de funciones obsoletas en PHP 7.4, no errores fatales. Lo que suele fallar de verdad es un puñado de módulos antiguos y overrides. Es una solución provisional y lo decimos claramente: durante un tiempo estarás fuera de la matriz de compatibilidad oficial de PrestaShop. Pero cierra la brecha y permite que la tienda siga vendiendo mientras planificas la actualización definitiva.
Un puente, no un destino: cierra la brecha y permite seguir vendiendo hasta la actualización definitiva.

Un ejemplo concreto de por qué 7.4 funciona donde PHP 8 no lo haría: el propio archivo Cookie.php de PrestaShop 1.6.1.23 contiene $this->_path{0}. En PHP 7.4, esa sintaxis con llaves solo está obsoleta; en PHP 8.0 provoca un error fatal. Esa sola línea marca la diferencia entre un puente que aguanta y una tienda que no carga.
1. Crea una copia de staging y evita que afecte a producción
Copia los archivos y la base de datos a un lugar independiente, por ejemplo, un subdominio protegido con contraseña. Después, antes de que la copia responda a una sola petición:
- Conéctala a su propia base de datos. La configuración copiada todavía contiene las credenciales de la base de datos de producción (
config/settings.inc.phpen 1.6,app/config/parameters.phpen 1.7). Cámbialas por las de la base de datos de staging, preferiblemente con un usuario de base de datos que no tenga acceso a producción. Todo lo que sigue da por hecho que has hecho esto primero. - Bloquea sus conexiones de salida. Antes de que la copia responda a su primera petición o ejecute cualquier tarea, bloquea a nivel de servidor, independientemente de PrestaShop, el correo saliente y las conexiones con tus servicios de producción (API de pagos, transportistas y marketplaces), y permite únicamente los servicios sandbox que quieras probar. La configuración de PrestaShop por sí sola no basta: algunos módulos envían correo o se comunican con marketplaces mediante sus propias conexiones. Después, desactiva las tareas cron copiadas y pon todos los módulos de pago en modo de prueba o sandbox.
- Impide el acceso de visitantes y buscadores mediante la protección con contraseña del servidor web.
Después, solo en la base de datos de staging:
-- SOLO EN LA BASE DE DATOS DE STAGING. Sustituye ps_ por el prefijo de tus tablas.
-- 1. El propio PrestaShop nunca envía correo desde esta copia
UPDATE ps_configuration SET value = '3' WHERE name = 'PS_MAIL_METHOD';
-- 2. Asigna a la copia su propia dirección (una sola tienda, instalada en la raíz del dominio)
SELECT id_shop_url, id_shop, domain, domain_ssl, physical_uri FROM ps_shop_url;
UPDATE ps_shop_url
SET domain = 'staging.example-shop.com', domain_ssl = 'staging.example-shop.com', physical_uri = '/'
WHERE id_shop_url = 1;
UPDATE ps_configuration SET value = 'staging.example-shop.com'
WHERE name IN ('PS_SHOP_DOMAIN', 'PS_SHOP_DOMAIN_SSL');
En una instalación multitienda, asigna cada URL de tienda por separado en lugar de utilizar el ejemplo de una sola tienda.
2. Pasa la copia al PHP 7.4 parcheado y registra todos los errores
Selecciona el PHP 7.4 parcheado para el sitio de staging en tu panel de hosting. Establece error_reporting en E_ALL, registra los errores en un archivo y evita que se muestren en pantalla. Comprueba que el registro recibe entradas de verdad y después ordena los fallos por frecuencia, de mayor a menor:
# Ordena los errores de PHP en staging por frecuencia, de mayor a menor (formato estándar del registro de PHP)
grep -E 'PHP (Fatal error|Parse error|Recoverable fatal error|Warning|Notice|Deprecated):' /path/to/php-error.log \
| sed -E 's/^\[[^]]*\] //' | sort | uniq -c | sort -rn | head -40
3. Revisa el código que suele fallar
Antes de recorrer la tienda, un análisis estático rápido de los módulos, los overrides y el tema te señala los sospechosos habituales. Es una lista de comprobación parcial: no detecta llamadas indirectas, llamadas repartidas en varias líneas ni algunos accesos a posiciones mediante llaves, así que un resultado vacío no demuestra que exista compatibilidad. Revisa cada coincidencia.
# Funciones eliminadas o declaradas obsoletas en PHP 7.x
grep -rnE --include='*.php' \
'\beach\s*\(|create_function\s*\(|get_magic_quotes_(gpc|runtime)\s*\(|\bmysql_[a-z_]+\s*\(|\beregi?(_replace)?\s*\(|\bsplit\s*\(|mcrypt_[a-z_]+\s*\(' \
modules override themes
# Llamadas a preg_replace: comprueba si alguna utiliza el modificador /e eliminado
grep -rnE --include='*.php' '\bpreg_replace\s*\(' modules override themes
# Acceso a posiciones de cadenas con llaves ($str{0}), obsoleto en PHP 7.4
grep -rnE --include='*.php' '\$[A-Za-z_][A-Za-z0-9_]*\{[^}$]*\}' modules override themes
# Comprueba la sintaxis de cada archivo PHP con el binario de destino, desde la raíz de staging
# (su nombre varía: php7.4, php74, /opt/cpanel/ea-php74/root/usr/bin/php ...)
find . -type f -name '*.php' -exec php7.4 -l {} \; | grep -v '^No syntax errors'
Una comprobación de sintaxis sin errores solo demuestra que los archivos se pueden analizar. No dice nada sobre extensiones que falten ni sobre cómo funciona el proceso de compra; para eso está el paso 5.
4. Corrige lo que falle, empezando por el cambio más pequeño
Estos son los fallos que encontramos con más frecuencia cuando una tienda antigua pasa a PHP 7.4, y la solución para cada uno:
| Código | Cambió en | Qué ves | Solución |
|---|---|---|---|
mysql_*, ereg*, split() | eliminados en 7.0 | Error fatal: llamada a una función no definida | La clase Db de PrestaShop y las funciones preg_*, manteniendo exactamente el mismo comportamiento |
preg_replace con el modificador /e | eliminado en 7.0 | Una advertencia y la función devuelve null, por lo que desaparece texto sin que resulte evidente | preg_replace_callback con la misma lógica |
mcrypt_* | eliminadas en 7.2 (siguen disponibles como extensión independiente) | Error fatal: llamada a una función no definida | Consulta la nota sobre cifrado que aparece más abajo |
each() | obsoleta en 7.2 | «La función each() está obsoleta» | foreach |
create_function() | obsoleta en 7.2 | «La función create_function() está obsoleta»; el callback sigue ejecutándose en 7.4 | Una función anónima con el mismo comportamiento |
count() sobre null o una cadena | advertencia desde 7.2 | «count(): el parámetro debe ser un array o un objeto que implemente Countable» | Comprueba primero el tipo (is_countable() en 7.3 y posteriores). El resultado no cambió: null sigue contando como 0 y una cadena como 1 |
continue dentro de switch | advertencia desde 7.3 | «continue» dentro de switch equivale a «break» | continue 2 o break, según la intención del autor |
$str{0} | obsoleta en 7.4 | «La sintaxis de acceso a posiciones de arrays y cadenas mediante llaves está obsoleta» | $str[0] |
| Acceso a un array sobre null o false | aviso desde 7.4 | «Se intenta acceder a una posición de array en un valor de tipo null» (o «bool» para false) | isset() o un valor predeterminado |
get_magic_quotes_gpc() | obsoleta en 7.4 | «La función get_magic_quotes_gpc() está obsoleta» | Elimina la llamada: desde PHP 5.4 siempre devuelve false |
implode($pieces, $glue) | obsoleta en 7.4 | «implode(): pasar la cadena separadora después del array está obsoleto. Intercambia los parámetros» | implode($glue, $pieces) |
| Operador ternario anidado sin paréntesis | obsoleto en 7.4 | «`a ? b : c ? d : e` sin paréntesis está obsoleto» | Añade paréntesis |
Corrige primero los errores fatales, después las advertencias del proceso de compra y luego el resto. Los avisos y las advertencias de funciones obsoletas no son inofensivos porque los visitantes no los vean: el gestor de errores de un módulo puede convertirlos en excepciones, y una avalancha de ellos puede llenar el disco. Si el autor de un módulo ofrece una actualización, úsala antes de crear tu propio parche, y lleva una lista por escrito de todos los archivos que cambies: la necesitarás para el cambio en producción y, de nuevo, para la actualización definitiva. Ya que estás revisando la configuración, elimina las líneas php_value y php_flag de .htaccess que correspondan a ajustes que PHP ya no reconozca. El aviso de PHP pide expresamente eliminar los ajustes por petición que sean inválidos o estén obsoletos.
Una nota sobre el cifrado
PrestaShop 1.6.1.23 cifra sus cookies con OpenSSL cuando está disponible, pero el código que las firma sigue leyendo la constante de mcrypt MCRYPT_RIJNDAEL_128. Sin mcrypt, PHP 7.4 genera una advertencia en cada petición y utiliza un valor distinto, así que las cookies de todos los usuarios dejan de coincidir (y en PHP 8 se produce un error fatal). La solución que mantiene válidas las cookies existentes consiste en definir la constante con el valor que utilizaba mcrypt, en un archivo que PrestaShop 1.6 carga automáticamente al principio:
Las versiones más antiguas de 1.6 y algunos módulos llaman directamente a funciones de mcrypt. Necesitan la extensión independiente de mcrypt para 7.4 o una reescritura, y los datos ya cifrados con mcrypt deben seguir siendo legibles después: OpenSSL no es un sustituto directo para los valores cifrados existentes.
<?php
// config/defines_custom.inc.php (PrestaShop 1.6 incluye este archivo automáticamente)
// PHP 7.2+ no incluye mcrypt, pero la firma de cookies de 1.6.1 sigue leyendo esta
// constante. El mismo valor que definía la extensión mcrypt mantiene válidas las cookies existentes.
if (!defined('MCRYPT_RIJNDAEL_128')) {
define('MCRYPT_RIJNDAEL_128', 'rijndael-128');
}
Este es el código en cuestión, sin cambios respecto a PrestaShop 1.6.1.23 (classes/Rijndael.php):
// PrestaShop 1.6.1.23, classes/Rijndael.php
protected function generateHmac($encrypted)
{
$macKey = $this->generateKeygenS2k('sha256', $this->_key, $this->_iv, 32);
return hash_hmac(
'sha256',
$this->_iv . MCRYPT_RIJNDAEL_128 . $encrypted,
$macKey
);
}
5. Recorre todo el circuito de venta y después haz el cambio con las correcciones
En staging, revisa todo lo que genera ingresos o trabajo: página de inicio, páginas de categorías con filtros, búsqueda, páginas de producto con combinaciones, carrito, proceso de compra con cada transportista y cada método de pago en modo de prueba, confirmación del pedido, página del pedido en el back office, PDF de facturas y albaranes, página de configuración de cada módulo, importaciones y URL de las tareas cron.
Cuando dejen de aparecer errores en el registro, programa el cambio en producción para una hora de poca actividad:
- Haz una copia de seguridad cuya restauración ya hayas probado al menos una vez, tanto de los archivos como de la base de datos.
- Aplica las correcciones de código probadas y cambia PHP a la vez. Las correcciones están en staging hasta que las copies a producción. Nunca sobrescribas la base de datos de producción con la de staging.
- Comprueba inmediatamente el proceso de compra y después vigila el registro de errores durante 48 horas.
- Si tienes que volver atrás al PHP antiguo sin parchear, restringe el acceso a la tienda mientras lo haces y mantenlo restringido hasta que vuelvas a tener un entorno de ejecución corregido.
Un puente tiene dos extremos
La cobertura de los proveedores para las versiones antiguas de PHP varía, y sus condiciones también. Consigue una confirmación por escrito de lo que cubre tu proveedor y de cómo anuncia los cambios, y fija tu propia fecha para la actualización definitiva. La lista de archivos que modificaste para el puente es el punto de partida de ese proyecto. Nuestro artículo sobre cómo migrar de PrestaShop 1.6 a 8 o 9 explica los siguientes pasos.
Hasta que tengas el parche: medidas temporales
El proyecto PHP publicó medidas que reducen la exposición a vías de ataque concretas. Según sus propias palabras, no convierten una instalación en segura y solo una actualización resuelve el problema por completo. Tampoco te permiten esperar con seguridad. Conviene aplicarlas durante las horas o días que falten hasta que tu tienda funcione con un PHP corregido. Así se aplican a una tienda PrestaShop.
Ajustes de PHP
Debes establecerlos en php.ini, en el pool de PHP-FPM o en la configuración del servidor, no en .user.ini ni con ini_set(). Después, reinicia todos los procesos de PHP.
; Medidas temporales contra PHP2Shell en php.ini (reinicia PHP después)
; El núcleo de PrestaShop no utiliza el seguimiento del progreso de subida, así que puedes desactivarlo
session.upload_progress.enabled = 0
; Cuerpos de petición más pequeños. Valores de ejemplo: adáptalos a las necesidades reales de tu tienda,
; y nunca aumentes un límite que ya sea inferior
post_max_size = 32M
upload_max_filesize = 24M
max_file_uploads = 10
; En un archivo de pool de PHP-FPM (por ejemplo /etc/php/7.4/fpm/pool.d/shop.conf), los mismos
; ajustes se escriben así; elimina los puntos y coma iniciales para activarlos:
; php_admin_flag[session.upload_progress.enabled] = off
; php_admin_value[post_max_size] = 32M
; php_admin_value[upload_max_filesize] = 24M
Tras cambiar los límites, prueba las subidas de archivos que realmente utiliza tu equipo: un archivo de módulo grande o una imagen de producto de gran tamaño pueden superarlos. La lista oficial también propone memory_limit = -1 frente al fallo por agotamiento de memoria, aplicado de forma que ningún ajuste de la aplicación pueda volver a imponer un límite. Eso permite que una sola petición utilice toda la memoria del servidor, así que es una opción únicamente para administradores que puedan limitar la memoria de PHP mediante un contenedor o cgroup y sepan qué ocurre cuando se alcanza ese límite. No elimina el fallo por completo, y el aviso desaconseja utilizar RLIMIT_AS o RLIMIT_DATA como alternativa. En un hosting compartido, déjalo en manos de tu proveedor. Para PHP 8.5, el aviso también incluye fatal_error_backtraces = 0.
Rechaza las subidas de archivos donde la tienda no las necesite
El exploit conocido llega como una petición multipart/form-data, el formato que utilizan los navegadores para subir archivos. La mayor parte de la zona pública de una tienda PrestaShop nunca lo necesita. Bloquearlo fuera del back office corta esa vía conocida. Qué deja de funcionar: los archivos adjuntos del formulario de contacto, los campos de archivo de la personalización de productos y cualquier módulo que permita a los clientes subir archivos. Para la mayoría de las tiendas, es una limitación aceptable durante unos días.
Primero, una condición: la excepción para el back office solo tiene sentido si has restringido su acceso a tus propias direcciones IP en el servidor web, de forma que las peticiones de cualquier otro origen nunca lleguen a PHP. Una página de inicio de sesión de PrestaShop no puede protegerte de un fallo que se activa antes de que PrestaShop se ejecute. Nuestro artículo sobre seguridad del back office incluye listas de direcciones permitidas listas para usar en Apache y nginx. Si no puedes restringir así el back office, omite la excepción y suspende también las subidas de archivos desde el back office durante unos días.
En Apache, coloca esto al principio del archivo .htaccess de la tienda, por encima de la línea # ~~start~~, para que PrestaShop lo conserve al regenerar el archivo. Sustituye admin-folder-name por la carpeta de tu back office:
# Medida temporal contra PHP2Shell: rechaza peticiones multipart fuera del back office.
# Elimina esta regla después de aplicar el parche.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:Content-Type} multipart/form-data [NC]
RewriteCond %{REQUEST_URI} !^/admin-folder-name/
RewriteRule ^ - [F]
</IfModule>
La regla solo funciona si mod_rewrite está activo y los archivos .htaccess tienen permiso para utilizarlo, así que pruébala: una subida de prueba inofensiva al formulario de contacto debería mostrar ahora una página de error 403, y esa página de error no debe ser a su vez un script PHP.
En nginx, dentro del bloque server de la tienda:
# Medida temporal contra PHP2Shell: rechaza peticiones multipart fuera del back office.
set $block_multipart 0;
if ($http_content_type ~* "multipart/form-data") { set $block_multipart 1; }
if ($uri ~ "^/admin-folder-name/") { set $block_multipart 0; }
if ($block_multipart) { return 403; }
Utiliza $uri, la ruta normalizada, como en el ejemplo. Con $request_uri, que contiene la ruta sin normalizar, se podría eludir el bloqueo mediante una ruta como /admin-folder-name/../index.php.
La protección delante de tu tienda
- Cloudflare implementó reglas WAF para los vectores de explotación conocidos, también en los planes gratuitos. Solo ayudan si todo el tráfico de tu tienda pasa realmente por Cloudflare y nadie puede acceder directamente a tu servidor. En los planes de pago, debes confirmar que las reglas administradas estén configuradas para bloquear. Se informó de que los atacantes estaban probando formas de eludirlas.
- Imunify360, habitual en hosting compartido, publicó reglas que bloquean la herramienta pública de explotación y variantes de CVE-2026-109619. Según CloudLinux, sus reglas todavía no cubren CVE-2026-109618. Otros firewalls ofrecen coberturas distintas.
- El modo de mantenimiento no ayuda. PrestaShop decide mostrar la página de mantenimiento después de que PHP ya haya procesado la petición. Si tu proveedor de hosting no puede aplicar el parche pronto, pregúntale si puede impedir por completo que las peticiones no fiables lleguen a PHP.
Después del parche: investiga una posible intrusión
Se detectaron intentos antes de la divulgación, y el fallo de exposición de memoria puede filtrar datos secretos sin dejar rastro en tu tienda. Si tu tienda estuvo conectada a internet con un PHP sin parchear después de mediados de octubre, dedica una hora a estas comprobaciones. Detectan rastros habituales; un resultado limpio no demuestra que no haya pasado nada.
# Archivos ejecutables en carpetas que solo deberían contener imágenes y archivos subidos.
# PrestaShop incluye un index.php en casi todas las carpetas: compáralos también con una copia limpia.
find img upload download -type f \( -iname '*.php' -o -iname '*.phtml' -o -iname '*.phar' \)
# Archivos modificados desde los primeros intentos de explotación (17 de octubre de 2026), incluidas las cachés.
# Solo son indicios: las marcas de tiempo pueden falsificarse. Revisa toda la lista.
find . -type f -newermt '2026-10-17 00:00:00 UTC'
-- Cuentas del back office, de más reciente a más antigua. ¿Hay alguna que no reconozcas?
SELECT id_employee, firstname, lastname, email, active, last_connection_date
FROM ps_employee
ORDER BY id_employee DESC;
La comparación más fiable es con una copia limpia de tu versión de PrestaShop, tus módulos y una copia de seguridad anterior al 17 de octubre, incluidos los archivos JavaScript, porque ahí se aloja el código inyectado que roba datos de pago. Si encuentras algo, conserva las pruebas y contiene la intrusión antes de cambiar cualquier contraseña; de lo contrario, las credenciales nuevas se filtrarán de la misma manera.
Después, cambia las credenciales que una fuga de memoria haya podido exponer, desde un dispositivo de confianza: todas las contraseñas del back office, las claves de API de los módulos de pago, transportistas y marketplaces, las claves del servicio web y las contraseñas SMTP. En el caso de la contraseña de la base de datos, cámbiala a la vez en el servidor de base de datos y en la configuración de la tienda (config/settings.inc.php en 1.6, app/config/parameters.php en 1.7 y posteriores), además de en cualquier otro servicio que se conecte con ella; si no, la tienda dejará de funcionar.
No cambies la clave de las cookies por impulso
La clave _COOKIE_KEY_ de PrestaShop parece un secreto que deberías cambiar sin dudar. En PrestaShop 1.6 forma parte del hash de la contraseña de cada cliente y empleado, y en 1.7 y posteriores sigue siendo necesaria para los hashes de contraseñas antiguas que no se hayan actualizado desde una migración (los hashes bcrypt modernos no la utilizan). Cambiarla impide el acceso a esas cuentas y cierra la sesión de todo el mundo. Cámbiala solo si tienes un plan de recuperación de contraseñas para el personal y los clientes.
¿Quieres que lo revise alguien más?
Nuestro Análisis de seguridad, gratuito y de código abierto, busca rastros habituales de un ataque, incluidos archivos PHP fuera de lugar en carpetas de recursos y configuraciones expuestas, y te ofrece un informe con prioridades. Si quieres una revisión completa, la Auditoría de seguridad & informe de refuerzo PrestaShop es una comprobación que nuestro equipo realiza por ti. Y si tu tienda necesita que configuremos y supervisemos el puente a 7.4 o un PHP parcheado por un proveedor, es parte del trabajo diario de nuestro Plan de cuidado & mantenimiento de tienda PrestaShop. Nuestros módulos están desarrollados para PHP 7.1 y posteriores, así que pasar a un PHP 7.4 u 8.x parcheado no los deja atrás; como con cualquier módulo, comprueba los requisitos de cada uno para las versiones de PHP y PrestaShop que elijas.
Preguntas frecuentes
¿Es vulnerable el propio PrestaShop?
Los fallos están en PHP, no en PrestaShop. Todas las versiones de PrestaShop quedan expuestas si el PHP con el que funcionan no está parcheado, y ninguna actualización de PrestaShop puede corregirlo. Solo puede hacerlo una compilación corregida de PHP, ya sea de php.net o de un proveedor.
Mi proveedor de hosting dice que utilizo PHP 7.1. ¿Soy vulnerable?
Depende de quién haya preparado la compilación. Algunos proveedores de hosting, entre ellos CloudLinux, parchearon incluso compilaciones de PHP 5 y 7. Otros no lo hicieron. El número de versión es el mismo en ambos casos, así que pide a tu proveedor de hosting la versión del paquete y la confirmación de que incluye la corrección de ambas CVE.
¿Me protegerán Cloudflare o un firewall?
En parte. Las reglas perimetrales bloquean los patrones de explotación conocidos y te dan algo de tiempo, pero solo para el tráfico que realmente pasa por ellas. Los atacantes se adaptan y la cobertura varía entre proveedores y entre los dos fallos. Considéralas un obstáculo para los ataques mientras aplicas el parche.
¿Debo desconectar mi tienda?
Algunos organismos públicos aconsejaron desconectar los sistemas que no pudieran corregirse. Para una tienda, el orden que seguimos es este: pide hoy a tu proveedor de hosting una compilación parcheada, aplica las medidas temporales y el bloqueo de subidas de archivos, y consigue que la tienda funcione con un PHP corregido lo antes posible. Si nada de eso es viable a corto plazo, la opción que queda es restringir el acceso público. El modo de mantenimiento de PrestaShop no cuenta, porque PHP procesa la petición antes de que PrestaShop muestre la página de mantenimiento.
¿Dejarán de funcionar mis módulos si paso de PHP 7.1 a 7.4?
Normalmente algunos necesitan pequeñas correcciones, muy a menudo las que aparecen en la lista anterior. Precisamente por eso debes hacerlo primero en una copia de staging, registrando los errores, antes de cambiar la tienda de producción.
¿Es el puente con PHP 7.4 una solución permanente?
No. Cierra esta brecha y permite que la tienda siga vendiendo, pero estás fuera de la matriz de compatibilidad oficial de PrestaShop y dependes de que tu proveedor mantenga la cobertura para 7.4. Aprovecha ese tiempo para planificar la actualización a versiones actuales de PrestaShop y PHP.
¿Tengo que cambiar las contraseñas?
Si tu tienda estuvo conectada a internet con un PHP sin parchear después de mediados de octubre, sí: contraseñas del back office, contraseña de la base de datos y claves de API, después de comprobar si hay indicios de intrusión. No toques la clave de las cookies salvo que tengas un plan de recuperación de contraseñas.
Fuentes
- Proyecto PHP: aviso de seguridad y anuncios de versiones, con los avisos GHSA-w8hw-w9fx-j79w y GHSA-6wmf-4rv5-p3rp
- PrestaShop: requisitos del sistema de 1.6 y 1.7, 8 y 9
- CloudLinux: cobertura de PHP2Shell y estado de los paquetes
- Sansec: investigación sobre PHP2Shell para comercio electrónico