¿Moment.js ha quedado obsoleto? Estado de obsolescencia, CVE y opciones de soporte

Ya están disponibles los parches de php2shell (CVE-2026-109618 y CVE-2026-109619) para PHP en fin de vida útil. Dado que las respuestas del departamento de ventas están tardando más de lo habitual debido a la elevada demanda, la forma más rápida de obtener los paquetes parcheados es comprar ELS para Runtimes en línea (se abre en una pestaña nueva). Lee las preguntas frecuentes sobre los parches

Ir directamente al resumen generado por IA de esta entrada del blog

  • Resume esta entrada con Perplexity
  • Resume esta publicación con Gemini

Principales conclusiones

  • Moment y Moment Timezone son proyectos antiguos que se encuentran en modo de mantenimiento, por lo que en los nuevos proyectos se deben utilizar alternativas.
  • El hecho de que un programa sea obsoleto no implica que deba desinstalarse rápidamente, ni que todas las instalaciones sean vulnerables.
  • Las migraciones que abandonan Moment se deben, con mucha más frecuencia, a la mutabilidad y al análisis sintáctico poco riguroso que a la sintaxis.
  • Elige un sustituto en función de la zona horaria y el comportamiento de análisis que necesites, no basándote en comparativas del tamaño de los paquetes.

Moment es una de las pocas bibliotecas que ha pedido públicamente a sus usuarios que dejen de utilizarla. El proyecto se declaró «obsoleto» y pasó a «modo de mantenimiento» ya en 2020; su página de npm sigue indicándola como un proyecto obsoleto que no incorpora nuevas funcionalidades, y el archivo README de Moment Timezone va un paso más allá y recomienda a la mayoría de los usuarios que elijan otra biblioteca. Eso no supone, sobre el papel, el fin de su vida útil. Sin embargo, para un equipo que sigue utilizando la versión 2.24.0, el problema práctico se parece mucho a eso, ya que las correcciones del desarrollador original se incorporan a la versión actual de Moment y nadie las adapta a una versión tan antigua.

La complicación radica en que sustituir Moment no es un mero ejercicio de sintaxis. Sus objetos son mutables y su análisis sintáctico es más tolerante en aspectos en los que las alternativas modernas no lo son deliberadamente, por lo que una migración mal realizada se manifiesta en forma de fechas erróneas en lugar de errores de compilación.

Moment resolvió el problema antes de que la plataforma estuviera lista

Moment.js apareció cuando el manejo de fechas en JavaScript resultaba realmente complicado. El análisis y el formateo se comportaban de forma diferente de un motor a otro, los cálculos de husos horarios eran una lotería y formatear una fecha sin una biblioteca auxiliar significaba tener que manipular cadenas de forma manual, algo de lo que nadie quería hacerse cargo. Moment solucionó eso, y lo hizo tan bien que se convirtió en la opción por defecto durante la mayor parte de una década. Considerar su antigüedad como un fracaso es interpretar la historia al revés. Resolvió un problema real antes de que la plataforma estuviera a la altura.

Eso es lo que hace que la experiencia actual resulte tan extraña. Abres la página del paquete para comprobar una versión y el archivo README se abre con una advertencia de que se trata de un proyecto obsoleto en modo de mantenimiento. A continuación, buscas en tus propios repositorios con «grep» y descubres que Moment aparece en tres de ellos.

Es fácil interpretar el «modo de mantenimiento» como un suave empujón hacia algo más nuevo. Pero eso no viene al caso. Se trata de una declaración sobre lo que se va a arreglar y lo que no, y una vez que lo interpretas así, la versión fijada en tu package.json empieza a tener un aspecto diferente.

¿Moment.js ha quedado obsoleto? ¿Qué significa el «modo de mantenimiento»?

No en sentido estricto. No hay ningún anuncio oficial sobre el fin de su vida útil ni ninguna «commit» de cierre. Lo que ha hecho el proyecto es autodenominarse «proyecto heredado en modo de mantenimiento» y desaconsejar su adopción por parte de nuevos usuarios, lo cual es una respuesta más precisa y útil que un simple «sí» o «no».

