SECURITY: prevents arbitrary method call from input (#123)

This commit is contained in:
Joffrey JAFFEUX 2021-04-27 15:58:58 +02:00 committed by GitHub
parent d6bee1fcb5
commit 227080a2da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 4 deletions

View File

@ -51,9 +51,12 @@ class MoveDataToEventDates < ActiveRecord::Migration[6.0]
return [] if event.reminders.blank?
event.reminders.split(",").map do |reminder|
value, unit = reminder.split('.')
date = event.original_starts_at - value.to_i.send(unit)
allowed = ["years", "months", "weeks", "days", "hours", "minutes", "seconds"]
next if !allowed.include?(unit)
date = event.original_starts_at - value.to_i.public_send(unit)
{ description: reminder, date: date }
end.select { |reminder| reminder[:date] <= Time.current }.sort_by { |reminder| reminder[:date] }
end.compact.select { |reminder| reminder[:date] <= Time.current }.sort_by { |reminder| reminder[:date] }
end
def up

View File

@ -46,9 +46,18 @@ module Jobs
return [] if event_date.event.reminders.blank?
event_date.event.reminders.split(",").map do |reminder|
value, unit = reminder.split('.')
date = event_date.starts_at - value.to_i.send(unit)
next if !validate_reminder_unit(unit)
date = event_date.starts_at - value.to_i.public_send(unit)
{ description: reminder, date: date }
end.select { |reminder| reminder[:date] <= Time.current }.sort_by { |reminder| reminder[:date] }.drop(event_date.reminder_counter)
end.compact.select { |reminder| reminder[:date] <= Time.current }.sort_by { |reminder| reminder[:date] }.drop(event_date.reminder_counter)
end
private
def validate_reminder_unit(input)
ActiveSupport::Duration::PARTS.any? { |part| part.to_s == input }
end
end
end

View File

@ -97,4 +97,34 @@ describe DiscourseCalendar::MonitorEventDates do
expect(events).to include(event_name: :discourse_post_event_event_ended, params: [past_event])
end
end
context '#due_reminders' do
fab!(:invalid_event) {
Fabricate(
:event,
post: Fabricate(:post),
original_starts_at: 7.days.after,
original_ends_at: 7.days.after + 1.hour,
reminders: "1.foo"
)
}
fab!(:valid_event) {
Fabricate(
:event,
post: Fabricate(:post),
original_starts_at: 7.days.after,
original_ends_at: 7.days.after + 1.hour,
reminders: "1.minutes"
)
}
it 'doesnt list events with invalid reminders' do
freeze_time (7.days.after - 1.minutes)
event_dates_monitor = DiscourseCalendar::MonitorEventDates.new
expect(event_dates_monitor.due_reminders(invalid_event.event_dates.first)).to be_blank
expect(event_dates_monitor.due_reminders(valid_event.event_dates.first).length).to eq(1)
end
end
end