Cookie di sessione di Discourse (400 Request Header Or Cookie Too Large)

Perché Discourse ha cookie così grandi? C’è una ragione? Esiste un modo per ridurne le dimensioni?

Sto esplorando la dashboard di amministrazione di Discourse e improvvisamente ho ricevuto un errore 400 Bad Request da /sidekiq/retries:

400 Bad Request
Request Header Or Cookie Too Large

Ho controllato la richiesta e, come previsto, il mio browser ha inviato un header Cookie enorme al server Discourse. Perché?

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 stringa del cookie Discourse sopra riportata è lunga 1.962 caratteri!

A titolo di confronto, l’header cookie inviato al mio sito Mediawiki è lungo 122 caratteri, inclusi nome utente, ID utente e ID sessione.

L’ID sessione di Mediawiki è lungo 32 caratteri, ma Discourse sembra avere due ID sessione: rack.session è lungo 813 caratteri e _forum_session è lungo 1.075 caratteri. Potete aiutarmi a capire perché un semplice uid debba essere così lungo? Posso configurare Discourse per utilizzare un uid di sessione più breve? Ha senso una richiesta del genere?

Cosa viene memorizzato in quella stringa? È possibile ridurne le dimensioni?

Nello specifico, a quale componente del software Discourse serve rack.session? E a cosa serve _forum_session?

Certo, potrei semplicemente aumentare i limiti di configurazione di nginx, ma preferirei mantenerli ragionevolmente bassi a meno che non ci sia una forte necessità di aumentarli.

Supporto l’audit dei nostri cookie di sessione e, forse, il passaggio all’uso predefinito della nostra sessione basata su Redis, che scade automaticamente ed è comunque migliore. @david, hai qualche opinione al riguardo?

Questo non dovrebbe essere un problema per chi utilizza la nostra installazione ufficiale, ma solo per chi usa proxy mal configurati, giusto?

Inoltre, la compressione degli header HTTP/2 fa sì che questi vengano inviati una sola volta durante l’intera visita dell’utente.

Dipende: i plugin che fanno un uso intensivo delle sessioni possono risentirne. È anche una questione di igiene: è meglio mantenere tutte queste informazioni riservate sul server invece che crittografate sul client.

Oh no, questa ottimizzazione è stata fatta intenzionalmente per motivi di sicurezza; non si tratta di un proxy “mal configurato”. Ridurre i seguenti direttive di nginx è una pratica comune per il loro hardening (per affrontare problemi di disponibilità, limitazione della frequenza, attacchi DOS, ecc.):

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

Le impostazioni che utilizziamo nella nostra configurazione di nginx funzionano perfettamente su tutti i nostri siti esistenti. Il problema qui sembra essere che Discourse memorizza dati client non necessari nel cookie, mentre a mio avviso l’unico dato che dovrebbe essere memorizzato nel cookie sono pochi identificatori univoci che il server può utilizzare per accedere a tali dati lato server.

Grazie, Sam. Con “passare all’uso predefinito di Redis” intendi suggerire che attualmente è possibile spostare i dati memorizzati nel cookie di sessione su Redis tramite una modifica alla configurazione? Oppure spostare questi dati dal cookie di sessione al server richiederebbe necessariamente una modifica al codice?

No, è necessaria una modifica del codice

Perché 10k di intestazioni rappresentano un problema? Sono compresse; se 10k di intestazioni sono un problema, perché è consentito un payload HTML di 10k?

Nota: Ho anche dovuto sovrascrivere la direttiva large_client_header_buffers nella mia configurazione nginx hardened per far funzionare Discourse.

Nello specifico, per tutte le altre configurazioni nginx dei miei siti utilizzo large_client_header_buffers 2 1k. Tuttavia, questo causa un errore 414 Request-URI Too Large da /admin/reports/bulk?XYZ, dove XYZ è in realtà lungo 1.019 caratteri!

Il problema è stato risolto impostando large_client_header_buffers 4 8k; nel blocco server{} della configurazione nginx di Discourse, che sovrascrive la direttiva globale e ripristina il valore predefinito per Discourse.

Per migliorare l’interoperabilità delle installazioni di Discourse attraverso server web hardened popolari, firewall di rete e firewall per applicazioni web, esorto gli sviluppatori di Discourse a valutare l’uso del metodo POST per query string così lunghe.

È un caso d’uso estremamente limitato, specifico per gli amministratori.

Per qualcuno che non è un ingegnere backend, qual è la soluzione?

Stiamo ricevendo molte segnalazioni di questo errore nell’ultimo mese sul forum di Webflow. Consigliare a un visitatore di cancellare i cookie/la cache o di utilizzare la modalità di navigazione in incognito ha funzionato, ma non è l’ideale.

Qualsiasi consiglio per risolvere questo problema per la nostra istanza di Discourse sarebbe molto apprezzato.

Puoi fornire un link a un esempio? Il problema nell’OP riguarda l’auto-hosting di Discourse, quindi non capisco come possa influire su un’istanza ospitata come quella che hai linkato.