Cookies de sesión de Discourse (400 Solicitud de encabezado o cookie demasiado grande)

¿Por qué Discourse tiene cookies tan grandes? ¿Hay alguna razón para ello? ¿Existe alguna forma de reducir su tamaño?

Estaba explorando el panel de administración de Discourse y, de repente, recibí un error 400 Bad Request desde /sidekiq/retries:

400 Bad Request
Request Header Or Cookie Too Large

Verifiqué la solicitud y, efectivamente, mi navegador envió una cabecera de Cookie enorme a mi servidor de Discourse. ¿Por qué?

Cookie: _t=403b8203003bdaf522679e0b6c17605f; rack.session=BAh7C0kiD3Nlc3Npb25faWQGOgZFVG86HVJhY2s6OlNlc3Npb246OlNlc3Np%0Ab25JZAY6D0BwdWJsaWNfaWRJIkU4NjY1Y2Y3MjU4OGYzZjk3MDUyMDdhNzhh%0ANzc4OGZlZTRhNzFkY2JjMzA4NDAyNjY3MWMwNmFhYzc2Zjg0NWIyBjsARkki%0AEF9jc3JmX3Rva2VuBjsARkkiMW9KNk83S1B5ZUVaR0I2WnBxckxISzNxbEla%0AdGRyVXNCUnc3d2JiaVorVmM9BjsARkkiFnNlY3VyZV9zZXNzaW9uX2lkBjsA%0AVEkiJWM3YWJjYTk3OTRlNTExNTllZWUyMTBkYmVkNDgzNDc4BjsARkkiCmZs%0AYXNoBjsAVHsHSSIMZGlzY2FyZAY7AFRbAEkiDGZsYXNoZXMGOwBUewZJIgxy%0AZWZlcmVyBjsAVCJPaHR0cHM6Ly9kaXNjb3Vyc2Uub3BlbnNvdXJjZWVjb2xv%0AZ3kub3JnL3UvbWFsdGZpZWxkMC9tZXNzYWdlcy9ncm91cC9hZG1pbnNJIglj%0Ac3JmBjsARkkiMVRuUHJ6TTMzUHZqcG9oditwdTRyem9HeDUxQnAwL0psci9z%0AYkFZWkpxdkU9BjsARkkiDXRyYWNraW5nBjsARnsGSSIUSFRUUF9VU0VSX0FH%0ARU5UBjsAVEkiLTk3MDJkMjYxMmJlZmM5N2U4YTIzMDVkNjU0Y2IwOThmMmQ4%0AYTI1NTUGOwBG%0A--e602081dddcd88bdb269034e7acb8c582665be0e; _forum_session=V2dWY0FGVGhsMDVtcmdmNVdicXpJVkxnVC9vUWpkeVdpSHRIYWZaVVhVZDUxcFlRdTh4bHFTQVRRcUpGR3pMRGZ1M3NGeENzUloreGdEWEtQS2Z2WDJKNFZUeXRjNXlTTTRHVzJsQzBORzVuSW9NNHg3UHhwNzdUNFlCNGVvcytkSjA1b0d3NlM3czNlTlFxMEloQmNOYzMxTm5mYW4zaWlMSkpxWXZiZDlBRFJnR3dxTkphM0ZtZmk4bGswcUdzYm94b3pkUk0zTG5sMjhqNkxYMnZqMjJPYkhzMGFLM2JWZzBCRXpFa2wyZm1HbUl3REVzd3c5MmhRMG5YMkFJV0t6Z2ZPRlI2bVpOQWJlZWJQd2pyclEvdmVmWUlsYkxyU0EzcDFaZkRpOU14SVptMk01TjZtZlNXa2VUQnFaaGZpNDlaQVBnY0RCS2ZlbVBiQWt3S2lSeHcvY0g2WUlXOTRLejh2dVhhcDFoRXVobUdRMnJvcjhtRTkxZjZCYXM1eDd2NU1rZ3duRy83VVhVSG5Ua3BIOTJoQ1orY2dlMjh2M0Fuc0lwb3p3ckVtaXhxaDkxT2E1YnEvbnBWTVlCaXd4Q2h6eTd5Ty84WUYzeUVFbE9KSXhadXZ4aUw1TmVoSEE0cW9YSHA3VTJoK3NtdktrL09qcDVxMnR5bFhhUmU1dDMzT0ZBUGxBRXBZVHB5WlNtODM2YzBsOVRkc3RpMmFFSW5COEhyRjFTY2ZCZk5VbUpYN2JzYlh6SGNGWEs2dWhQUkJnMmd4K3ZJQUFkQThwa2tOMnI3Vi9qMFo5RE5XWWxxRXFTTTNmRnJKU294aStKZFJ4NHRDTGh4WXR1Z3F5QWU3ZkMxTXBpMzcvYTd5QkRwajNjcDF6SWdFSkdqNDJlMk0vYW1mODNEdDhZSk9jbzRPRHNhZUYzNjVOWkErbVJSNG82VnhRL0FFRUtWbE1uQWFPa0JqQUFmZ21iL0YvSFIrM1dlSDNvPS0tK1pMRzNmRjA4L3c4VTkrVEllYmNQZz09--325ca2e886afaefffeb6174c99776f91fefd4292

