
Divulgación responsable de vulnerabilidad sin parchear en FluentCRM por WPManageNinja
Actualización 2023-06-12: Ya no necesitas el fragmento. WPManageNinja parcheó la vulnerabilidad dos horas después de la divulgación pública (93 días después del informe).
Actualización 2024-01-27: El problema relacionado con los valores hash perpetuos ahora está completamente resuelto.
tl;dr Los atacantes pueden ver y editar los datos de contacto en FluentCRM. WPManageNinja no ha parcheado la vulnerabilidad dentro de la ventana de divulgación responsable de 90 días. Proporciono un fragmento de mitigación para prevenir la explotación de la vulnerabilidad mientras se espera un parche oficial.
Hoy publico información sobre una vulnerabilidad que encontré en el popular plugin de WordPress FluentCRM de WPManageNinja. La vulnerabilidad, CVE-2023-1430, es causada por el uso insuficiente de un hash de dirección de correo electrónico como control de autorización por parte de FluentCRM. Divulgué la vulnerabilidad de forma responsable de acuerdo con la política de divulgación de vulnerabilidades de Google Zero. WPManageNinja no ha proporcionado un parche dentro de la ventana de 90 días ni ha solicitado una extensión de tiempo.
En este informe, contacto se refiere a un objeto de contacto de FluentCRM, mientras que usuario se refiere a un objeto de usuario de WordPress. Un contacto puede estar vinculado a un usuario, pero no es un requisito. Los detalles sobre la explotación de la vulnerabilidad se omiten hasta que esté disponible un parche oficial. Los profesionales de seguridad pueden contactarme para obtener el informe completo ([email protected]).
En los sitios que ejecutan FluentCRM, un atacante puede ver y editar el nombre, la dirección de correo electrónico y la configuración de listas de un contacto con solo conocer su dirección de correo electrónico. Dado que el nombre del contacto a menudo se incluye en los boletines mediante etiquetas de combinación, un atacante puede reemplazar el nombre del contacto con lenguaje obsceno, lo que hace que el propietario del sitio web envíe boletines vulgares. Si el administrador del sitio web ha habilitado el shortcode de FluentCRM para gestionar preferencias y lo ha añadido a una página web pública, un atacante puede ver y editar toda la información personal expuesta, es decir, título, número de teléfono, fecha de nacimiento y dirección (según la configuración de FluentCRM).
FluentCRM está instalado en más de 30 000 sitios. Los administradores de sitios con FluentCRM pueden prevenir la explotación de la vulnerabilidad añadiendo mi fragmento de mitigación al archivo functions.php del tema hijo.
El fragmento no parchea la vulnerabilidad. Reemplaza el contenido vulnerable de la página de cancelación de suscripción de FluentCRM (unsubscribe.php) y de la página de gestión de preferencias (manage_subscription.php) con un mensaje de error que indica al contacto que se comunique por correo electrónico en su lugar. La dirección de correo electrónico en el mensaje de error es la del administrador del sitio (se puede cambiar desde el fragmento). El fragmento de mitigación también garantiza que los visitantes no conectados no puedan renderizar el shortcode vulnerable de FluentCRM para gestionar preferencias (fluentcrm_pref). Un visitante no conectado verá en su lugar un mensaje de error indicándole que inicie sesión. Todas las cadenas son traducibles con el archivo POT proporcionado.
Recomiendo a los propietarios de sitios web que implementen la mitigación que proporciono o su propia mitigación correspondiente. Los propietarios de sitios web también deberían verificar la integridad de sus datos de contacto en FluentCRM y, si es posible, revisar sus registros en busca de posibles fugas de datos. Revisar los registros es especialmente importante para los siguientes sitios:
El responsable del tratamiento de datos asignado al sitio web deberá gestionar las posibles fugas de datos personales de acuerdo con las leyes y regulaciones de las jurisdicciones afectadas.
Si FluentCRM está configurado para sincronizar la configuración de un contacto con su usuario correspondiente, un atacante puede cambiar el nombre del usuario. Afortunadamente, FluentCRM no sincroniza las direcciones de correo electrónico de los contactos con los usuarios. Si lo hiciera, esta vulnerabilidad permitiría la toma de control total del sitio. Un atacante habría podido obtener acceso privilegiado cambiando la dirección de correo electrónico del administrador del sitio y luego restableciendo la contraseña del administrador.
Sin embargo, otras soluciones pueden sincronizar todos los metadatos de los contactos con los usuarios, por ejemplo, WP Fusion y la API de FluentCRM. WP Fusion es probablemente el plugin de terceros más popular para sincronizar los metadatos de los contactos entre un CRM (p. ej., FluentCRM) y WordPress. Afortunadamente, la versión actual de WP Fusion no está conectada a los cambios de metadatos iniciados desde los formularios vulnerables. He informado a los desarrolladores de WP Fusion, y no abordarán esta limitación hasta que WPManageNinja haya parcheado la vulnerabilidad.
La API de FluentCRM también se puede utilizar para actualizar datos de contactos y usuarios. Los propietarios de sitios que utilizan la API de FluentCRM para actualizar las direcciones de correo electrónico de los usuarios deben desactivar esta actualización cuando se inicie desde la página o el shortcode de FluentCRM para gestionar preferencias (o añadir mi fragmento de mitigación para garantizar que no se puedan actualizar configuraciones desde los formularios vulnerables).
FluentCRM permite a los contactos cancelar su suscripción y gestionar sus preferencias desde páginas web públicas. Los enlaces a estas páginas se incluyen en todos los boletines. Los cambios realizados en estas páginas se autorizan mediante hashes MD5 de las direcciones de correo electrónico de los contactos, enviados como parámetros de URL. El hash MD5 de una dirección de correo electrónico no es un secreto y cualquiera puede calcularlo. Un atacante puede explotar el uso incorrecto de los hashes para cancelar la suscripción de contactos específicos o cancelar la suscripción de contactos con direcciones de correo electrónico conocidas de forma masiva.
Mientras que la página de cancelación de suscripción se basa únicamente en el hash MD5 para la autorización, la página de gestión de preferencias requiere un parámetro de URL adicional llamado ce_id. En este caso, el ce_id se refiere al ID del contacto en la tabla fc_subscribers. Este ID es un entero incremental. El valor de ce_id se encuentra fácilmente probando todos los valores posibles (el espacio de búsqueda es el número de contactos que se han registrado en el sitio). Los usuarios administradores probablemente tienen valores bajos.
Desde la página de gestión de preferencias, un atacante también puede exfiltrar el valor secure_hash del contacto. Al actualizar la dirección de correo electrónico del contacto, el valor “secure_hash” del contacto se almacena en una cookie llamada fc_hash_secure. Con esta cookie, el atacante puede mostrar toda la información de contacto disponible a través del shortcode del formulario de preferencias de FluentCRM.
El “secure_hash” mencionado anteriormente es un valor en el que FluentCRM (en algunas situaciones) se basa en lugar del hash MD5 de la dirección de correo electrónico o como alternativa a este. Desde el lanzamiento de FluentCRM 2.8.0, la página de cancelación de suscripción se basa exclusivamente en el valor secure_hash para la autorización. La página de gestión de preferencias acepta tanto el nuevo valor secure_hash como el antiguo hash MD5 de la dirección de correo electrónico para la autorización.
Si bien el valor secure_hash no se puede derivar de la dirección de correo electrónico, el uso que hace FluentCRM no sigue buenas prácticas de seguridad. El valor secure_hash se genera una vez por contacto. Nunca se actualiza y nunca expira. Esto es problemático ya que el valor secure_hash se incluye en todos los boletines. Si un atacante obtiene acceso a la bandeja de entrada de un contacto, el atacante puede cambiar la configuración del contacto indefinidamente. Si el contacto afectado está vinculado a un usuario con privilegios de administrador, y los cambios de dirección de correo electrónico se sincronizan de FluentCRM a WordPress, cada boletín enviado a este contacto contendrá un token que nunca expira para tomar el control del sitio.
Informé de este problema relacionado a WPManageNinja el 2023-03-15. Dos meses después (2023-05-15), WPManageNinja respondió que sus asesores de seguridad no consideraban que el valor estático secure_hash fuera un problema. Los asesores de seguridad de WPManageNinja dijeron que era “aceptable utilizar este tipo de tokens generados una sola vez para identificar al contacto” y que era “similar a los tokens de API de los servicios SaaS que no se entregan a ningún otro contacto, sino que solo se envían al contacto real que posee la dirección de correo electrónico”.
WPManageNinja fue receptivo y me dijo que les avisara si todavía pensaba que era un problema de seguridad, y así lo hice. Expliqué por qué los valores secure_hash no se podían comparar con los tokens de API. (Se puede garantizar que los tokens de API solo se envíen a través de conexiones TLS, y el acceso a los tokens de API se puede restringir. Ese no es el caso con los valores en texto plano en los correos electrónicos. Lo más importante es que los tokens de API se pueden revocar, mientras que un contacto no tiene forma de revocar un valor secure_hash).
Más tarde ese mismo día, WPManageNinja me agradeció y dijo que consideraban combinar el ID del registro de correo electrónico con el hash. Eso resolverá el problema si se implementa junto con la revocación automática de los valores secure_hash antiguos (caducidad por tiempo) o anteriores (caducidad por contador). Esta función aún no se ha implementado, pero no considero que el uso de valores hash estáticos sea parte de este CVE.
En el primer trimestre de 2023, comenzamos a migrar desde nuestra herramienta de boletines anterior (Sendy) a FluentCRM. Encontré la vulnerabilidad mientras integraba FluentCRM con Nikka Systems Academy (Project Opal). Dado que reemplazamos el sistema de gestión de suscripciones de FluentCRM con nuestro plugin personalizado, los formularios vulnerables de FluentCRM nunca han afectado a nuestro sitio ni a los datos de nuestros clientes.
FluentCRM es un gran plugin, pero el manejo de la divulgación de la vulnerabilidad por parte de WPManageNinja deja mucho margen de mejora. La siguiente lista es mi sugerencia sobre cómo WPManageNinja podría mejorar la situación.
Dicho esto, todavía confío en WPManageNinja. Hay errores en todo software, y un único informe de vulnerabilidad mal gestionado no es una razón para dejar de usar sus plugins.
Actualización 2023-06-12: El hecho de que todavía intentaran ocultar la vulnerabilidad en su registro de cambios me preocupa genuinamente. (Ahora han añadido el CVE).