FIX: Validate user note length against max_post_length (#42240)

Previously, staff could persist user notes longer than the configured
maximum post length, which could consume excessive client resources when
rendered.

This change rejects user notes longer than `SiteSetting.max_post_length`
before persistence.

Relates to https://patch.discourse.org/patch-triage/1360
This commit is contained in:
Gabriel Grubba
2026-07-31 16:19:10 -03:00
committed by GitHub
parent be1c355de1
commit 099285da70
3 changed files with 31 additions and 2 deletions
@@ -15,6 +15,13 @@ module DiscourseUserNotes
end
def create
raw = params[:user_note][:raw]
if raw.to_s.length > SiteSetting.max_post_length
return(
render_json_error(I18n.t("user_notes.note_too_long", max: SiteSetting.max_post_length))
)
end
user = User.where(id: params[:user_note][:user_id]).first
raise Discourse::NotFound if user.blank?
extras = {}
@@ -26,8 +33,7 @@ module DiscourseUserNotes
extras[:reviewable_id] = reviewable_id
end
user_note =
DiscourseUserNotes.add_note(user, params[:user_note][:raw], current_user.id, extras)
user_note = DiscourseUserNotes.add_note(user, raw, current_user.id, extras)
render json: create_json(user_note)
end
@@ -6,6 +6,7 @@ en:
user_notes:
official_warning: "Received an official warning from @%{username} -- %{warning_link}"
note_too_long: "User note must be %{max} characters or fewer."
user_suspended: "@%{username} suspended this account until %{suspended_till}. Reason: %{reason}"
user_silenced: "@%{username} silenced this account until %{silenced_till}. Reason: %{reason}"
@@ -10,6 +10,28 @@ describe DiscourseUserNotes::UserNotesController do
before { SiteSetting.user_notes_enabled = true }
describe "#create" do
it "rejects notes longer than the maximum post length" do
SiteSetting.max_post_length = 10
sign_in(moderator)
post "/user_notes",
params: {
user_note: {
user_id: user.id,
raw: "a" * 11,
},
},
headers: {
"ACCEPT" => "application/json",
}
expect(response.status).to eq(422)
expect(response.parsed_body["errors"]).to contain_exactly(
I18n.t("user_notes.note_too_long", max: SiteSetting.max_post_length),
)
expect(DiscourseUserNotes.notes_for(user.id)).to be_empty
end
context "when post_id references a PM the moderator cannot see" do
fab!(:pm_topic) do
Fabricate(