Error de duplicación de lista de correo con implicaciones de seguridad

He encontrado un error interesante y poco común con respecto a cómo se archivan las respuestas a las publicaciones en listas de correo que se reflejan en Discourse.

Tengo pruebas de que las respuestas a una lista de correo pueden archivarse incorrectamente en una segunda lista de correo (con un público diferente) si el correo electrónico inicial se envió a ambas listas de correo al mismo tiempo.

Imagina que pertenezco a dos listas de correo, A y B, suscrito con mi dirección de Gmail. Tienen públicos potencialmente diferentes. El servidor de listas envía una sola copia de un mensaje a quienes están en ambas listas de correo, pero la línea Para: indica que el mensaje se envió a las listas A y B en el mismo correo electrónico. Este correo electrónico llega a mi dirección de Gmail, que luego, a través de un filtro, reenvía una copia a listaA@mydiscourse.org.uk, y Gmail elige una de las dos listas en la línea Para:. Gmail está configurado para reenviar publicaciones a A a listaA@mydiscourse.org.uk y publicaciones a B a listB@mydiscourse.org.uk. Discourse está configurado con dos categorías con esas dos direcciones de correo electrónico de entrada de duplicación diferentes (listA@mydiscourse.org.uk y listB@mydiscourse.org.uk).

El problema de que el servidor de listas y Gmail solo envíen una copia es un tema aparte y no es el objeto de este error.

Después de esto, una copia del correo electrónico enviado a mí en mi cuenta de Gmail termina mostrándose en la categoría asociada con la dirección de entrada listA@mydiscourse.org.uk después de que Gmail lo reenviara.

Todo bien hasta ahora (aparte del hecho de que solo llegó un correo electrónico del servidor de listas en primer lugar).

Ahora, un usuario separado, que solo está en la lista de correo B, responde a ese correo electrónico al servidor de listas. El servidor de listas envía ese mensaje a todos en la lista de correo B. Esto llega a mi dirección de Gmail con una línea Para: que indica que se envió a la lista B. Gmail lo reenvía a listB@mydiscourse.org.uk.

¡Pero entonces Discourse lo archiva como si se hubiera enviado por correo electrónico a listA@mydiscourse.org.uk!

¡Esto, por lo tanto, revela a quienes tienen acceso a la lista A el contenido de la publicación de un miembro de la lista B!

Sospecho que Discourse ignora la ruta que tomó el correo electrónico para ingresar a Discourse y lo archivó basándose en los indicadores del ID del mensaje en las cabeceras, eludiendo así la ruta de entrada.

El correo electrónico original, enviado a A y B, tiene un único ID de mensaje y sospecho que se está produciendo un archivo basado únicamente en ese ID de mensaje.

Si el remitente original hubiera escrito dos correos electrónicos separados a la lista A y a la lista B, este problema no habría ocurrido, ya que los dos mensajes tendrían sus propios IDs de mensaje.

Solución sugerida: Si una categoría está duplicando una lista de correo y llega un mensaje a través de la dirección de duplicación que, según las cabeceras, parece ser una respuesta a otra publicación que reside en otro lugar de Discourse, entonces se debe crear una nueva publicación (quizás sin un padre obvio) en la categoría esperada, en lugar de que la respuesta termine en una categoría que está asociada con una lista de correo diferente.

De hecho, o:

Creo que es el tema de este error. Esto debería corregirse en el servidor de listas, no en Discourse.

1 me gusta

No estoy seguro de haberme explicado bien, ya que no entiendo por qué Discourse pondría una publicación en la categoría incorrecta. Es como si no estuviera mirando la ruta de entrada (que debería tener prioridad) sino solo el message-id. Para un solo correo electrónico enviado a dos listas de correo al mismo tiempo, habrá un message-id pero con dos listas de distribución (que son independientes), dos direcciones ‘To:’ y dos direcciones ‘Reply-To:’ (con una diferente que se muestra en cada uno de los mensajes dependiendo de a qué lista se envió).

Si esto es lo que está sucediendo, ¿qué pasaría si alguien moviera un tema fuera de una categoría que era un espejo de una lista de correo y lo pusiera en otro lugar en Discourse, pero luego las respuestas (a través de la lista de correo) siguieran llegando? ¿Añadiría Discourse esas respuestas a la categoría asociada con la lista de correo (aunque la publicación original se haya movido) o todas las respuestas terminarían mágicamente en la categoría a la que se había movido el tema?

¿Puede Discourse manejar tener dos mensajes en dos categorías al mismo tiempo que tienen el mismo message-id (pero diferentes direcciones ‘To:’)?

