Saltar al contenido
CVE-2026-121564 ·
Baja · 3 de noviembre de 2026

Comparación incompleta por omisión de factores en merge_chats de whatstk

S0
Secur0 CNA
CVE-2026-121564

Descripción

Comparación incompleta por omisión de factores (CWE-1023) en merge_chats() (whatstk/utils/chat_merge.py), alcanzada desde BaseChat.merge(), en whatstk desde 0.3.0 y anterior a 0.9.0. Fusionar dos exports de la misma conversación puede dejar mensajes fuera del chat fusionado sin ninguna indicación de que se haya retirado nada.

La fusión conserva íntegro el chat cuyo primer mensaje es más antiguo y añade del otro únicamente los mensajes estrictamente posteriores al último mensaje del primero. Todo mensaje del segundo chat que caiga dentro del rango de fechas ya cubierto por el primero queda por tanto descartado, con independencia de que el primero contenga ese mensaje o no.

Los dos chats se comparan por sus rangos de fechas y no por la identidad de cada mensaje, de modo que un mensaje que sólo consta en uno de los dos exports se pierde siempre que su fecha caiga dentro del rango del otro. Ambas ramas de _merge_two_chats() se comportan así, y el resultado fusionado se devuelve sin aviso alguno y sin un recuento de lo retirado.

Quien aporta los exports decide qué rangos se solapan y qué contiene cada fichero, por lo que pueden hacerse desaparecer mensajes del registro fusionado entregando dos exports cuyas ventanas se solapen. Nada tiene que estar mal formado: los dos ficheros son exports válidos y cada uno está completo por separado.

Esto importa por los usos que el propio proyecto documenta. Dos exports de una misma conversación, tomados en momentos distintos o desde los teléfonos de participantes distintos, son precisamente el caso para el que existe la función, y la salida fusionada es sobre la que después se construye una revisión forense o un corpus de entrenamiento.

Tipo de vulnerabilidad (CWE)

  • CWE-1023: Comparación incompleta por omisión de factores

Versiones afectadas

whatstk desde 0.3.0 y anterior a 0.9.0. chat_merge.py se publica por primera vez en 0.3.0, y el descarte está presente desde esa versión: la implementación original comparaba el índice del DataFrame y desde 0.4.0 compara la columna de fecha, con el mismo efecto en ambos casos. Estado por defecto: no afectado.

Reproducido en la 0.8.1 de PyPI con dos exports de un mismo chat solapados en cinco días, donde el export ensombrecido contenía tres mensajes que el otro no: 11 mensajes distintos entre las dos entradas, 8 filas en la salida fusionada, 3 mensajes perdidos. Las mismas entradas en 0.9.0 producen los 11.

Puntuación (CVSS 4.0)

Baja (1.8)

CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:A/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N

El vector de ataque es Local porque la librería lee ficheros de export en la máquina que la ejecuta. Los privilegios requeridos son Ninguno, ya que quien aporta los exports no necesita ningún acceso a esa máquina. La interacción del usuario es Activa porque la fusión tiene que invocarse sobre los dos ficheros. Los requisitos de ataque son Presentes porque deben coincidir varias condiciones ajenas al control del atacante: han de fusionarse dos exports de la misma conversación en lugar de leerse por separado, los mensajes que se pretende suprimir no deben constar en el export del propio atacante, y el export del atacante debe empezar antes y terminar después que esos mensajes, lo que depende de la ventana de un fichero producido en el dispositivo de otra persona. La confidencialidad es Ninguna: no se revela nada que las entradas no contuvieran ya. La integridad del sistema vulnerable es Baja porque la salida fusionada queda incompleta mientras los dos exports de origen permanecen intactos y la fusión puede repetirse una vez actualizada la librería, por lo que la pérdida se limita al registro derivado. La disponibilidad es Ninguna porque nada deja de funcionar. Las métricas del sistema subsiguiente son Ninguna, ya que lo que se produce después a partir del chat fusionado es una consecuencia de la salida y no un impacto sobre otro sistema.

Solución

Actualizar a whatstk 0.9.0 o posterior.

Fusionar los exports con la versión corregida reproduce el registro completo a partir de los mismos ficheros de entrada, por lo que una fusión realizada con una versión afectada puede repetirse en lugar de quedar perdida de forma permanente.

Parche

Publicado en 0.9.0, mediante la pull request #185 y el commit de publicación 01d66d8. merge_chats() devuelve ahora la unión deduplicada de todos los mensajes de los chats dados, ordenada por fecha, y considera dos mensajes como el mismo cuando coinciden su fecha, su nombre de usuario y su texto. Los mensajes repetidos se numeran dentro de cada chat antes de concatenar, de modo que un mensaje que un usuario envió realmente dos veces se conserva dos veces mientras que la copia de él que contiene un segundo export de la misma conversación se colapsa.

Créditos

  • Robert Mihaila - descubridor
  • Amirreza Fadaeizadeh Bidari - descubridor
  • Xoán M. Otero Jorge - analista
  • Darío Rivas - analista
  • Secur0 CNA - coordinador
  • Lucas Rodés-Guirao - desarrollador de la corrección

Origen del descubrimiento: Externo

Registro oficial: CVE-2026-121564