Headline
CVE-2023-38498: SECURITY: Don't allow a particular site to monopolize the defer queue · discourse/discourse@26e2674
Discourse is an open source discussion platform. Prior to version 3.0.6 of the stable
branch and version 3.1.0.beta7 of the beta
and tests-passed
branches, a malicious user can prevent the defer queue from proceeding promptly on sites hosted in the same multisite installation. The issue is patched in version 3.0.6 of the stable
branch and version 3.1.0.beta7 of the beta
and tests-passed
branches. There are no known workarounds for this vulnerability. Users of multisite configurations should upgrade.
Expand Up
@@ -8,7 +8,11 @@ module Deferrable
def initialize
@async = !Rails.env.test?
@queue = Queue.new
@queue =
WorkQueue::ThreadSafeWrapper.new(
WorkQueue::FairQueue.new(500) { WorkQueue::BoundedQueue.new(10) },
)
@mutex = Mutex.new
@stats_mutex = Mutex.new
@paused = false
Expand All
@@ -23,7 +27,7 @@ def timeout=(t)
end
def length
@queue.length
@queue.size
end
def stats
Expand All
@@ -44,15 +48,15 @@ def async=(val)
@async = val
end
def later(desc = nil, db = RailsMultisite::ConnectionManagement.current_db, &blk)
def later(desc = nil, db = RailsMultisite::ConnectionManagement.current_db, force: true, &blk)
@stats_mutex.synchronize do
stats = (@stats[desc] ||= { queued: 0, finished: 0, duration: 0, errors: 0 })
stats[:queued] += 1
end
if @async
start_thread if !@thread&.alive? && !@paused
@queue << [db, blk, desc]
@queue.push({ key: db, task: [db, blk, desc] }, force: force)
else
blk.call
end
Expand All
@@ -71,7 +75,7 @@ def stopped?
end
def do_all_work
do_work(_non_block = true) while [email protected]?
do_work(non_block = true) while [email protected]?
end
private
Expand All
@@ -89,7 +93,8 @@ def start_thread
# using non_block to match Ruby #deq
def do_work(non_block = false)
db, job, desc = @queue.deq(non_block)
db, job, desc = @queue.shift(block: !non_block)[:task]
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
db ||= RailsMultisite::ConnectionManagement::DEFAULT
Expand Down