Los responsables del mantenimiento han sido claros respecto al alcance y lo redefinieron en agosto de 2026 por primera vez desde 2020. Moment seguirá abordando los problemas críticos de seguridad, y las actualizaciones de los datos de zonas horarias de Moment seguirán basándose en las publicaciones de la IANA. Seguirá sin incorporar nuevas funcionalidades dirigidas al usuario y no se va a rediseñar la API mutable. Lo que ha cambiado es el alcance. La política de 2020 descartaba cualquier trabajo relacionado con el tamaño de los paquetes y el «tree shaking», así como cualquier versión 3. La actualización de 2026 amplía ese ámbito, permitiendo a los mantenedores ocuparse del empaquetado, las declaraciones de TypeScript, las herramientas de compilación y la composición de los paquetes.

Y no se trataba solo de palabras. La versión 2.31.0 se lanzó el 14 de septiembre de 2026 con una corrección de seguridad, una larga lista de correcciones de errores y actualizaciones de configuración regional: la primera versión desde la 2.30.1, a finales de 2023.

El proyecto también se ha retractado de su promesa de 2020 de no lanzar nunca una versión 3. No hay un calendario para la 3.0, y cualquier versión 3.0 seguiría siendo una versión de mantenimiento en lugar de un retorno al desarrollo de nuevas funcionalidades, pero la puerta que se soldó en 2020 ahora solo está cerrada. Ese es el límite actual, y es un poco más amplio que hace seis años.

Moment forma parte de la Fundación OpenJS como proyecto «At-Large», por lo que cuenta con un marco de gobernanza neutral y una política de seguridad publicada. Ninguno de estos elementos financia la retrocompatibilidad con ramas de versiones anteriores. Las correcciones de seguridad que se implementan se aplican al código actual.

Una visión realista: para un equipo que sigue utilizando la versión 2.24.0, el modo de mantenimiento plantea un problema de soporte relacionado con el fin de vida útil (EOL). Las medidas de seguridad de la versión original se centran en la versión actual de Moment, por lo que el plazo de soporte práctico para tu versión finalizó hace años, aunque el proyecto en sí siga muy vivo.

El historial de CVE es breve y se centra en los casos en los que realmente se utiliza.

El número de vulnerabilidades de Moment es reducido, lo cual es una buena noticia. El problema es que todas las entradas se encuentran en el código que gestiona la entrada de datos (análisis de fechas, análisis de duraciones y carga de configuraciones regionales), y esas son precisamente las rutas a las que las aplicaciones suelen enviar los datos de los usuarios.

CVE Tipo Versiones afectadas Corregido en CVSS
31129 ReDoS en el análisis sintáctico de RFC 2822 2.18.0 a 2.29.3 2.29.4 7,5 Alto
24785 Recorrido de la ruta mediante la configuración regional 1.0.1 a 2.29.1 2.29.2 7,5 Alto
18214 ReDoS en el análisis sintáctico antiguo anterior a la versión 2.19.3 2.19.3 7,5 Alto
4055 ReDoS en el análisis de la duración antes de la versión 2.11.2 2.11.2 6,5 Medio

CVE-2022-31129 presenta un comportamiento cuadrático (N²) en preprocessRFC2822 cuando elimina los comentarios heredados de una cadena de fecha. Si se le proporciona una entrada lo suficientemente larga, el análisis se bloquea, lo que constituye una primitiva clara de denegación de servicio. CVE-2022-24785 es un recorrido de ruta a través de una cadena de configuración regional proporcionada por el usuario y utilizada para cambiar la configuración regional de Moment, corregido en la versión 2.29.2. CVE-2017-18214 es un ReDoS anterior en las expresiones regulares de análisis de versiones más antiguas, y CVE-2016-4055 es un ReDoS relacionado en duration(), corregido en la versión 2.11.2.

La cuestión que determina la gravedad en tu aplicación es concreta. ¿Puede una entrada controlada por un atacante llegar al constructor de Moment? moment.duration(), o el conmutador de configuración regional, ¿y qué lo comprueba al entrar? Si nada que no sea de confianza llega a esas rutas, tu exposición real es menor de lo que sugiere la puntuación bruta.

