Сессийные куки Discourse (400 Заголовок запроса или куки слишком велики)

Почему у Discourse такие большие куки? Есть ли для этого причина? Можно ли уменьшить их размер?

Я копался в админ-панели Discourse и вдруг получил ошибку 400 Bad Request от /sidekiq/retries.

400 Bad Request
Request Header Or Cookie Too Large

Я проверил запрос и, как и следовало ожидать, мой браузер отправил огромный заголовок Cookie на мой сервер Discourse. Почему?

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

Приведенная выше строка куки Discourse имеет длину 1962 символа!

Для сравнения: заголовок куки, отправляемый на мой сайт Mediawiki, имеет длину 122 символа, включая имя пользователя, идентификатор пользователя и идентификатор сеанса.

Идентификатор сеанса Mediawiki имеет длину 32 символа, но, похоже, в Discourse есть два идентификатора сеанса: rack.session имеет длину 813 символов, а _forum_session — 1075 символов. Пожалуйста, помогите мне понять, почему простой uid должен быть таким длинным. Могу ли я настроить Discourse на использование более короткого uid сеанса? Имеет ли смысл такая просьба?

Что хранится в этой строке? Можно ли сделать её меньше?

В частности, для какого компонента программного обеспечения Discourse используется rack.session? А для чего используется _forum_session?

Конечно, я могу просто увеличить лимиты конфигурации nginx, но я хотел бы держать их на разумно низком уровне, если нет строгой необходимости их увеличивать.

Я поддерживаю идею провести аудит наших сессионных cookie-файлов и, возможно, просто перейти к использованию по умолчанию нашей сессии на базе Redis с автоматическим истечением срока действия, что в любом случае лучше. @david, есть ли у вас какие-либо мысли по этому поводу?

Это не должно быть проблемой для тех, кто использует нашу официальную установку, только для людей с неправильно настроенными прокси, верно?

Кроме того, сжатие заголовков HTTP/2 позволяет загружать эти заголовки только один раз за всё посещение пользователя.

Зависит от ситуации. Плагины, которые активно используют сессии, могут пострадать. Кроме того, это вопрос гигиены: безопаснее хранить всю эту конфиденциальную информацию на сервере, а не в зашифрованном виде на клиенте.

Ой, эта настройка была сделана намеренно в целях безопасности; это не «плохо настроенный» прокси. Понижение следующих директив nginx обычно выполняется в рамках его усиления (для решения вопросов доступности, ограничения частоты запросов, защиты от DoS и т. д.):

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

Настройки, которые мы используем в нашем конфигурационном файле nginx, отлично работают на всех наших существующих сайтах. Проблема здесь, по-видимому, заключается в том, что Discourse хранит в куках ненужные данные клиента. На мой взгляд, в куках должны храниться лишь несколько уникальных идентификаторов, которые сервер может использовать для доступа к этим данным на своей стороне.

Спасибо, Сэм. Имея в виду «переход к использованию по умолчанию Redis», вы предлагаете, что сейчас можно переместить данные, хранящиеся в куке сессии, в Redis с помощью изменения конфигурации? Или перемещение этих данных из куки сессии на сервер обязательно потребует изменения кода?

Нет, требуется изменение кода.

Почему заголовки объёмом 10 КБ являются проблемой? Они сжимаются. Если заголовки в 10 КБ — это проблема, то почему разрешён HTML-пейлоад в 10 КБ?

Примечание: Мне также пришлось переопределить директиву large_client_header_buffers в моём конфигурационном файле усиленного nginx, чтобы Discourse заработал.

В частности, для всех остальных моих сайтов я использую large_client_header_buffers 2 1k в конфигурациях nginx. Однако это приводит к ошибке 414 Request-URI Too Large при обращении к /admin/reports/bulk?XYZ, где XYZ на самом деле имеет длину 1019 символов!

Проблема была решена установкой large_client_header_buffers 4 8k; в блоке server{} конфигурации nginx для Discourse, что переопределяет глобальную директиву и возвращает её к значению по умолчанию для Discourse.

Для обеспечения лучшей совместимости установок Discourse с популярными усиленными веб-серверами, сетевыми межсетевыми экранами и веб-приложениями я настоятельно рекомендую разработчикам Discourse рассмотреть возможность использования метода POST для таких длинных строк запросов.

Это очень узкий случай использования, специфичный для администратора.

Для человека, который не является бэкенд-инженером, как решить эту проблему?

В течение последнего месяца мы получаем множество сообщений об этой ошибке на форуме Webflow. Рекомендация посетителям очистить куки/кэш или использовать режим инкогнито помогает, но это не идеальный вариант.

Будем очень признательны за любые советы по исправлению этого в нашем экземпляре Discourse.

Можете привести пример? Проблема в оригинальном посте касается самостоятельного размещения Discourse, поэтому я не понимаю, как это может повлиять на размещённый экземпляр, подобный тому, на который вы дали ссылку.