Cookies de session Discourse (400 En-tête de requête ou cookie trop volumineux)

Pourquoi Discourse utilise-t-il de si gros cookies ? Y a-t-il une raison à cela ? Existe-t-il un moyen de réduire leur taille ?

Je fouillais dans le tableau de bord d’administration de Discourse, et soudain, j’ai reçu une erreur 400 Bad Request depuis /sidekiq/retries :

400 Bad Request
Request Header Or Cookie Too Large

J’ai vérifié la requête et, effectivement, mon navigateur a envoyé un en-tête Cookie énorme à mon serveur Discourse. Pourquoi ?

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 chaîne de cookie Discourse ci-dessus fait 1 962 caractères de long !

À titre de comparaison, l’en-tête de cookie envoyé à mon site Mediawiki ne fait que 122 caractères, y compris mon nom d’utilisateur, mon identifiant utilisateur et mon identifiant de session.

L’identifiant de session Mediawiki fait 32 caractères, mais Discourse semble utiliser deux identifiants de session : rack.session fait 813 caractères et _forum_session en fait 1 075. Pouvez-vous m’aider à comprendre pourquoi un simple uid doit être si long ? Puis-je configurer Discourse pour qu’il utilise un uid de session plus court ? Une telle demande a-t-elle du sens ?

Que contient cette chaîne ? Est-il possible de la rendre plus petite ?

Plus précisément, à quoi sert rack.session dans le logiciel Discourse ? Et à quoi sert _forum_session ?

Bien sûr, je pourrais simplement augmenter les limites de la configuration nginx, mais je préférerais les maintenir raisonnablement basses sauf s’il existe une forte nécessité de les augmenter.

Je soutiens l’audit de nos cookies de session et peut-être simplement passer par défaut à notre session basée sur Redis qui expire automatiquement, ce qui est de toute façon mieux. @david, qu’en penses-tu ?

Cela ne devrait pas poser de problème pour quelqu’un qui utilise notre installation officielle, seulement pour les personnes utilisant des proxies mal configurés, n’est-ce pas ?

De plus, la compression d’en-têtes HTTP/2 permet de ne transmettre ces en-têtes qu’une seule fois lors de toute la visite de l’utilisateur.

Cela dépend. Les plugins qui utilisent beaucoup les sessions peuvent être affectés. C’est aussi une question d’hygiène : il est préférable de garder toutes ces informations confidentielles sur le serveur plutôt que chiffrées côté client.

Ouh là, ce réglage a été effectué intentionnellement pour des raisons de sécurité ; il ne s’agit pas d’un proxy « mal configuré ». Réduire les directives nginx suivantes est une pratique courante dans le cadre du durcissement de nginx (pour gérer la disponibilité, la limitation du débit, les attaques DDoS, 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

Les paramètres que nous utilisons dans notre configuration nginx fonctionnent parfaitement sur tous nos sites existants. Le problème ici semble être que Discourse stocke des données client inutiles dans le cookie, alors que, selon moi, le cookie ne devrait contenir que quelques identifiants uniques permettant au serveur d’accéder à ces données côté serveur.

Merci Sam. En parlant de « passer par défaut à l’utilisation de Redis », suggères-tu qu’il est actuellement possible de déplacer les données stockées dans le cookie de session vers Redis via un changement de configuration ? Ou bien le déplacement de ces données hors du cookie de session vers le serveur nécessiterait-il nécessairement une modification du code ?

Non, cela nécessite une modification du code.

Pourquoi 10 ko d’en-têtes poseraient-ils problème ? Ils sont compressés. Si 10 ko d’en-têtes posent problème, pourquoi un payload HTML de 10 ko est-il autorisé ?

Remarque : J’ai également dû remplacer la directive large_client_header_buffers de ma configuration nginx renforcée pour que Discourse fonctionne.

Plus précisément, j’utilise large_client_header_buffers 2 1k pour les configurations nginx de tous mes autres sites. Cela provoque cependant une erreur 414 Request-URI Too Large depuis /admin/reports/bulk?XYZ — où XYZ fait en réalité 1 019 caractères de long !

Cela a été résolu en définissant large_client_header_buffers 4 8k; dans le bloc server{} de la configuration nginx de Discourse, ce qui remplace la directive globale et rétablit la valeur par défaut de la directive pour Discourse.

Pour une meilleure interopérabilité des installations de Discourse via des serveurs web populaires renforcés, des pare-feu réseau et des pare-feu d’applications web, j’invite les développeurs de Discourse à envisager l’utilisation de POST pour de telles chaînes de requête longues.

C’est un cas d’usage très, très spécifique, propre à l’administration.

Pour quelqu’un qui n’est pas un ingénieur backend, quelle est la solution ?

Nous recevons de nombreux rapports de cette erreur au cours du dernier mois sur le forum Webflow. Recommander à un visiteur de vider ses cookies/son cache ou d’utiliser le mode incognito a fonctionné, mais ce n’est pas idéal.

Tout conseil pour résoudre ce problème pour notre instance de Discourse serait très apprécié.

Pouvez-vous fournir un lien vers un exemple ? Ce problème dans le message initial concerne l’auto-hébergement de Discourse, donc je ne comprends pas comment il pourrait affecter une instance hébergée comme celle que vous avez liée.