Un CVE publicado el lunes indica que las wheels oficiales de Flair para 0.15.0 y 0.15.1 aún contienen flair/models/clustering.py, cuya ruta de carga del modelo devuelve pickle.loads(joblib.load(...)). Se trata del mismo sink, en el mismo archivo, que en un CVE de 2024 — el cual sitúa 0.15.0 como la versión corregida.

Qué significaba «corregido»

El soporte para clustering se retiró en 0.15.0 — de la API documentada. No se eliminó del artefacto distribuido. El módulo sigue en la wheel y puede alcanzarse importando directamente flair.models.clustering. El nuevo aviso lo dice con claridad: «la versión corregida del registro anterior no se corresponde con el paquete distribuido».

Qué falla en el enfoque convencional

La trampa aquí no está en el código, sino en los metadatos. «Corregido en 0.15.0» en un registro CVE se interpretó como que el código había salido del paquete; en realidad, significaba que los mantenedores dejaron de dar soporte a la función. Cualquiera cuyo escáner de análisis de composición de software lea el campo de versión corregida del registro de 2024 marcará como limpio un 0.15.1 instalado. No lo está. La segunda mala interpretación va en sentido contrario, hacia la alarma: las puntuaciones son 8.4 y 7.8 HIGH, pero el vector es localAV:L y requiere interacción del usuario. La víctima tiene que cargar un archivo de modelo proporcionado por un atacante. Se trata de un problema de cadena de suministro de pesos no confiables, no de una RCE de red, y presentar la 8.4 sin el vector lo exagera mucho. Ambas puntuaciones son secundarias; NVD no ha publicado ninguna CVSS primaria.

Las fechas que lo agravan

0.15.0 de Flair se subió a PyPI el 20 de diciembre de 2024. 0.15.1 le siguió el 5 de febrero de 2025 y desde entonces ha sido la versión actual, durante unos 18 meses en los que el archivo ha seguido presente, la función ha estado sin documentar y los metadatos del ecosistema han dicho que el problema estaba resuelto. Hoy tampoco existe ninguna versión corregida.

Por qué esta clase de problema se repite

«Cargar un archivo de modelo y ejecutar su código» es el riesgo más antiguo del ecosistema de ML en Python, y pickle sigue siendo la serialización predeterminada en gran parte de él. Lo que hace instructivo este caso es que el fallo está en el registro y no en el código: un aviso de hace dos años dejó señalado como resuelto un sink activo, y la automatización en la que confían la mayoría de las organizaciones se lo creyó.