Cuidado: Limita la longitud de cualquier cadena de fecha o duración antes de que llegue a Moment. El propio aviso de los responsables del mantenimiento sobre CVE-2022-31129 sugiere 200 caracteres, lo que neutraliza el fallo de RFC2822 y reduce drásticamente la exposición a los otros dos. El mismo aviso indica que un filtro como ese también ayuda con la mayoría de los futuros fallos de ReDoS. Sin embargo, no sirve de nada para el fallo de configuración regional. Para esos, solo manualmente moment.locale() una cadena procedente de una lista de configuraciones regionales permitidas que realmente distribuyes.

Soporte técnico de ciclo de vida ilimitado de TuxCare para Moment.js Afecta a las versiones 2.0.0, 2.10.6 y 2.24.0, y las tres se sitúan por debajo de las correcciones de la serie 2.29.x. La vulnerabilidad de recorrido de ruta (CVE-2022-24785) afecta a todas ellas. Los CVE de ReDoS se dividen según las versiones. El ReDoS de RFC2822 (CVE-2022-31129) solo se aplica a partir de la versión 2.18.0, por lo que afecta a la 2.24.0, pero no a las dos versiones anteriores. El ReDoS de análisis anticuado (CVE-2017-18214) se corrigió antes de que se lanzara la versión 2.24.0, por lo que son las versiones 2.0.0 y 2.10.6 las que lo contienen. El ReDoS de duración (CVE-2016-4055) se limita aún más y solo afecta a la versión 2.10.6. La versión 2.0.0 se encuentra dentro del rango publicado, pero su duration() No analiza cadenas en absoluto, por lo que la expresión regular vulnerable simplemente no existe.

TuxCare ya ha publicado parches para todas y cada una de estas CVE que afectan a las versiones para las que ofrece soporte. Visita el CVE Tracker para consultar todas las vulnerabilidades y las correcciones disponibles para el software de código abierto para el que TuxCare ofrece soporte, así como sus cadenas de dependencias.

Elegir una alternativa a Moment.js es lo más fácil

Si has decidido marcharte, la lista de opciones es breve y elegir una es lo más rápido. La primera opción es una biblioteca que nunca se modifica in situ. Luxon y Day.js devuelven nuevos objetos inmutables, mientras que date-fns funciona con datos simples Date toma los valores y devuelve otros nuevos. La segunda se basa en la función integrada Intl API para el formateo y la gestión de la configuración regional. La tercera es la API nativa Temporal, que alcanzó la fase 4 del TC39 en marzo de 2026 y ya está disponible en Chrome, Edge y Firefox. Safari solo la tiene en «Technology Preview» por el momento, pero una vez que se implemente en todas partes, el uso de una biblioteca de terceros pasará a ser opcional para muchos casos de uso.

La pregunta más complicada es de qué comportamientos de Moment depende tu aplicación en este momento, ya que eso determina qué dejará de funcionar cuando realices el cambio. Una biblioteca que, objetivamente, esté mejor diseñada puede seguir generando resultados diferentes para las mismas entradas que tu código lleva años proporcionando a Moment.

Considera Moment Timezone como una decisión independiente. Cuenta con su propio paquete de datos de zonas horarias y su propia interfaz API, y el código sensible a las zonas horarias que se desarrolla sobre él es la parte más complicada del trabajo. El código que solo da formato a las fechas se adapta fácilmente. El código que realiza cálculos relacionados con las zonas horarias al cruzar los límites del horario de verano, en cambio, no.

La semántica de las fechas que provoca errores en las migraciones

Aquí es donde las migraciones de Moment fallan realmente. La estructura de la API es fácil de traducir, pero la semántica subyacente no lo es.

Empecemos por la mutabilidad. Los objetos de Moment se modifican in situ, por lo que .add() y .startOf() cambia la instancia sobre la que las has llamado. El código que pasa una instancia compartida de Moment y espera que cada llamada la modifique depende de ese comportamiento, a menudo sin que nadie se dé cuenta. Luxon, Day.js y Temporal devuelven, en cambio, nuevos objetos, y las funciones de date-fns devuelven nuevos Date valores. Si se aplica ese patrón de llamada tal cual, se obtiene silenciosamente un resultado erróneo en lugar de un error, ya que el valor que se pretendía modificar nunca se modificó.

