Principales conclusiones
- La falta de soporte para Werkzeug implica que las correcciones de la versión principal se detienen, dejando a las aplicaciones afectadas sin un parche cuando surgen nuevas vulnerabilidades.
- Las actualizaciones apresuradas pueden generar errores de producción, problemas de dependencia, deuda técnica y costes imprevistos.
- TuxCare ELS mantiene actualizadas las versiones antiguas de Werkzeug mientras usted planifica el momento adecuado para actualizar.
Has construido algo sólido sobre Werkzeug. El enrutamiento funciona. El manejo de solicitudes es impecable. La capa WSGI hace exactamente lo que se supone que debe hacer. Entonces, se activa el escáner de dependencias o alguien del equipo de seguridad pregunta qué versión de Werkzeug se está ejecutando en el contenedor, y la respuesta resulta ser la 2.2.3, una versión que data de 2023.
¿Y ahora qué?
Este problema es más común de lo que parece, principalmente porque casi nadie elige su versión de Werkzeug a propósito. Flask la importa, pip la resuelve y permanece ahí sin cambios hasta que algo obliga a preguntar. Así que veamos qué sucede realmente cuando una rama de Werkzeug deja de recibir actualizaciones y qué se puede hacer al respecto.
Cómo funcionan realmente los sistemas de liberación de Werkzeug
Werkzeug es mantenido por el proyecto Pallets junto con Flask, Jinja y Click. Pallets no publica un calendario de soporte a largo plazo con ventanas de mantenimiento fijas para cada rama, como sí lo hacen Python o Node.js. No hay una fecha de fin de vida útil anunciada para Werkzeug 2.2 en ninguna hoja de ruta. El soporte debe inferirse de las versiones que los mantenedores realmente distribuyen.
La estructura general es bastante fácil de seguir. Werkzeug 2.x dejó de ser compatible con Python 2 y 3.5 y orientó el código hacia las anotaciones de tipo. Werkzeug 3.x continuó evolucionando, eliminando las API obsoletas y elevando el nivel mínimo de compatibilidad con Python, y ahora requiere Python 3.9 o superior. La versión activa actualmente es la 3.1.x, siendo la 3.1.8, publicada el 2 de abril de 2026, la última versión estable a fecha de agosto de 2026.
Aquí es donde surge la confusión. El modelo intuitivo, que supone que una nueva versión principal elimina inmediatamente la rama anterior, no es fiable. Werkzeug 3.0.0 se lanzó a finales de septiembre de 2023, y la versión 2.3.8 llegó el 8 de noviembre de 2023 con una corrección de seguridad. Las retrocompatibilidades existen, pero son impredecibles y no están garantizadas.
Lo que sí muestra el historial de lanzamientos es dónde se centra la atención. La línea 3.0 tuvo su último lanzamiento, el 3.0.6, a finales de octubre de 2024, días antes del lanzamiento del 3.1.0, y desde entonces no ha habido más. La línea 2.x finalizó con el 2.3.8. Así pues, en la práctica, el 3.1.x es la única rama que sigue recibiendo lanzamientos, mientras que las ramas anteriores parecen inactivas sin haber sido declaradas oficialmente obsoletas. Esto es, sin duda, peor que una fecha de fin de vida útil publicada, porque no se puede proporcionar a un auditor un calendario ni planificar en función de una ventana de mantenimiento que nunca se ofreció.
Si no estás seguro de cuál es tu situación, pip show werkzeug Responde en aproximadamente dos segundos. Si la versión no comienza con 3.1, no cuente con que el desarrollador principal publique una solución para lo que se anuncie a continuación.
Qué significa realmente un Werkzeug sin soporte en la producción.
El soporte finaliza. La aplicación sigue funcionando. No hay ningún fallo visible. Entonces, ¿por qué importa?
Que se detengan las actualizaciones no significa que desaparezcan las vulnerabilidades. El riesgo no reside en que los atacantes mantengan una lista de ramas de Werkzeug que no cumplen con los estándares. Es más sencillo y aburrido que eso: se descubre una vulnerabilidad, afecta a tu rama y no existe una solución en la rama principal. Werkzeug se ejecuta sobre Flask, por lo que esa brecha se hereda en cualquier proyecto que hayas desarrollado sobre él.
Dos ejemplos ilustran bien el problema.
CVE-2024-34069 es una vulnerabilidad en el depurador interactivo de Werkzeug, calificada con un nivel de riesgo alto (7.5) por NVD y el servicio de asesoramiento Pallets. Su explotación es limitada. El atacante debe lograr que un desarrollador interactúe con un dominio y subdominio que controle, que introduzca el PIN del depurador y que adivine una URL de la aplicación que lo active. Si se cumplen las tres condiciones, se ejecuta código en la máquina del desarrollador, incluso con el depurador configurado para usar localhost. Esta vulnerabilidad se corrigió en la versión 3.0.3.
Esa corrección es fundamental. Werkzeug 3.0.3 es la primera versión que la incluye, y todas las versiones posteriores de la serie 3.x la incorporan. Lo que no existe es una versión de la serie 2.x con el parche, incluida la 2.3.8, la última versión de dicha serie. Si tu sistema está en la línea 2.x, no hay ninguna versión en esa rama a la que puedas actualizar para solucionar este problema.
Más información sobre Werkzeug Security y las vulnerabilidades actuales.
CVE-2023-46136 es una denegación de servicio en el analizador de formularios multipart. Si una carga comienza con un CR o LF y luego va seguida de megabytes sin esos caracteres, el analizador agrega bytes en bloques a un array de bytes interno y vuelve a escanear el búfer creciente para encontrar el límite, consumiendo CPU y bloqueando el proceso de trabajo para procesar cualquier otra cosa. Afecta a las versiones 2.3.7 y anteriores, así como a la 3.0.0, y se corrigió en las versiones 2.3.8 y 3.0.1. Es importante saberlo antes de discutir sobre esto en un ticket: NVD le da una calificación de 7.5 (Alta), mientras que el aviso de Pallets le da una calificación de 5.7 (Moderada), porque ambos discrepan sobre el vector de ataque y los privilegios requeridos. Diferentes escáneres pueden reportar diferentes niveles de gravedad según la fuente de donde obtengan la información. La exposición afecta a las aplicaciones con un punto final que realmente analiza datos multipart proporcionados por el atacante.
En una rama con soporte, ambas acciones implican un aumento de versión. En una rama sin soporte, una vulnerabilidad recién descubierta permanece sin parchear en la rama principal hasta que actualices o busques una adaptación en otra parte.
Riesgos de seguridad y cumplimiento normativo tras la finalización del soporte
La versión 4.0.1 de la norma PCI DSS exige, en el requisito 6.3.3, que los parches para vulnerabilidades críticas se instalen en el plazo de un mes desde su publicación, mientras que los demás parches aplicables se gestionan según el cronograma documentado de la organización, basado en el riesgo. La versión 4.0 había extendido ese plazo de un mes también a los elementos de alta gravedad, y la versión 4.0.1 volvió a la redacción más restrictiva. La dirección de esa revisión es menos importante que la premisa subyacente: que existe un parche para instalar.
Cuando no existe una solución en la rama principal para tu problema, no es que estés retrasado en la corrección. Simplemente estás fuera del modelo en el que se basó el requisito, y eso dificulta la conversación con el evaluador.
SOC 2 no incluye ninguna norma contra el software obsoleto, así que tenga cuidado al plantear este tema internamente. Lo que sí hace es suscitar preguntas sobre la gestión de vulnerabilidades y sobre si puede demostrar una solución eficaz. Una dependencia sin soporte, con vulnerabilidades detectadas y sin parche disponible, genera solicitudes de seguimiento, ralentiza los cuestionarios de seguridad y complica las revisiones de riesgos con los clientes al renovar la certificación.
Sus opciones cuando se agota el soporte
Hay tres, y la correcta depende menos del CVE que te marcó que de la superficie de Werkzeug que realmente tenga tu aplicación.
Actualiza a la última versión de Werkzeug
La respuesta habitual, y para muchos equipos la correcta. Werkzeug 3.1.x es una versión madura, la API es más limpia y las anotaciones de tipo son realmente útiles.
Lo interesante radica en la suposición de que se trata de un cambio de una sola línea. Werkzeug no se mueve por sí solo. Las versiones de Flask generalmente declaran una versión mínima de Werkzeug en lugar de fijar un límite superior, lo que permite a pip resolver una versión de Werkzeug más reciente que aquella con la que se probó tu versión de Flask. Esto no es hipotético. Werkzeug 3.0 fue eliminado url_quote, que Flask 2.2.2 importa en la parte superior de app.py, por lo que el emparejamiento falla en la importación. Luego se eliminó Werkzeug 3.1 werkzeug.__version__, que el cliente de prueba Flask 2.2.4 todavía lee cuando construye una cadena de agente de usuario, produciendo un AttributeError la primera vez que alguien ejecuta el conjunto en un contenedor nuevo. Eso está escrito en Flask número 5652.
Actualizar Werkzeug bien podría implicar actualizar Flask, lo que significa auditar cada extensión vinculada a Flask, lo que a su vez implica una revisión de compatibilidad en todo el árbol de dependencias. Si tu código fuente es pequeño, tu lista de extensiones es corta y tu cobertura de pruebas es correcta, hazlo ahora y deja de leer. Si se trata de una aplicación madura con una década de middleware acumulado, planifica bien tu presupuesto.
Migrar a otro marco de trabajo
Algunos equipos analizan una dependencia no compatible y deciden que la solución real se encuentra en otro lugar completamente distinto. Django si buscas funcionalidades completas, FastAPI si prefieres un framework de API asíncrona basado en Starlette, Starlette si quieres el conjunto de herramientas ASGI sin restricciones, Bottle o Falcon si buscas algo más ligero. FastAPI, en particular, goza de gran popularidad, un diseño que prioriza la programación asíncrona y documentación OpenAPI gratuita.
Ninguna de estas soluciones reemplaza directamente a Werkzeug. La lógica de enrutamiento, el análisis de solicitudes, la representación de plantillas, la pila de middleware, el manejo de errores y la configuración de despliegue deben ser rediseñados. Para una aplicación con una superficie de Werkzeug significativa, una migración bien planificada y probada se convierte en un proyecto de varios sprints o trimestres, no en una simple tarea de limpieza. Hágalo porque ya deseaba trabajar de forma asíncrona, no porque un escáner lo detectara un martes.
Utilice el soporte extendido y gane tiempo.
La tercera opción es mantener la versión actual y seguir recibiendo las actualizaciones de seguridad. Esto elimina la dependencia de quien publique la próxima divulgación de información sobre el plazo de actualización y permite retomar el tema en tu plan de desarrollo. Más adelante encontrarás una explicación detallada de cómo funciona esto.
El verdadero coste de precipitarse a la hora de actualizar
Imagínese un equipo de SaaS de treinta personas al que se le pide que resuelva un hallazgo de alta gravedad antes de que finalice el plazo para la certificación SOC 2 en tres semanas. La actualización en sí no es lo difícil. Lo complicado son las consecuencias.
Los errores que las pruebas no detectaron empiezan a manifestarse en producción, y el equipo de soporte recibe una avalancha de incidencias sobre comportamientos que antes funcionaban correctamente. Las dependencias transitivas generan sus propios casos límite, de esos que solo aparecen bajo carga real, lo que produce fallos intermitentes que son muy difíciles de reproducir y aún más difíciles de explicar durante una revisión de incidentes.
Entonces empiezan los atajos. Se omiten las refactorizaciones, se acumulan las soluciones provisionales y todos acuerdan arreglarlo bien más tarde. Seis meses después, ese "más tarde" no ha llegado y el código está en peor estado que antes de la actualización que supuestamente iba a mejorarlo.
Los costos siguen el mismo patrón. Horas de contratistas no presupuestadas, compromisos de la hoja de ruta que se retrasan un trimestre y ingenieros sénior que pasan la semana leyendo la salida del solucionador de pip en lugar de desarrollar lo que los clientes pidieron. Nada de esto aparece en el presupuesto original, porque este se refería a la actualización de versión.
Cómo funciona TuxCare ELS para Werkzeug
TuxCare lleva 15 años aplicando parches a software de código abierto que ha llegado al final de su ciclo de vida, con más de 420 000 parches entregados y más de 14 000 vulnerabilidades corregidas en sistemas operativos, entornos de ejecución, bibliotecas y aplicaciones. Werkzeug está cubierto por el servicio ELS para bibliotecas de TuxCare.
Actualmente, las versiones compatibles incluyen Werkzeug 1.0.1, 2.2.3 y 2.3.8, y hay otras versiones disponibles bajo petición.
¿Qué hace que este enfoque sea diferente?
La superficie de dependencias de Werkzeug es inusualmente pequeña. Las versiones 2.x declaran exactamente una dependencia de tiempo de ejecución requerida, MarkupSafe, y la versión 1.0.1 no declara ninguna, lo que simplifica la cuestión de la cobertura. ELS incluye correcciones de seguridad para dependencias directas y transitivas sin costo adicional, lo cual es más importante de lo que parece, ya que el riesgo de fin de vida útil puede estar en un nivel inferior al del paquete que se está monitorizando.
El proceso de aplicación de parches se ejecuta de forma automatizada, con personal que verifica los resultados. TuxCare realiza un seguimiento continuo de las vulnerabilidades CVE en NVD, los avisos de los proveedores y los avisos de seguridad de GitHub. Aplica correcciones a versiones anteriores mediante automatización algorítmica y asistida por IA, con validación experta, y somete cada compilación a pruebas de integridad, funcionalidad y regresión antes de firmarla y publicarla en los repositorios ELS. Si prefiere conocer los detalles técnicos en lugar del resumen, la documentación sobre el proceso de aplicación de parches de código abierto lo explica con claridad.
La integración permanece dentro de pip. O bien apuntas pip al repositorio de TuxCare con index-url, o bien mantienes PyPI público y lo agregas como un extra-index-url, fijando directamente la compilación parcheada. Las versiones parcheadas llevan una cadena de versión como werkzeug==1.0.1.post1+tuxcareDe esta forma, la compilación parcheada permanece identificable dondequiera que se registren las versiones resueltas. Se trata de un cambio en la configuración del repositorio con credenciales, no de una reconstrucción de la canalización de despliegue.
La entrega se realiza bajo un acuerdo de nivel de servicio (SLA) en lugar de con un enfoque de mejor esfuerzo, y los paquetes se firman y distribuyen desde repositorios alojados por TuxCare, con asistencia las 24 horas del día, los 7 días de la semana, para la clasificación y las solicitudes de parches cuando se requiere la intervención humana. Para las auditorías, cada versión parcheada incluye datos SBOM y un feed VEX, de modo que las herramientas compatibles con VEX pueden distinguir los hallazgos corregidos de aquellos que aún requieren atención.
En cuanto al costo, la verdad es que el soporte extendido no es barato. Lo que sucede es que traslada la ingeniería de migración, las pruebas de compatibilidad y el trabajo de regresión de una situación de emergencia a una planificada, donde el costo es el que corresponde.
Cómo empezar
Si desea saber qué cobertura tiene realmente su versión, el rastreador de CVE de TuxCare enumera las vulnerabilidades de Werkzeug que se han parcheado, y la documentación de ELS cubre las versiones compatibles y las opciones de instalación en detalle.
Para obtener información sobre las versiones compatibles, los precios y cómo funciona la implementación en la práctica, la página de Soporte de ciclo de vida completo para Werkzeug es el lugar ideal para comenzar.
No permita que una herramienta no compatible ponga en riesgo sus sistemas.
La posición de Werkzeug como capa WSGI bajo Flask implica que las decisiones sobre su ciclo de vida rara vez se controlan. Cuando una versión sin soporte contiene un fallo en el código que tu aplicación utiliza, esta también lo sufre, y te enteras a través de un escáner o un cuestionario, en lugar de consultar las notas de la versión.
Nada de esto justifica el pánico. Puedes planificar una actualización de Werkzeug para un trimestre en el que tengas margen para hacerlo bien. Puedes cambiar a otro framework si existe una razón técnica real que vaya más allá del escáner. O puedes seguir recibiendo parches para la versión que ya utilizas mientras decides, lo que te ayuda a mantener tu nivel de seguridad y te proporciona pruebas reales de remediación para las revisiones de cumplimiento, sin tener que entregar tu plan de desarrollo a quien presente la próxima vulnerabilidad CVE.
Los equipos que superan esta situación con éxito rara vez son los que cuentan con los mayores presupuestos. Son aquellos que supieron identificar la versión en la que se encontraban, comprendieron qué se mantenía y qué no, y eligieron con criterio en lugar de reaccionar impulsivamente.
Si actualmente tienes alguna de estas tareas pendientes, el soporte de ciclo de vida infinito para software de código abierto muestra cómo el soporte extendido cubre los componentes que llegan al final de su ciclo de vida en el resto de tu infraestructura durante el tiempo que los necesites.
