En resumen: quien quiere actualizar dependencias necesita un proceso para tres mundos de paquetes: paquetes de Composer en el código PHP, módulos de npm en el build del frontend y plugins o temas en el CMS. Forman parte de él un ritmo fijo, una persona responsable, pruebas antes del despliegue y un plan para los paquetes sin actualización. Frente a PHP2Shell no ayuda, porque esa vulnerabilidad está en el propio PHP, pero sí frente a las muchas vulnerabilidades del código ajeno.
Tres mundos de paquetes, un punto ciego
En la semana posterior al 21 de octubre de 2026, todo giró en torno al intérprete de PHP. Muchos equipos se dieron cuenta entonces de que no conocen con exactitud las versiones de sus propios componentes. El sitio web funciona, la agencia se ocupa, el plugin avisa cuando hay algo nuevo: así o de forma parecida suenan las suposiciones, hasta que alguien comprueba.
Un proyecto PHP típico se compone hoy de bastante más código ajeno que propio. El OWASP Top 10 recoge los componentes vulnerables y obsoletos como categoría de riesgo propia. El problema rara vez es la falta de herramientas, sino la falta de rutina: las actualizaciones se hacen cuando alguien tiene tiempo y los avisos de seguridad acaban en un buzón que nadie lee.
¿Qué dependencias se actualizan dónde?
Cada mundo de paquetes tiene herramientas propias y trampas propias. La tabla siguiente ayuda a no pasar nada por alto.
| Mundo de paquetes | Mostrar el inventario | Comprobar vulnerabilidades | Trampa típica |
|---|---|---|---|
| Composer (bibliotecas PHP) | composer show |
composer audit |
Paquetes indirectos que nadie conoce |
| npm (build del frontend) | npm ls |
npm audit |
Una actualización sin recompilar nunca llega al servidor |
| Plugins y temas de CMS | Interfaz de administración o CLI | Avisos del fabricante, servicios de seguridad | Plugins abandonados, plugins de pago sin canal de actualización |
| PHP y extensiones | Gestión de paquetes | Security tracker de la distribución | La versión mostrada dice poco sobre los backports |
La última fila no forma parte, en sentido estricto, de las dependencias de la aplicación, pero a menudo se olvida en el mismo momento. Lo mismo vale para los scripts que se incorporan directamente desde servidores ajenos, como bibliotecas de un CDN, widgets de chat o código de seguimiento. No aparecen en ningún archivo de bloqueo, pero se ejecutan en el navegador de sus visitantes. Inclúyalos en la lista y compruebe si se incorporan versiones fijas en lugar de «siempre la más reciente». Los detalles sobre composer audit, el archivo de bloqueo y la integración en el build figuran en la guía Comprobar vulnerabilidades en las dependencias de Composer. Cómo funciona Composer en general lo explica Composer: el gestor de paquetes de PHP.
El ciclo de mantenimiento en seis pasos
Un proceso sostenible no tiene por qué ser complicado. Este orden ha dado buen resultado:
- Registrar el inventario: para cada proyecto, una lista de las dependencias directas con versión, origen y finalidad. Los archivos de bloqueo (
composer.lock,package-lock.json) pertenecen al repositorio. - Recopilar avisos: las herramientas de comprobación se ejecutan en cada build y, además, con regularidad sobre el estado desplegado, incluso sin cambios en el código.
- Valorar: ¿se usa el paquete afectado en producción?, ¿es accesible la función afectada?, ¿existe una versión corregida?
- Actualizar y probar en staging: primero las actualizaciones de seguridad dentro de la misma versión principal; los saltos a nuevas versiones principales se planifican como proyecto aparte.
- Desplegar con vía de retorno: el estado anterior sigue disponible como paquete o release, con copia de seguridad de la base de datos antes de la actualización.
- Documentar: qué se actualizó y cuándo, qué no se actualizó deliberadamente y por qué.
Preste atención además a las indicaciones de versión en composer.json y package.json. Las restricciones demasiado estrechas impiden que las correcciones de seguridad puedan siquiera instalarse. Las demasiado amplias, en cambio, traen al proyecto sin comprobar nuevas versiones principales. Ha dado buen resultado permitir actualizaciones dentro de la versión principal y planificar deliberadamente el salto a la siguiente.
Para los plugins del CMS, las actualizaciones disponibles suelen poder mostrarse también en la línea de comandos; en WordPress, por ejemplo, con WP-CLI:
# Mostrar las actualizaciones disponibles sin cambiar nada
wp plugin list --update=available
wp theme list --update=available
# Paquetes del frontend: versiones obsoletas y vulnerabilidades conocidas
npm outdated
npm audit --omit=dev
Las actualizaciones automáticas de plugins directamente en el sistema de producción son cómodas, pero arriesgadas si nadie comprueba después. Actívelas solo si se garantizan una copia de seguridad antes de cada ejecución y una verificación después.
Si no hay actualización
No todo aviso se resuelve con un clic. La hoja de referencia de OWASP sobre el trato con dependencias vulnerables distingue varios casos que se trasladan bien al día a día:
- Parche disponible: aplicarlo en staging, probar, desplegar. Si algo se rompe, adaptar el código propio en lugar de dejar sin aplicar la actualización.
- Parche anunciado, pero aún no disponible: aplicar la solución provisional del fabricante, desactivar o blindar si es posible la función afectada y dejar constancia de la decisión.
- No se espera parche: buscar un paquete sustituto o portar usted mismo la corrección, con una prueba que distinga la vulnerabilidad antes y después del parche.
En los plugins de CMS es frecuente un cuarto caso: el plugin está abandonado. Entonces solo ayuda sustituirlo o eliminarlo. Lo mismo vale para plugins de origen dudoso, por ejemplo copias «gratuitas» de plugins de pago. No reciben actualizaciones por el canal oficial y no pocas veces contienen ellas mismas código malicioso. Las indicaciones para operadores de WordPress se reúnen en WordPress y PHP2Shell.
Aclarar las responsabilidades antes del próximo aviso
La razón más frecuente de paquetes obsoletos no es un obstáculo técnico, sino una pregunta abierta: ¿quién lo hace? En proyectos construidos por una agencia y operados internamente, a menudo nadie se siente responsable. Defina para cada proyecto quién recibe los avisos, quién los valora y quién da el visto bueno, y déjelo por escrito.
Reserve además tiempo. Una fecha fija de mantenimiento al mes, en la que se comprueben y actualicen las dependencias, evita que las actualizaciones se acumulen durante años. Cuanto más tiempo lleve un proyecto sin actualizarse, mayor y más arriesgado será el siguiente salto. Cómo encajan las actualizaciones de PHP y de paquetes en un proceso global lo describe La gestión de parches como proceso, no como apagafuegos.
¿Cómo ayuda PHP SOS en concreto?
- Registramos todas las dependencias de sus proyectos procedentes de Composer, npm y CMS y marcamos los paquetes obsoletos, vulnerables y abandonados.
- Configuramos comprobaciones automáticas y definimos quién valora cada aviso.
- Actualizamos en staging, probamos los procesos más importantes y desplegamos con vía de retorno.
- En el marco de un contrato de mantenimiento de seguridad asumimos el ciclo mensual de forma permanente, incluidas las actualizaciones de PHP.
Conclusión: las dependencias actualizadas no son un proyecto, sino una rutina. Quien regula una vez bien el inventario, el ritmo y las responsabilidades solo tendrá que comprobar en el próximo gran aviso, no empezar a buscar.
Preguntas frecuentes
¿Con qué frecuencia deben actualizarse las dependencias?
Las actualizaciones de seguridad, lo antes posible tras su valoración; las actualizaciones de rutina, con un ritmo fijo, por ejemplo mensual. Más importante que la frecuencia exacta es que la fecha esté fijada y que alguien sea responsable de ella.
¿Protege un plugin actualizado frente a PHP2Shell?
No. PHP2Shell está en el propio intérprete de PHP. Frente a ello solo ayuda una actualización de PHP con reinicio de todos los procesos de PHP. Aun así, los plugins y paquetes actualizados son importantes, porque cierran vulnerabilidades propias.
¿Qué hago con un plugin que ya no se mantiene?
Sustituirlo o eliminarlo. Un plugin abandonado ya no recibe correcciones, aunque hoy aún funcione. Hasta contar con un sustituto, debería comprobar si la función se necesita realmente y documentar la decisión.
¿Tiene que actualizarse también en el servidor el frontend con npm?
A menudo los paquetes de npm solo están en el build y llegan al servidor como archivos ya compilados. Aun así, una vulnerabilidad en un paquete puede estar en el JavaScript entregado. Por eso, tras una actualización hay que volver a compilar y a entregar.