Luego está el análisis sintáctico. Moment es flexible por diseño. Acepta entradas que otras bibliotecas más estrictas rechazan directamente o interpretan de forma diferente, y cuando una cadena no cumple ni con la norma ISO 8601 ni con la RFC 2822, recurre al formato nativo Date El constructor, una fuente clásica de errores de «desviación de un día». Si se sustituye por un analizador sintáctico más estricto, es posible que las entradas que antes «funcionaban» ahora sean rechazadas o se sitúen en un día diferente.

Consejo de experto: Los tokens de formato tampoco son portables. Moment’s YYYY-MM-DD es yyyy-MM-dd en date-fns y Luxon. Day.js conserva los tokens de Moment, y date-fns, como mínimo, genera un error al YYYY por defecto. Luxon no lanza en absoluto. No reconoce YYYY y lo muestra tal cual, y DD significa una fecha adaptada a la zona, así que YYYY-MM-DD el resultado es algo así como «YYYY-12-29 de diciembre de 2026». La búsqueda y sustitución mecánica en cadenas de tokens es una forma bien documentada de generar resultados erróneos de forma imperceptible que ningún compilador detectará.

Las zonas horarias son aún más complicadas. La hora local frente al UTC, los cambios de horario de verano y los datos históricos sobre zonas horarias pueden variar sutilmente de una biblioteca a otra, y esas diferencias solo se hacen evidentes en fechas concretas. Los datos de configuración regional y los tokens de formato también varían, y ninguno de ellos da lugar a errores evidentes.

Lo que lo hace peligroso es el modo en que se produce el fallo. Las pruebas se superan. La compilación se realiza sin errores. No hay ningún aviso en la integración continua. Entonces, un informe de fin de mes se publica un día antes de lo previsto, solo para los usuarios de un determinado huso horario y únicamente en el límite de dicho huso.

Imagina un producto de análisis SaaS con unas 400 llamadas a Moment repartidas entre la configuración de gráficos, la exportación a CSV y los resúmenes programados por correo electrónico. Los gráficos y las exportaciones se ejecutan constantemente, por lo que sus errores se detectan rápidamente. Los resúmenes programados se ejecutan una vez al mes, formatean un intervalo de fechas según la zona horaria del destinatario y envían silenciosamente el intervalo erróneo a un subconjunto de clientes durante todo un ciclo de facturación antes de que nadie se dé cuenta. Así es como se manifiesta en la práctica una migración fallida de Moment.

Un plan de sustitución basado en el comportamiento

El plan que resiste en un código fuente extenso se organiza en torno al comportamiento, no en torno a una búsqueda global de la cadena moment. Deja las partes más arriesgadas para el final, una vez que tengas la certeza de que las partes fáciles han salido bien.

Identifica primero todos los casos de uso de «Moment» y «Moment Timezone», incluidas las dependencias transitivas y las copias integradas en paquetes de proveedores o bibliotecas de componentes. A continuación, clasifica cada punto de llamada según lo que realmente haga, ya sea análisis sintáctico, formateo, operaciones aritméticas, localización u operaciones relacionadas con la zona horaria. Estas categorías conllevan riesgos de migración muy diferentes, y agruparlas todas en una sola categoría es lo que provoca sorpresas a los equipos.

Añade pruebas de regresión basadas en fechas reales y casos extremos conocidos antes de cambiar ni una sola línea. Los cambios de horario de verano, los años bisiestos, los cambios de mes y los usuarios que no utilizan la zona horaria UTC son los que dan más problemas. A continuación, canaliza el manejo de las fechas a través de un módulo interno de fechas, de modo que la biblioteca subyacente se convierta en un detalle de implementación que puedas sustituir tras una interfaz estable, en lugar de tener 400 llamadas directas repartidas por todo el código. Ese envoltorio es el patrón que realmente funciona.