¡La cadena de cookies de Discourse anterior tiene 1.962 caracteres de longitud!

Para comparar, la cabecera de cookies enviada a mi sitio de MediaWiki tiene solo 122 caracteres, incluyendo mi nombre de usuario, ID de usuario e ID de sesión.

El ID de sesión de MediaWiki tiene 32 caracteres de longitud, pero Discourse parece tener dos IDs de sesión: rack.session tiene 813 caracteres y _forum_session tiene 1.075 caracteres. Por favor, ayúdame a entender por qué un simple uid necesita ser tan largo. ¿Puedo configurar Discourse para que utilice un uid de sesión más corto? ¿Tiene sentido tal solicitud?

¿Qué se almacena en esa cadena? ¿Es posible hacerla más pequeña?

Específicamente, ¿para qué componente del software de Discourse se utiliza rack.session? ¿Y para qué se utiliza _forum_session?

Por supuesto, puedo simplemente aumentar los límites de configuración de nginx, pero me gustaría mantenerlos razonablemente bajos a menos que haya una necesidad imperiosa de aumentarlos.

Apoyo la auditoría de nuestras cookies de sesión y quizás simplemente pasar a usar por defecto nuestra sesión respaldada por Redis que expira automáticamente, lo cual es mejor de todos modos. @david, ¿tienes alguna opinión al respecto?

Esto no debería ser un problema para alguien que usa nuestra instalación oficial, solo para personas con proxies mal configurados, ¿verdad?

Además, la compresión de encabezados HTTP/2 hace que estos encabezados se carguen solo una vez durante toda la visita del usuario.

Depende. Los plugins que hacen un uso intensivo de sesiones pueden verse afectados; además, es una cuestión de higiene: es mejor mantener toda esta información confidencial en el servidor en lugar de tenerla cifrada en el cliente.

¡Vaya! Esta configuración se realizó intencionalmente por razones de seguridad; no se trata de un proxy “mal configurado”. Ajustar a la baja las siguientes directivas de nginx es una práctica común al endurecer la configuración de nginx (para abordar la disponibilidad, la limitación de tasa, ataques de denegación de servicio, etc.):

limit_conn_zone
limit_conn
limit_req_zone
client_body_timeout
client_header_timeout
ssl_*
add_header # SAMEORIGIN/XSS-Protection/CORS/CSP
client_body_buffer_size
client_header_buffer_size
large_client_header_buffers
client_max_body_size

Los ajustes que utilizamos en nuestra configuración de nginx funcionan perfectamente en todos nuestros sitios existentes. El problema aquí parece ser que Discourse almacena datos innecesarios del cliente en la cookie, cuando en mi opinión lo único que debería almacenarse en la cookie son unos pocos identificadores únicos que el servidor pueda utilizar para acceder a esos datos del lado del servidor.

Gracias, Sam. ¿Al decir “pasar a usar por defecto Redis” estás sugiriendo que actualmente es posible mover los datos almacenados en la cookie de sesión a Redis mediante un cambio de configuración? ¿O mover estos datos fuera de la cookie de sesión al servidor requeriría necesariamente un cambio en el código?

No, requiere un cambio en el código.

¿Por qué un tamaño de 10k de encabezados es un problema? Están comprimidos; si 10k de encabezados es un problema, ¿por qué se permite una carga útil HTML de 10k?

Nota: También he tenido que sobrescribir la directiva large_client_header_buffers de mi configuración endurecida de nginx para que Discourse funcione.

Específicamente, uso large_client_header_buffers 2 1k en las configuraciones de nginx de todos mis otros sitios. Sin embargo, esto provoca un error 414 Request-URI Too Large desde /admin/reports/bulk?XYZ, donde XYZ tiene en realidad 1.019 caracteres de longitud.

Esto se solucionó estableciendo large_client_header_buffers 4 8k; en el bloque server{} de la configuración de nginx de Discourse, lo que sobrescribe la directiva global y restaura la directiva a su valor predeterminado para Discourse.

Para mejorar la interoperabilidad de las instalaciones de Discourse a través de servidores web endurecidos populares, firewalls de red y firewalls de aplicaciones web, insto a los desarrolladores de Discourse a considerar el uso de POST para cadenas de consulta tan largas.

Ese es un caso de uso muy, muy específico… propio de la administración.

Para alguien que no es un ingeniero backend, ¿cuál es la solución para esto?

Hemos recibido muchos informes de este error durante el último mes en el foro de Webflow. Recomendar a los visitantes que borren sus cookies/caché o que usen el modo incógnito ha funcionado, pero no es ideal.

Agradeceríamos cualquier consejo sobre cómo solucionar esto para nuestra instancia de Discourse.

¿Puedes enlazar un ejemplo? Este problema en OP trata sobre el autoalojamiento de Discourse, así que no entiendo cómo puede afectar a una instancia alojada como la que has enlazado.