Independientemente de cómo maneje Discourse esto, un Message-ID debe ser único. En mi opinión, cuando un servidor de listas envía un mensaje a una lista de correo, crea una nueva instancia de ese mensaje y, por lo tanto, debería reescribir el message ID.

Además, no entiendo cómo el mensaje original podría ser adecuado tanto para los miembros de las listas A como B, pero la respuesta del miembro de la lista B no podría revelarse a los miembros de la lista A. Si esas audiencias son tan diferentes, ¿por qué el usuario envía los mismos mensajes a ambas listas al mismo tiempo?

Tal vez haya una buena solución técnica para esto y tal vez Discourse pueda modificarse para que maneje esto correctamente, pero encuentro que este es un caso límite realmente extraño en una tecnología de 36 años.

Se podría argumentar que, dado que el mensaje es el mismo, tiene un único ID de mensaje. De hecho, para el ejemplo en cuestión, el autor original compuso el mensaje en Gmail (que asignó el ID del mensaje) y se envió a dos direcciones de listas de correo en el mismo servidor. Esto no es infrecuente, por ejemplo, podría ser un comunicado de prensa común para gerentes y médicos, cada uno de los cuales se encuentra en sus propias listas de correo. Puede haber un problema médico dentro del comunicado de prensa que necesite discusión, por lo que un médico podría responder (y la dirección de Respuesta a: se habría establecido en la lista de médicos, aunque el encabezado Para: todavía tenía ambas listas de correo mencionadas). De manera similar, los gerentes podrían desear discutir su propia visión de las noticias. Responderían y el encabezado de Respuesta a: relevante se utilizaría para reflejar la lista de gerentes. Si un remitente hubiera hecho uso de las direcciones Para: al hacer una “respuesta a todos”, se habría generado un mensaje de rebote de la lista de la que no eran miembros.

El comportamiento anterior no es tan inusual, pero parece que Discourse no puede manejarlo correctamente si se usa como un espejo de lista de correo y mantiene separadas las respuestas bifurcadas, ya que todas estarán vinculadas al ID de mensaje original y a la categoría en la que apareció esa publicación por primera vez.

Esto podría significar que los gerentes podrían ver las publicaciones de los médicos, por ejemplo, si el médico, al responder a la lista de médicos, tuviera esa publicación que apareciera en el espejo de la lista de gerentes debido a la forma en que Discourse archiva los mensajes.

Una solución podría ser verificar cada dirección en el encabezado Para: de los mensajes entrantes para ver si coincidía con una dirección de espejo de lista de correo en cada una de las configuraciones de Categoría. Si lo hiciera, se podría publicar una copia del mensaje en cada categoría coincidente, y potencialmente podría haber varias copias de la publicación en diferentes categorías. Luego, si llegaran respuestas, el ID del mensaje podría usarse, como es el caso actualmente, pero solo si la línea Para: coincidiera también con la categoría.

¿Podría ser una solución que una opción reescriba el message-id para reflejar el id original creado por el cliente de correo del remitente más un identificador adicional, por ejemplo, la dirección To: de la lista de correo que Discourse ya busca? Esto significaría que si una publicación proviniera de la lista de correo B pero hiciera referencia a un encabezado message-id que también estuviera en una publicación de la lista de correo A, ¿Discourse la archivaría correctamente?

Por ejemplo. El correo electrónico original enviado simultáneamente a dos listas de correo A y B tiene un message-id único ‘1234567890gmail’.

Discourse recibe dos copias reenviadas a la dirección genérica de entrada de Discourse. El primer mensaje se archiva basándose en que la dirección To: es para la Lista A y Discourse agrega caracteres adicionales al message-id para que se convierta en ‘1234567890gmailListA’. El segundo mensaje no se archiva ya que parece un duplicado. (Creo que este es el comportamiento actual).

Alguien en la Lista B responde usando la dirección To: para la Lista B. Discourse recibe una copia y detecta que hay un encabezado “in reply to” que contiene ‘1234567890gmail’. Discourse, al ver que el correo electrónico entró con una línea To: que refleja la Lista B, agrega caracteres al final para que el encabezado “in reply to” parezca ‘1234567890gmailListB’. Luego procede a archivar esto como un nuevo mensaje en la categoría correcta, ya que ya no está vinculado al mensaje que se archivó contra la Lista A.

Este enfoque podría funcionar también para transferir archivos, donde el mismo message-id podría encontrarse en varias listas de correo si un usuario envió el mensaje a varias listas al mismo tiempo. En el momento de la importación, todos los campos message-id (y “in reply to”) podrían tener texto único agregado vinculado a la lista de correo con nombre para detener una especie de interferencia entre archivos cuando se indexan los mensajes.