Solo entonces sustituye los casos de uso limitados y de bajo riesgo, lo que genera confianza y proporciona las herramientas necesarias para los más complejos. Por encima de todo, evita ejecutar dos modelos de datos en el mismo flujo de trabajo empresarial sin una delimitación explícita entre ellos, ya que mezclar lógica mutable e inmutable en un mismo flujo es una auténtica fábrica de errores.

Tomar una decisión: ¿Ocupación reducida, buena cobertura de pruebas y ausencia de lógica de zonas horarias? Migra ahora. ¿Uso intensivo de zonas horarias o configuraciones regionales? Envuelve primero el código y, a continuación, migra módulo por módulo. ¿Un paquete «congelado» o un componente de un proveedor que incluye Moment? Actualiza o sobrescribe la dependencia cuando el empaquetado lo permita, y deja de considerar la eliminación total como una prioridad inmediata en la hoja de ruta.

Cuándo la decisión más sensata es quedarse temporalmente con Moment

A veces, la respuesta sincera es que no vas a realizar la migración este trimestre, y esa puede ser la decisión correcta. Piensa en los sistemas regulados o en la lógica de fechas financieras, en los que un error de un solo día supone un incumplimiento normativo; en grandes aplicaciones internacionalizadas cuyo comportamiento según la configuración regional nadie ha documentado por completo; en productos integrados con ciclos de lanzamiento largos; o en aplicaciones que carecen de la cobertura de pruebas necesaria para validar una migración apresurada. En todos estos casos, retirar Moment bajo presión de tiempo es la opción más arriesgada.

La advertencia es tajante. El término «temporalmente» requiere un responsable, una fecha y un albarán. Sin esos tres elementos, «temporal» solo significa que, en la próxima auditoría, se comprobará que sigue ahí.

Esta es precisamente la brecha para la que se han diseñado los parches proporcionados por los fabricantes. El servicio ELS de TuxCare cubre moment 2.0.0, 2.10.6 y 2.24.0, además de moment-timezone 0.4.1, dentro de su Cobertura de bibliotecas de JavaScript. Las correcciones se distribuyen a través de npm con datos SBOM y VEX, por lo que la procedencia es auditable. Moment en sí mismo no tiene ninguna dependencia en tiempo de ejecución, por lo que la cuestión de la cobertura se centra en Moment, y no en una cadena de paquetes subyacentes.

Se siguen aplicando parches de seguridad en la versión fijada mientras las pruebas de migración centradas en el comportamiento avanzan a un ritmo razonable, lo que elimina la presión de tener que reescribir la lógica de fechas según un plazo fijado por una revelación que no tiene nada que ver. Así, puedes realizar la migración según tu propio calendario, y no según el calendario de las revelaciones.

El papel de OpenJS y la sostenibilidad

Moment está alojado en la Fundación OpenJS, que gestiona el Programa de Sostenibilidad del Ecosistema para que las versiones archivadas, retiradas del mercado y antiguas de sus proyectos puedan contar con cobertura de seguridad comercial, y que una parte de esos ingresos se destine a los propios proyectos. TuxCare participa como miembro «Gold» y proveedor, y el programa no es exclusivo.

La mejor alternativa es aquella que ya has comprobado

Las cifras de referencia no te salvarán a final de mes. La mejor alternativa a Moment.js es aquella cuya semántica hayas comprobado con las fechas en las que tu empresa no puede permitirse cometer errores.

Resumen
¿Moment.js ha quedado obsoleto? Estado de obsolescencia, CVE y opciones de soporte
Nombre del artículo
¿Moment.js ha quedado obsoleto? Estado de obsolescencia, CVE y opciones de soporte
Descripción
Moment.js es un proyecto heredado que se encuentra en modo de mantenimiento. Descubre qué implica esto en materia de seguridad, por qué las migraciones fallan en tiempo de ejecución y cuáles son tus opciones.
Autor
Nombre del editor
TuxCare
Logotipo de la editorial

Únase a más de 4.500 profesionales de Linux y el código abierto.

2 veces al mes. Sin spam.

Índice
Obtenga las respuestas de seguridad de código abierto que necesita

Únase a más de 4.500 profesionales de Linux y el código abierto.

2 veces al mes. Sin spam.