Principales conclusiones
- Tu exposición va más allá del propio Flask: Flask incluye seis dependencias directas, cada una con su propio historial de CVE.
- Las migraciones precipitadas acarrean costes reales: Las actualizaciones apresuradas provocan fallos en las extensiones, obligan a cambiar de versión de Python y superan los plazos previstos.
- El fin de la vida útil no tiene por qué significar que no se apliquen parches: El soporte ampliado garantiza que las versiones de Flask al final de su ciclo de vida sigan recibiendo correcciones de seguridad mientras planificas la actualización.
Si estás utilizando Flask en entorno de producción, probablemente te hayas encontrado con esa situación. Quizá fuera una advertencia de pip-audit que señalaba una versión obsoleta en tu archivo requirements.txt. Quizá fuera un correo electrónico del equipo de seguridad preguntándote por las versiones de tus frameworks. Quizá fuera un compañero que te reenviaba un aviso de CVE con el asunto «¿Nos afecta esto?».
Y entonces surge la pregunta que nadie quiere abordar: «¿Qué versión de Flask estamos utilizando y qué habría que hacer para actualizarla?»
Pallets, la organización responsable de Flask, solo ofrece soporte para la última versión con nuevas funcionalidades. Si no utilizas esa versión, te encuentras en un entorno sin soporte, y los riesgos son mayores de lo que muchos equipos creen. Pero el fin de la vida útil (EOL) de Flask no tiene por qué ser motivo de pánico. Tienes más opciones de las que podrías imaginar. Veamos qué implica ejecutar una versión de Flask sin soporte para tu entorno de producción y, lo que es más importante, qué medidas realistas puedes tomar al respecto sin dar al traste con tu hoja de ruta de ingeniería.
Cómo funcionan realmente las versiones de Flask
Antes de pasar a la parte de «¿qué hacemos al respecto?», conviene entender cómo gestiona Flask el ciclo de vida de sus versiones, ya que se diferencia de la mayoría de los marcos de trabajo en un aspecto que tiene implicaciones directas para tu nivel de seguridad.
Flask no sigue un modelo de soporte a largo plazo con fechas de fin de vida útil (EOL) definidas, como sí lo hacen Angular o Node.js. En su lugar, Pallets (la organización que se encarga del mantenimiento de Flask) publica una política de soporte de versiones que es breve y explícita: la última versión con nuevas funcionalidades recibe correcciones de errores y de seguridad, mientras que las versiones anteriores no las reciben. Dependiendo de la gravedad y del nivel de esfuerzo que suponga, una corrección de seguridad puede retroaplicarse a una versión anterior previa solicitud, pero esto no está garantizado. En la práctica, cuando se lanza una nueva versión con funcionalidades, la línea anterior deja de recibir actualizaciones, incluidos los parches de seguridad.
El historial de lanzamientos es el siguiente: la versión 1.0 salió en abril de 2018, seguida de la 1.1 en julio de 2019. Flask 2.0 se lanzó en mayo de 2021, incorporando compatibilidad con funciones de vista asíncronas y elevando las versiones mínimas en todo el ecosistema de Pallets. Las versiones 2.1, 2.2 y 2.3 se sucedieron a lo largo de 2022 y 2023. Flask 3.0 se lanzó en septiembre de 2023, requiriendo Werkzeug 3.0 y basándose en la limpieza de la API que comenzó con Flask 2.3. Flask 3.1.0 se lanzó en noviembre de 2024, y la última versión a fecha de agosto de 2026 es Flask 3.1.3, publicada en febrero de 2026 —una versión dedicada exclusivamente a correcciones de seguridad—.
Esa política tiene una consecuencia concreta. La línea de versiones actual es la 3.1.x, por lo que es necesario utilizar su última versión de corrección para disfrutar de soporte completo. Cualquier versión de la línea 3.0.x o anterior queda fuera del periodo de soporte, y no cabe esperar que las vulnerabilidades recién reveladas que afecten a esas líneas reciban una corrección por parte del desarrollador original.
Qué significa realmente el fin de vida útil (EOL) de Flask para tu API de producción
Vale, tu versión no es la más reciente. Tu aplicación funciona bien, tus puntos de extremo responden y tu proceso de integración continua está en verde. Entonces, ¿cuál es el problema?
No por el hecho de que una línea de versiones deje de recibir parches se deja de descubrir vulnerabilidades. Además, cada aviso publicado indica exactamente qué versiones se ven afectadas, lo que significa que una implementación sin soporte técnico acumula debilidades documentadas y que permanecerán sin parchear de forma permanente, y que cualquiera puede consultar.
El propio historial de CVE de Flask lo deja claro. El ejemplo más conocido es CVE-2023-30861 (CVSS 7,5, Alto), un problema de divulgación de cookies de sesión que provocó la publicación de boletines de seguridad por parte de los proveedores que incluyen Flask en sus productos empresariales, entre ellos IBM Maximo Application Suite.
El fallo subyacente era de alcance limitado. Flask establece un encabezado de respuesta «Vary: Cookie» cuando se utiliza la sesión, lo que indica a las cachés que no deben servir esa respuesta a otro usuario. En un caso concreto de sesión permanente, Flask actualizó la cookie de sesión sin considerar que se hubiera accedido a la sesión, por lo que faltaba dicho encabezado, mientras que sí estaba presente un encabezado «Set-Cookie». En el caso de un proxy de almacenamiento en caché que no elimina las cookies, una sesión permanente, el parámetro `SESSION_REFRESH_EACH_REQUEST` dejado en su valor por defecto y la ausencia de un encabezado `Cache-Control` explícito, una respuesta que contuviera la cookie de sesión de un usuario podría almacenarse en caché y servirse a otro usuario. Cuando la cookie de sesión controla el acceso a una cuenta autenticada, esto no es un caso extremo teórico.
Pallets lo solucionó en Flask 2.3.2 y 2.2.5 —la línea de versiones vigente en aquel momento y la anterior—, tal y como describe la política de soporte. No se publicó nada para la versión 2.1.x ni para versiones anteriores, por lo que los equipos que utilizaban esas versiones no disponían de ninguna corrección del desarrollador original que pudieran instalar.
Aunque pueda parecer algo del pasado, no lo es. En febrero de 2026, Pallets reveló CVE-2026-27205, un problema del mismo tipo: la sesión no se marcaba como accedida cuando el código solo comprobaba sus claves, utilizando operadores como «in» y «len», por lo que «Vary: Cookie» se omitía de nuevo en condiciones de almacenamiento en caché similares. Afecta a todas las versiones de Flask anteriores a la 3.1.3, es decir, a todas las versiones fuera de soporte que se siguen utilizando hoy en día. Flask 3.1.1 ya había incorporado una corrección independiente para la firma de sesiones (CVE-2025-47278) en mayo de 2025. Tres versiones de seguridad en tres años, y solo la línea actual las ha recibido.
Los marcos de cumplimiento añaden una segunda dimensión. El requisito 6.3.3 de la norma PCI DSS v4.0.1 exige que los parches para vulnerabilidades críticas se instalen en el plazo de un mes desde su publicación. Cuando no existe una versión parcheada para tu versión, ese plazo nunca comienza a contar y el hallazgo permanece abierto. SOC 2 y otras evaluaciones similares basadas en controles no prohíben directamente los componentes sin soporte, pero sí esperan una evaluación de riesgos documentada, controles compensatorios o una vía fiable para recibir las correcciones. Utilizar una versión de Flask sin soporte sin que se cumpla ninguno de estos requisitos constituye una deficiencia sobre la que el evaluador te preguntará.
El riesgo oculto: el árbol de dependencias de Flask
Cuando los equipos piensan en la seguridad de Flask, piensan en el propio marco de trabajo: el enrutamiento, el contexto de la solicitud y la gestión de sesiones. Esa es la capa más evidente.
Pero el marco no funciona de forma aislada. Al instalar la versión actual de Flask, también se instalan seis dependencias directas de tiempo de ejecución: Werkzeug (la capa WSGI y el análisis de solicitudes), Jinja2 (plantillas), MarkupSafe (escapado de cadenas para su inclusión segura en el marcado), ItsDangerous (firmado de cookies de sesión), Click (herramientas de CLI) y Blinker (señales). En Python 3.9 hay una séptima, importlib-metadata. Cada una tiene su propio historial de CVE y cadencia de lanzamiento, y el conjunto exacto varía según la versión de Flask; Blinker, por ejemplo, solo pasó a ser obligatorio en Flask 2.3.
Lo que complica las cosas es lo estrechamente vinculadas que están las versiones entre sí. Flask 3.1.0 requiere Werkzeug 3.1 o posterior, ItsDangerous 2.2 o posterior y Blinker 1.9 o posterior. Flask especifica versiones mínimas en lugar de versiones exactas, por lo que una versión anterior de Flask no bloquea por sí sola todo tu árbol de código. La limitación práctica viene de otra parte: una vulnerabilidad en el análisis de peticiones de Werkzeug o en la lógica de firma de ItsDangerous afecta a tu aplicación tan directamente como un fallo en Flask, y actualizar solo ese paquete puede romper la compatibilidad con tu versión de Flask, tus extensiones o tu propio código.
También puedes obtener más información sobre los problemas de seguridad de Python y los riesgos que pueden afectar a las aplicaciones en todo el ecosistema de Python en general.
Tus opciones cuando Flask llegue al final de su ciclo de vida
Vale, pues estás utilizando una versión de Flask que ya no recibe soporte. ¿Qué opciones realistas tienes ahora?
Hay tres opciones, y cada una presenta ventajas e inconvenientes diferentes. La actualización o la migración reducen el riesgo a largo plazo asociado a los sistemas heredados, pero pueden requerir un trabajo de ingeniería considerable. La ampliación del soporte técnico subsana la brecha de seguridad inmediata y permite ganar tiempo para llevar a cabo ese trabajo de forma adecuada.
Opción 1: Actualizar a la última versión compatible de Flask
Esta es la respuesta oficial: pasar a la línea de versiones actual (Flask 3.1.x en el momento de escribir este artículo), instalar los últimos parches de seguridad y mantenerse al día. Para los equipos con códigos bien mantenidos, es la decisión más acertada a largo plazo.
Flask 3.x aporta mejoras reales. La compatibilidad con las funciones de vista asíncronas, introducida en la versión 2.0, ha seguido desarrollándose, aunque Flask sigue siendo un marco WSGI y no uno diseñado principalmente para la asincronía. La reestructuración de Sans-IO en la versión 3.0 separó la lógica central de Flask de su infraestructura WSGI, lo que permite que proyectos como Quart puedan reutilizarlo. Las versiones de las dependencias están actualizadas y se mantienen al día. Si puedes actualizar sin problemas, deberías hacerlo.
Pero esto es lo que implica «actualizarse a la última versión» cuando se parte de Flask 1.x o de las primeras versiones de 2.x:
Requisitos de versión de Python: Flask 3.0 requiere como mínimo Python 3.8, y Flask 3.1 elevó ese mínimo a Python 3.9, eliminando por completo la versión 3.8. Si tu entorno de producción utiliza una versión anterior de Python —algo habitual en aplicaciones heredadas y en contenedores creados a partir de imágenes base fijas—, la actualización de Python se convierte en un requisito previo antes de poder utilizar Flask.
Extensiones que no funcionan: Este es el problema más importante. El ecosistema de Flask incluye Flask-Login, Flask-SQLAlchemy, Flask-Migrate, Flask-Admin y docenas de extensiones más, cada una con sus propios requisitos de compatibilidad. Cuando Flask 3.0 se lanzó junto con Werkzeug 3.0 el 30 de septiembre de 2023, Werkzeug eliminó los ayudantes url_decode y url_encode, en desuso desde hacía tiempo, que Flask-Login 0.6.2 importaba al cargar el módulo. Las aplicaciones que adoptaron la nueva versión de Werkzeug no pudieron iniciarse y arrojaron un error `ImportError`, y la corrección no llegó hasta la versión 0.6.3 de Flask-Login, el 30 de octubre —un mes de problemas para una de las extensiones más utilizadas de Flask—. Cualquier aplicación que dependa de más de unas pocas extensiones conlleva ese mismo riesgo de coordinación en cada actualización importante.
Se han eliminado las API obsoletas: Flask 2.3.0 ha eliminado un conjunto de API que ya se habían marcado como obsoletas en la versión 2.2, entre ellas app.before_first_request, bp.before_app_first_request, el json_encoder y json_decoder , el variable de entorno FLASK_ENV y el valor de la variable de entorno send_file_max_age_default, use_x_sendfiley propagate_exceptions de la aplicación. Flask 3.0 no ha reintroducido ninguna de ellas. El código de la aplicación o las extensiones que sigan utilizando estas API dejarán de funcionar tan pronto como la ruta de actualización llegue a la versión 2.3. Esto es especialmente importante al pasar directamente de la versión 1.x o de las primeras versiones de la 2.x a la 3.x: se heredan tanto las eliminaciones de la 2.3 como los cambios de la 3.0 en la misma migración.
Cascada de compatibilidad de Werkzeug: Dado que Werkzeug está tan estrechamente vinculado a Flask, actualizar Flask suele implicar actualizar Werkzeug, lo que puede afectar a las extensiones, al middleware personalizado y a cualquier código que interactúe directamente con los componentes internos de Werkzeug.
En el caso de una aplicación Flask pequeña y con un mantenimiento activo, esto podría suponer un sprint específico. Sin embargo, en el caso de una API de gran envergadura, con años de patrones acumulados, extensiones personalizadas y la necesidad de garantizar la disponibilidad del servicio durante la migración, esto implica una planificación minuciosa, pruebas exhaustivas y una posibilidad real de que se produzcan regresiones en el entorno de producción.
Comprender Werkzeug Security antes de actualizar Flask.
Opción 2: Migrar a un marco alternativo
Hay equipos que, ante una actualización de Flask, piensan: «Quizá sea el momento de replantearse todo el asunto».
FastAPI destaca por su documentación automática de API, su compatibilidad nativa con la asincronía y su validación basada en Pydantic. Django REST Framework ofrece un enfoque «listo para usar» para los equipos que prefieren las convenciones a la configuración. Starlette proporciona una base ASGI ligera para pilas de API personalizadas.
Existen argumentos técnicos válidos a favor de cada una de ellas, dependiendo de tus necesidades y de la orientación de tu equipo.
Pero ten claro cuál es el alcance. No estás cambiando una dependencia. Estás reescribiendo los controladores de rutas para adaptarlos a una interfaz API diferente, sustituyendo el modelo de contexto de solicitud de Flask, rediseñando la autenticación y la gestión de sesiones, y buscando equivalentes para las extensiones de Flask de las que dependes —Flask-Login, Flask-SQLAlchemy, Flask-Migrate— o reconstruyendo esa lógica tú mismo.
Los beneficios a largo plazo pueden justificar el esfuerzo en el contexto adecuado. El plazo y el coste suelen superar las estimaciones iniciales una vez que se ha definido el alcance completo del proyecto, y el mantenimiento de la aplicación Flask existente mientras se desarrolla su sustituta supone una carga adicional.
Opción 3: Asistencia técnica ampliada de terceros
La opción que los equipos suelen pasar por alto con mayor frecuencia es el soporte de seguridad ampliado que ofrece un proveedor especializado.
TuxCare ofrece soporte de ciclo de vida ilimitado (ELS) para las versiones de Flask que han llegado al final de su vida útil. En lugar de verte obligado a realizar una migración antes de estar preparado, o de dejar tus API expuestas mientras la planificas, puedes seguir utilizando una versión de Flask cubierta por el servicio, con parches de seguridad activos.
La idea es muy sencilla: ganas tiempo y control. Tiempo para planificar una actualización adecuada cuando sea lo más conveniente para tu equipo y tu aplicación. Control sobre tu calendario de migración, en lugar de que sea la divulgación de una vulnerabilidad la que lo fije por ti en el peor momento posible.
El coste real de precipitarse a la hora de actualizar un matraz al final de su vida útil
Piensa en lo que ocurre cuando un equipo se ve obligado a acelerar una migración de Flask en un plazo poco realista porque una auditoría de seguridad ha detectado dependencias no compatibles.
Aumento de la carga de asistencia técnica: Los problemas de compatibilidad que no se detectaron en las pruebas intensivas empiezan a aparecer en producción. Una extensión que funcionaba en el entorno de pruebas se comporta de forma diferente bajo carga. La cola de asistencia técnica se llena de incidencias que se remontan a la migración, y diagnosticarlas requiere conocer a fondo qué ha cambiado en cada dependencia.
Inestabilidad del sistema: Un cambio de versión de Werkzeug modifica la forma en que se analizan los datos de los formularios de varias partes, y un punto final de carga comienza a rechazar archivos que antes aceptaba. Un cambio en la gestión de sesiones provoca fallos de autenticación intermitentes que solo se producen bajo patrones de carga específicos. Estos son los problemas que provocan alertas a las 3 de la madrugada y el incumplimiento de los SLA.
Acumulación de deuda técnica: En su prisa por cumplir con los requisitos, los equipos toman atajos. El uso de API obsoletas se enmascara con soluciones de compatibilidad en lugar de refactorizarse adecuadamente. La frase «Lo arreglaremos después de la migración» se convierte en algo permanente, y seis meses después te encuentras con un código técnicamente actualizado pero repleto de soluciones provisionales y tareas de limpieza aplazadas.
Sobrecostes: La estimación inicial era de dos semanas. Han pasado cinco semanas y sigues detectando problemas de compatibilidad con las extensiones, el contratista sigue facturando, se han pospuesto algunas funciones y los ingenieros, que deberían estar desarrollando nuevas capacidades, se dedican a depurar conflictos entre versiones.
La diferencia entre una actualización de Flask bien planificada y otra realizada por pánico no es insignificante. Es la diferencia entre un proyecto controlado con un alcance definido y una emergencia interminable que agota la capacidad de tu equipo durante meses.
Mantener la seguridad de Flask al final de su ciclo de vida con TuxCare
Aquí es donde el «Soporte de ciclo de vida ilimitado» de TuxCare cambia las reglas del juego.
TuxCare lleva 15 años proporcionando parches de seguridad para sistemas operativos, entornos de ejecución, bibliotecas y marcos de aplicaciones que han llegado al final de su ciclo de vida. La empresa ha distribuido más de 220 000 parches y ha resuelto más de 5 000 CVE en unos 10 000 paquetes para más de 2 300 clientes empresariales: una trayectoria consolidada en entornos de producción, más que una serie de promesas al respecto.
¿Qué diferencia al enfoque de TuxCare?
Cobertura a lo largo de la cadena de dependencias: El riesgo de fin de vida útil rara vez se limita únicamente al paquete de nivel superior. En el caso de una aplicación Flask, se extiende a Werkzeug, Jinja2, MarkupSafe, ItsDangerous y todo lo que se encuentre por debajo de ellos. Cuando una dependencia cubierta necesita una corrección de seguridad, TuxCare aplica los parches, recompila y valida los paquetes afectados de forma conjunta, en lugar de dejar que seas tú quien actualice un componente y descubra qué es lo que deja de funcionar. La cobertura de dependencias directas y transitivas está incluida sin coste adicional.
Retroportación automatizada con validación por parte de expertos: TuxCare realiza un seguimiento del NVD, los avisos de los proveedores y las fuentes de seguridad de GitHub; a continuación, realiza el backporting de las correcciones mediante automatización algorítmica y asistida por IA, y los ingenieros de seguridad validan el resultado. Los paquetes se someten a pruebas de integridad, funcionalidad y regresión, y se firman antes de llegar a los repositorios de los clientes. Para ver cómo funciona el proceso de principio a fin, lee el informe técnico de TuxCare sobre su proceso de aplicación de parches de código abierto.
Distribución a través de tu flujo de trabajo de pip actual: Los paquetes parcheados se distribuyen desde un repositorio alojado en TuxCare que tú configuras como índice de pip o índice adicional. No tienes que reformar tu proceso de compilación, volver a formar a tu equipo ni cambiar tu proceso de implementación; solo tienes que indicar una fuente que sigue generando correcciones incluso después de que Pallets haya dejado de estar disponible.
Tiempos de respuesta garantizados por el SLA: Los objetivos publicados por TuxCare para el servicio «Endless Lifecycle Support for Libraries» son la publicación de parches en un plazo de 14 días desde la divulgación pública para vulnerabilidades de riesgo alto y crítico (CVSS 7.0 y superior), de 60 días para las de riesgo medio y de 90 días para las de riesgo bajo. Trabajas con plazos documentados en torno a los cuales puedes planificar un periodo de corrección, con asistencia las 24 horas del día, los 7 días de la semana.
Coste predecible: El soporte ampliado tiene un precio fijo durante la vigencia del contrato, lo que facilita su comparación con una migración. Si comparas esa cifra con las horas de ingeniería, los ciclos de pruebas, los honorarios de los contratistas, el posible tiempo de inactividad y las funciones retrasadas que requeriría una actualización acelerada, estarás comparando dos cifras reales en lugar de una cifra y una esperanza.
Documentación preparada para auditorías: Cada lanzamiento incluye información sobre qué CVE se han solucionado y qué versiones de paquetes se han modificado, además de SBOM legibles por máquina (SPDX y CycloneDX) y documentos VEX. Esa es la evidencia que se solicita en las revisiones de gestión de vulnerabilidades y control de cambios, aunque los requisitos específicos siempre dependen del marco de trabajo, los límites de su sistema y su evaluador.
Cómo empezar
Si estás utilizando una versión de Flask que ha llegado al final de su ciclo de vida y quieres conocer tu nivel de exposición, TuxCare mantiene un registro de CVE en el que se muestran las vulnerabilidades asociadas a las versiones de Flask cubiertas y las correcciones publicadas para ellas. La cobertura publicada incluye actualmente las versiones 0.12.5, 1.1.2, 1.1.4 y 2.2.1 de Flask, y hay versiones adicionales disponibles previa solicitud.
Comprueba las vulnerabilidades y las correcciones disponibles de ELS para Flask.
No dejes que el fin de la vida útil de Flask ponga en riesgo tus API
Ofrecer soporte únicamente para la última versión con nuevas funcionalidades es una política pragmática para un equipo pequeño de código abierto. Sin embargo, resulta menos conveniente para las organizaciones que ejecutan aplicaciones en producción y que no pueden actualizar cada vez que se lanza una nueva versión.
Lo importante es que el fin de la vida útil (EOL) de Flask no tiene por qué suponer un problema. Tienes opciones. Puedes planificar una actualización bien meditada cuando a tu equipo le convenga, evaluar otro marco de trabajo si existe una razón arquitectónica real para cambiar, o recurrir al soporte ampliado para seguir recibiendo parches de seguridad y cumplir con tus obligaciones de cumplimiento normativo mientras tomas esas decisiones según tu propio calendario, en lugar de según el de un auditor.
Los equipos que gestionan bien el fin de vida útil (EOL) de Flask son aquellos que detectan el riesgo a tiempo, comprenden las opciones de las que disponen y toman decisiones meditadas en lugar de reaccionar de forma impulsiva.
Si te preocupa el fin de la vida útil de Flask, merece la pena averiguar qué cubre el servicio de soporte de ciclo de vida ilimitado de TuxCare de TuxCare. Quizá lo mejor sea asegurar la versión que ya utilizas mientras planificas la actualización que realmente deseas.

