Principales conclusiones
- Commons Collections suele incluirse de forma transitiva, por lo que puede que esté presente en tu compilación aunque nadie lo haya añadido.
- Su paquete «functors» proporcionó los componentes básicos para las cadenas de utilidades de deserialización más conocidas de Java.
- Pasar de la versión 3.x a la 4.x implica nuevas coordenadas, un nuevo espacio de nombres para los paquetes y cambios deliberados en la API.
- ELS para Apache Commons Collections aplica parches a las versiones en fin de vida útil y a sus cadenas de dependencias mientras planificas la migración.
Si Apache Commons Collections aparece en algún punto de tu grafo de dependencias de Java —y en el ámbito del Java empresarial suele ser así—, conviene aclarar la cuestión del fin de la vida útil antes de que un escáner o un auditor te lo plantee.
Esta es la biblioteca que hay detrás de algunas de las cadenas de gadgets de deserialización más famosas de Java. No porque Apache incluyera una puerta trasera, sino porque unas cuantas clases del paquete «functors» son serializables y utilizan reflexión, y alguien acabó dándose cuenta de lo que se podía construir a partir de eso. Las revelaciones de 2015 convirtieron un archivo JAR de utilidad rutinario en un problema de dependencias que los equipos de seguridad tuvieron que perseguir a través de servidores de aplicaciones que no controlaban. Esta entrada repasa esa historia, lo que significa para los equipos que aún utilizan la línea de artefactos más antigua y qué papel desempeña el soporte ampliado cuando la migración no se va a llevar a cabo este trimestre.
Dos líneas de artefactos y por qué es importante
Commons Collections existe desde el año 2001. Amplía el Java Collections Framework con estructuras de datos, iteradores, comparadores y utilidades de transformación que el JDK nunca incluyó, y esa es precisamente la razón por la que acabó utilizándose en todas partes. Su omnipresencia es también lo que ha hecho que su historial en materia de seguridad haya sido tan problemático.
Existen dos líneas de artefactos, y confundirlas es la causa más habitual de que se den consejos erróneos sobre la remediación.
La línea heredada es commons-collections:commons-collections, que abarca toda la serie 3.x y se encuentra en la org.apache.commons.collections espacio de nombres de paquetes. Apache describe las versiones 3.2 y 3.2.1 como compatibles con Java 1.2; la versión 3.2.1 se lanzó el 15 de abril de 2008. La versión final, la 3.2.2, llegó en noviembre de 2015 como una actualización de seguridad y corrección de errores, y pasó a Java 1.3. Su cambio más destacado fue desactivar por defecto la deserialización de las clases de functores inseguras, por lo que intentar realizarla genera un UnsupportedOperationException a menos que alguien establezca explícitamente el org.apache.commons.collections.enableUnsafeSerialization propiedad del sistema a «true». Desde entonces no se ha lanzado nada en la línea 3.x.
La línea actual es org.apache.commons:commons-collections4, y el espacio de nombres del paquete se ha trasladado a org.apache.commons.collections4 junto con él. Se le asignó un nuevo `groupId` y `artifactId` precisamente porque la versión 4.0 nunca se diseñó para ser compatible con versiones anteriores, y ese cambio en el espacio de nombres es la razón por la que un JAR 3.x y uno 4.x pueden coexistir en la misma ruta de clases sin que se produzcan conflictos. La versión 4.0 se lanzó el 27 de noviembre de 2013, con genéricos en todo el sistema y Java 5 como requisito mínimo. La versión 4.1 le siguió el 28 de noviembre de 2015 y completó el trabajo que había iniciado la 3.2.2, eliminando por completo `Serializable` de las clases de functores inseguras, en lugar de limitarse a restringir su uso. Después llegaron la 4.2 el 11 de julio de 2018, la 4.3 el 21 de diciembre de 2018, la 4.4 el 5 de julio de 2019, la 4.5.0 el 19 de abril de 2025 y la versión actual, la 4.6.0, el 6 de agosto de 2026. El umbral de Java subió al mismo ritmo, pasando de Java 5 en 4,0 a Java 6 en 4,1 y Java 7 en 4,2, y luego a Java 8 a partir de 4,3, incluida la versión 4.6.0.
Apache no publica un aviso oficial de fin de vida útil (EOL) para la versión 3.x, por lo que nadie te va a facilitar un comunicado con fecha concreta para que lo pegues en un ticket. Lo que sí puedes dejar claro es lo siguiente: no se ha lanzado ninguna versión 3.x desde noviembre de 2015, todo el desarrollo se centra en la versión 4.x y, dado que la 3.2.2 fue la última de esa línea, nadie debería contar con una adaptación (backport) de la versión 3.x del código original para un problema recién detectado.
Qué significa realmente «fin de la vida» en este contexto
Se acabaron las soluciones «upstream»
Para cualquier cosa que se ejecute en commons-collections:commons-collections, en la práctica, la situación es sencilla. No ha habido ninguna nueva versión 3.x desde la 3.2.2, y Apache lleva más de una década centrando su atención en la línea 4.x.
Las versiones anteriores de la serie 4.x se encuentran en una variante más moderada de esa misma situación. Las correcciones publicadas por Apache se incorporan a las versiones más recientes de la serie 4.x, por lo que, en el caso de un problema que afecte a una versión anterior de la serie 4.x, la vía habitual de corrección por parte del desarrollador original consiste en pasar a la versión actual.
La historia de la CVE que mucha gente entiende mal
Conviene ser preciso en este punto, ya que los resultados del escáner y los títulos de los CVE no coinciden, y esa discrepancia ha provocado muchas reuniones inútiles.
Apache afirma en su propia página de seguridad que no se asignó ningún identificador CVE a la biblioteca Commons Collections por el problema de deserialización de 2015. Los identificadores que todo el mundo cita pertenecen a productos derivados. El CVE-2015-7501 se registró para los productos Red Hat JBoss y el CVE-2015-6420 para una larga lista de productos de Cisco; ambos tienen una calificación de 9,8 (crítico) según el CVSS v3, y ambos se describen como relacionados con la biblioteca Apache Commons Collections, más que como fallos en la propia biblioteca. La propia página de Apache señala un tercero, el CVE-2015-4852, correspondiente a Oracle WebLogic Server.
El mecanismo que hay detrás de todas ellas es el mismo. Varias clases del paquete «functors» son serializables e invocan métodos de forma reflexiva, con InvokerTransformer especialmente útil para un atacante, ya que invocará un método específico mediante reflexión. Si se encadenan los «gadgets» necesarios, se pasa el objeto resultante a una aplicación que deserializa entradas no fiables sin validarlas —mientras esas clases se encuentran en la ruta de clases— y el resultado puede ser la ejecución de comandos arbitrarios con los privilegios del proceso de la JVM. Apache indica que las versiones afectadas van de la 3.0 a la 4.0, y que el problema se solucionó en las versiones 3.2.2 y 4.1.
La cronología explica por qué tuvo un impacto tan grande. Gabriel Lawrence y Chris Frohoff presentaron la técnica en AppSecCali el 28 de enero de 2015. Stephen Breen publicó el 6 de noviembre de 2015 escenarios de ataque operativos contra WebSphere, JBoss, Jenkins, WebLogic y OpenNMS. Apache afirma que su equipo de seguridad no fue informado antes de la publicación, por lo que las correcciones se implementaron pocas semanas después de que el exploit se hiciera público, y los equipos descubrieron que la biblioteca se encontraba en varios niveles de profundidad dentro de los árboles de dependencias, por lo que no podían modificarla directamente.
Por lo tanto, cuando tu escáner detecta un archivo JAR 3.2.1 asociado a un CVE cuyo título menciona a Cisco, el escáner no está dando un falso positivo. Esos registros de avisos vinculan las versiones vulnerables de Commons Collections con los productos derivados que las incluían, y la base de datos de avisos de GitHub recoge el mismo problema relacionado con el artefacto de Maven con el identificador GHSA-6hgm-866r-3cjv. El hallazgo es real, aunque el CVE incluya el nombre de un producto de otra empresa.
Riesgos en materia de cumplimiento normativo y auditoría
El requisito 6.3.3 de la norma PCI DSS v4.0.1 exige que los parches para las vulnerabilidades que su organización clasifique como críticas se instalen en el plazo de un mes desde su publicación, mientras que el resto debe instalarse en el plazo que usted establezca mediante el mismo proceso de clasificación de riesgos descrito en el requisito 6.3.1. La norma PCI DSS no considera automáticamente que todos los hallazgos de CVSS 7.0 sean críticos, por lo que la gravedad que se le atribuya a un hallazgo de Commons Collections dependerá de su clasificación documentada y de su exposición real. La Norma de Seguridad de la HIPAA funciona de manera diferente, ya que obliga a las entidades afectadas y a los socios comerciales a proteger la información sanitaria protegida en formato electrónico frente a amenazas razonablemente previsibles, que es precisamente el tipo de obligación de alcance indefinido que un componente al final de su vida útil (EOL) sin parchear dificulta defender.
Los componentes sin soporte técnico también pueden suscitar dudas sobre los controles de gestión de vulnerabilidades durante una auditoría SOC 2 Tipo II, y la autorización FedRAMP conlleva sus propias expectativas en materia de supervisión continua y corrección de fallos. El soporte técnico ampliado no garantiza por sí solo el cumplimiento normativo de una organización, pero sí mantiene un flujo constante de parches, lo que permite seguir cumpliendo los compromisos de gestión de vulnerabilidades mientras se sigue planificando la migración.
El problema del árbol de dependencias
Commons Collections en sí misma no es Tangle. El artefacto 4.6.0 ocupa muy poco espacio, con commons-codec 1.22.1 como única dependencia opcional de compilación y todo lo demás limitado al ámbito de las pruebas, por lo que su propia contribución al gráfico de dependencias en tiempo de ejecución de un consumidor es mínima.
El problema está en el lado del consumidor. Los servidores de aplicaciones lo incluyen, las herramientas de desarrollo lo distribuyen y los marcos heredados lo requieren. Ejecutar mvn dependency:tree si lo aplicas a una aplicación Java empresarial madura, es muy probable que encuentres en el resultado un antiguo archivo JAR de Commons Collections 3.x, incluido por algún proyecto cuyos responsables no hayan actualizado sus declaraciones de dependencias desde hace mucho tiempo. Cada copia vulnerable de ese gráfico puede convertirse en un hallazgo, ya que los escáneres recorren todo el gráfico en lugar de limitarse a lo que tú has declarado. Que una copia concreta cuente o no depende de la versión, ya que las versiones 3.0 a 3.2.1 se encuentran dentro del rango afectado, mientras que la 3.2.2 ya incorpora la corrección de Apache.
Eso es lo que hace que el fin de vida útil (EOL) de Apache Commons Collections resulte complicado. No se trata tanto de un problema de versión de la biblioteca como de uno de alcance y visibilidad, y cuando el propio componente que incorpora el antiguo JAR ya no recibe mantenimiento, aplicar un parche a la biblioteca en el lugar donde realmente se encuentra evita el riesgo de incompatibilidad que supone forzar una versión transitiva más reciente en una cadena de dependencias que ya nadie mantiene.
¿Cuáles son tus opciones (realistas)?
Migración a commons-collections4 4.6.0
La solución definitiva a largo plazo consiste en pasar de commons-collections:commons-collections a org.apache.commons:commons-collections4 en la versión 4.6.0, lo que te sitúa en la rama que se mantiene activamente.
Sin embargo, no se trata de un simple cambio de versión. Es un cambio de dependencias con modificaciones en la API que obligan a revisar todas las clases que interactúan con la biblioteca. Se han incorporado genéricos en todo el código, se han eliminado las clases obsoletas de la versión 3.x, el Buffer La interfaz se sustituyó por java.util.Queue, y se han trasladado las firmas de utilidades. Todas las importaciones deben trasladarse al espacio de nombres «collections4», y cualquier elemento que dependa del comportamiento de la versión 3.x, especialmente en el paquete «functors», requiere cambios reales en el código para que se pueda compilar.
Los equipos que ya utilizan la versión 4.x tienen menos trabajo, aunque siguen teniendo que leer los registros de cambios de cada versión intermedia y probar la ruta de actualización, en lugar de actualizar a ciegas.
Cuando Commons Collections se instala de forma transitiva en lugar de directa, la ruta de migración pasa por aquello que lo está incorporando. Si esas bibliotecas tampoco reciben mantenimiento, te ves obligado a anular las versiones transitivas y a validar la compatibilidad por tu cuenta, lo cual es factible, pero no es gratuito ni siempre seguro.
Sustitución total de Commons Collections
Algunos equipos consideran que el hecho de que una biblioteca haya llegado al final de su vida útil (EOL) es una buena excusa para plantearse si realmente siguen necesitando esa biblioteca. Las alternativas son ahora realmente buenas, entre ellas Eclipse Collections, las utilidades de colecciones de Guava y una biblioteca estándar que ha incorporado gran parte de lo que llevó a la gente a recurrir a Commons Collections en un principio.
Sustituirlo por completo supone un trabajo mayor que actualizarlo. Cada punto de uso necesita un equivalente, hay que comprobar las diferencias de comportamiento y todo lo que se haya creado a partir de functores o flujos de transformación requiere una atención individualizada. Para un código base con años de uso acumulado, se trata de un proyecto que abarca varios sprints, no de una respuesta a un hallazgo que se detectó el martes pasado.
Asistencia técnica ilimitada durante todo el ciclo de vida de TuxCare
ELS para Apache Commons Collections garantiza el suministro continuo de parches de seguridad para las versiones en fin de vida útil (EOL) compatibles, sin que tengas que llevar a cabo una migración que tu equipo no haya planificado. Actualmente, la cobertura incluye las versiones 3.2 y 3.2.1; para otras versiones, merece la pena consultar. Si utilizas una versión compatible, esta se mantiene tal cual, tus flujos de trabajo actuales no se ven afectados y los parches siguen llegando a medida que surgen nuevos problemas.
Esa es la brecha que este producto viene a cubrir: el lapso que transcurre entre el momento en que una versión fuera de ciclo de vida (EOL) se convierte en un problema en un informe y el momento en que se completa realmente una migración planificada y probada.
Por qué precipitarse a la hora de actualizar puede resultar contraproducente
La presión es real. Los escáneres la ponen de manifiesto, los auditores preguntan por el plan y los plazos de cumplimiento no se modifican. Los equipos que gestionan bien esta situación son aquellos que saben diferenciar entre responder a un riesgo y generar uno nuevo.
En qué consiste realmente la migración
Dejar atrás la versión 3.x implica actualizar las coordenadas de los artefactos en todos los lugares donde se declare la dependencia o se gestione de forma centralizada, reescribir las importaciones para el nuevo espacio de nombres del paquete y, a continuación, revisar los usos de las colecciones para garantizar la seguridad de tipos y tener en cuenta los cambios en la API que trajo consigo la API generificada de la versión 4.x. Las clases eliminadas deben sustituirse o reescribirse. El código que utiliza el paquete de functores de la versión 3.x debe evaluarse caso por caso, ya que parte de él se adapta perfectamente a las interfaces funcionales de Java 8 y otra parte requiere una reescritura específica del diseño.
En cualquier caso en el que se procesen datos Java serializados, es necesario comprender y probar la diferencia entre el modelo 3.2.2 —en el que la deserialización insegura de functores está desactivada a menos que una propiedad del sistema la active— y el modelo 4.1 —en el que esas clases no son serializables en absoluto— antes de que el sistema pase a producción.
¿Qué falla cuando se comprime?
Los errores de compilación son la parte fácil, porque las API a las que se les ha cambiado el nombre o se han eliminado se detectan de inmediato. Los errores interesantes pasan más desapercibidos. Los problemas de compatibilidad binaria pueden manifestarse como NoSuchMethodError en tiempo de ejecución, mientras que las búsquedas reflexivas fallidas pueden generar NoSuchMethodException en cambio, y no hay garantía de que ninguna de las dos se detecte solo con la compilación.
Los cambios de comportamiento son peores. MultiValueMap quedó obsoleto en la versión 4.1 y se sustituyó por el nuevo MultiValuedMap interfaz, BeanMap Se lanzó en la versión 4.0, tras haber trasladado su equivalente a Commons BeanUtils, y en la versión 4.6.0 se dejó de recomendar su uso por completo. Bag familia a favor de MultiSet. El código que depende de la semántica antigua puede superar una suite de pruebas y, posteriormente, fallar ante un formato de datos concreto en producción.
Luego están los restos. Las soluciones provisionales de compatibilidad creadas para cumplir un plazo se convierten en permanentes, y el «ya lo arreglaremos más adelante» acaba siendo un problema del que se tiene que encargar otra persona. Si a esto le sumamos el tiempo de ingeniería de emergencia, el retraso en el trabajo de la hoja de ruta y el hecho de que los ingenieros sénior tengan que depurar el entorno de producción en lugar de lanzar la versión, una migración apresurada puede acabar costando fácilmente más que el plazo que se pretendía cumplir. El problema no se resuelve de esa manera. Simplemente se aplaza a un coste adicional.
Cómo funciona TuxCare ELS para Apache Commons Collections
TuxCare cuenta con quince años de experiencia en la creación de parches de código abierto y ha publicado más de 420 000 parches para sistemas operativos, entornos de ejecución, marcos de trabajo y bibliotecas. ELS para Apache Commons Collections sigue ese mismo proceso.
Cobertura de la cadena de dependencias incluida
La cobertura abarca tanto las dependencias directas como las transitivas sin coste adicional. Los escáneres no se detienen en el artefacto de nivel superior, por lo que tampoco lo hace la aplicación de parches.
Cómo se fabrican los parches
El seguimiento de CVE se lleva a cabo de forma continua a partir del NVD, los avisos de los proveedores, los avisos de seguridad de GitHub y otras fuentes. Cuando se detecta algo, las herramientas algorítmicas y la automatización asistida por IA ayudan a los ingenieros con la retrocompatibilidad; los ingenieros de seguridad validan el resultado, y cada compilación se somete a pruebas de integridad, funcionalidad y regresión antes de llegar al repositorio. Los parches se distribuyen firmados desde repositorios alojados por TuxCare, y el documento técnico «Open Source Patching Process» contiene toda la información detallada si deseas conocer el proceso.
Cómo adaptarlo a tu complexión
Tanto si obtienes Commons Collections a través de Maven como de Gradle, el principal cambio consiste en dirigir tu compilación al repositorio de TuxCare y asegurarte de que la resolución de dependencias seleccione el artefacto parcheado. Tu proceso de compilación, tu CI/CD y la forma de trabajar de tu equipo no sufren ningún cambio.
Con qué rapidez llegan los parches
Las vulnerabilidades de riesgo alto y crítico que afecten a versiones en fin de vida útil (EOL) para las que se ofrece soporte —es decir, aquellas con una puntuación CVSS 7.0 o superior— tienen un plazo de 14 días desde su divulgación pública, mientras que las de riesgo medio tienen un plazo de 60 días y las de riesgo bajo, de 90. El servicio de clasificación de vulnerabilidades y asistencia para la resolución de problemas está disponible las 24 horas del día, los 7 días de la semana, los 365 días del año.
Visibilidad para los auditores
El rastreador de CVE de TuxCare muestra qué vulnerabilidades se han identificado y solucionado en los productos compatibles y en sus cadenas de dependencias. Esto proporciona a los equipos de seguridad y cumplimiento normativo una evidencia más clara de lo que realmente se ha solucionado que el resultado de un escáner en un momento determinado por sí solo.
No dejes que un aviso de fin de vida útil se convierta en un incidente
Una versión de EOL Commons Collections no causa ningún problema por sí sola. Lo que sí hace es dejarte sin una versión 3.x de origen que se mantenga y a la que puedas recurrir cuando aparezca la próxima vulnerabilidad que afecte a esa versión, o cuando las clases que aún se encuentran en tu ruta de clases resulten útiles en una cadena de deserialización recién revelada.
Si tu problema actual es garantizar la seguridad de una versión antigua de Commons Collections mientras planificas la migración, echa un vistazo a lo que cubre el servicio «Endless Lifecycle Support for Open Source Software» de TuxCare en el resto de tu infraestructura.
