mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-06-13 21:22:50 +08:00
## Summary Reports have surfaced of posts that lock up or crash browsers when their topic loads, even though the raw is well within `max_post_length`. The trigger is many `[quote=...]` BBCode openers per post — typically unbalanced with the matching `[/quote]` closers. When the BBCode block rule can't pair them up, each opener falls through to inline parsing and cooks into its own `<p>[quote=...]</p>` paragraph. Posts with hundreds to thousands of these paragraphs are cheap to author but expensive to render: thousands of DOM nodes, per-post decoration passes (quote-back links, MutationObservers, oneboxer, etc.) running once per fragment, and post-level event handlers all compound. Examples in the wild have raws of 11–47 KB containing 220–880 `[quote=` openers, cooking into 25–100 KB of near-identical paragraphs. None of these come close to `max_post_length`, so the existing length validator never fires. This adds a `max_quotes_per_post` site setting (default `50`, set to `0` to disable). `PostValidator` rejects any post whose raw contains more `[quote=` / `[quote]` openers than the limit. ## Notes - The default of 50 is well above any realistic legitimate use (deeply nested quote-replies in practice top out around 5–10 levels). The four observed offender posts contain 220, 220, 660, and 880 `[quote=` openers — all rejected at the default. - Counts openers only (`[quote=` and `[quote]`, case-insensitive), not balanced pairs. The DoS comes from openers; closers are cheap. - Existing offending posts on affected sites still need to be deleted/rebaked manually — this only stops new ones. ## Test plan - [x] `bin/rspec spec/lib/validators/post_validator_spec.rb` — all 53 examples pass, including 6 new cases covering: over-limit, at-limit, unbalanced openers, plain `[quote]`, case-insensitivity, and disable-via-zero. - [ ] Manually try to submit a post with 51+ `[quote=...]` lines via the composer and confirm the error message. - [ ] Try the same via the API. - [ ] Confirm legitimate "Quote Reply" workflows (a handful of nested quotes) still work. |
||
|---|---|---|
| .. | ||
| allow_user_locale_enabled_validator.rb | ||
| allowed_iframes_validator.rb | ||
| allowed_ip_address_validator.rb | ||
| alternative_reply_by_email_addresses_validator.rb | ||
| at_least_one_group_validator.rb | ||
| categories_topics_validator.rb | ||
| category_search_priority_weights_validator.rb | ||
| censored_words_validator.rb | ||
| color_list_validator.rb | ||
| content_localization_locales_validator.rb | ||
| csp_script_src_validator.rb | ||
| css_color_validator.rb | ||
| css_color_with_blank_validator.rb | ||
| datetime_setting_validator.rb | ||
| default_composer_category_validator.rb | ||
| delete_rejected_email_after_days_validator.rb | ||
| email_address_validator.rb | ||
| email_setting_validator.rb | ||
| email_validator.rb | ||
| enable_discourse_id_validator.rb | ||
| enable_local_logins_via_email_validator.rb | ||
| enable_private_email_messages_validator.rb | ||
| enable_sso_validator.rb | ||
| external_system_avatars_validator.rb | ||
| form_template_yaml_validator.rb | ||
| google_oauth2_hd_groups_validator.rb | ||
| group_setting_validator.rb | ||
| host_list_setting_validator.rb | ||
| integer_setting_validator.rb | ||
| ip_address_format_validator.rb | ||
| language_switcher_setting_validator.rb | ||
| linkedin_oidc_credentials_validator.rb | ||
| markdown_linkify_tlds_validator.rb | ||
| markdown_typographer_quotation_marks_validator.rb | ||
| max_emojis_validator.rb | ||
| max_username_length_validator.rb | ||
| mediaconvert_output_subdirectory_validator.rb | ||
| min_username_length_validator.rb | ||
| not_username_validator.rb | ||
| objects_setting_validator.rb | ||
| password_validator.rb | ||
| pop3_polling_enabled_setting_validator.rb | ||
| post_validator.rb | ||
| quality_title_validator.rb | ||
| regex_presence_validator.rb | ||
| regex_setting_validation.rb | ||
| regex_setting_validator.rb | ||
| regexp_list_validator.rb | ||
| reply_by_email_address_validator.rb | ||
| reply_by_email_enabled_validator.rb | ||
| search_ranking_weights_validator.rb | ||
| search_tokenize_chinese_validator.rb | ||
| search_tokenize_japanese_validator.rb | ||
| selectable_avatars_mode_validator.rb | ||
| sso_overrides_email_validator.rb | ||
| string_setting_validator.rb | ||
| stripped_length_validator.rb | ||
| timezone_validator.rb | ||
| topic_setting_validator.rb | ||
| topic_title_length_validator.rb | ||
| unicode_username_allowlist_validator.rb | ||
| unicode_username_validator.rb | ||
| unique_among_validator.rb | ||
| upload_setting_validator.rb | ||
| upload_validator.rb | ||
| url_validator.rb | ||
| user_full_name_validator.rb | ||
| user_password_validator.rb | ||
| username_setting_validator.rb | ||
| video_conversion_enabled_validator.rb | ||
| watched_words_validator.rb | ||