CVE-2022-23837 (published 2022-01-21T21:15Z)

In api.rb in Sidekiq before 5.2.10 and 6.4.0, there is no limit on the number of days when requesting stats for the graph. This overloads the system, affecting the Web UI, and makes it unavailable to users.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-770
cwe_name: Allocation of Resources Without Limits or Throttling
description: The product allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on the size or number of resources that can be allocated, in violation of the intended security policy for that actor.
extended_description: Code frequently has to work with limited resources, so programmers must be careful to ensure that resources are not consumed too quickly, or too easily.  Without use of quotas, resource limits, or other protection mechanisms, it can be easy for an attacker to consume many resources by rapidly making many requests, or causing larger resources to be used than is needed. When too many resources are allocated, or if a single resource is too large, then it can prevent the code from working correctly, possibly leading to a denial of service.
         

Fix information:
repo_url: https://github.com/mperham/sidekiq
commit_details: repo_url: https://github.com/mperham/sidekiq
author: Mike Perham
author_date: 2022-01-20 10:42:26-08:00
msg: Validate `days` parameter to avoid possible DoS in Web UI

Thank you to Sergey Shpakov of http://tutum.space for reporting.
repository: repo_url: https://github.com/mperham/sidekiq
repo_name: sidekiq/sidekiq
description: Simple, efficient background processing for Ruby
repo_language: Ruby
owner: mperham
file_changes: filename: api.rb
change_type: ModificationType.MODIFY
diff: @@ -161,6 +161,8 @@ module Sidekiq
 
     class History
       def initialize(days_previous, start_date = nil)
+        # we only store five years of data in Redis
+        raise ArgumentError if days_previous < 1 || days_previous > (5 * 365)
         @days_previous = days_previous
         @start_date = start_date || Time.now.utc.to_date
       end

programming_language: Ruby
filename: application.rb
change_type: ModificationType.MODIFY
diff: @@ -50,7 +50,10 @@ module Sidekiq
 
     get "/" do
       @redis_info = redis_info.select { |k, v| REDIS_KEYS.include? k }
-      stats_history = Sidekiq::Stats::History.new((params["days"] || 30).to_i)
+      days = (params["days"] || 30).to_i
+      return halt(401) if days < 1 || days > 180
+
+      stats_history = Sidekiq::Stats::History.new(days)
       @processed_history = stats_history.processed
       @failed_history = stats_history.failed
 

programming_language: Ruby
filename: test_api.rb
change_type: ModificationType.MODIFY
diff: @@ -156,6 +156,15 @@ describe 'API' do
         Time::DATE_FORMATS[:default] = @before
       end
 
+      describe "history" do
+        it "does not allow invalid input" do
+          assert_raises(ArgumentError) { Sidekiq::Stats::History.new(-1) }
+          assert_raises(ArgumentError) { Sidekiq::Stats::History.new(0) }
+          assert_raises(ArgumentError) { Sidekiq::Stats::History.new(2000) }
+          assert Sidekiq::Stats::History.new(200)
+        end
+      end
+
       describe "processed" do
         it 'retrieves hash of dates' do
           Sidekiq.redis do |c|

programming_language: Ruby
filename: test_web.rb
change_type: ModificationType.MODIFY
diff: @@ -748,8 +748,9 @@ describe Sidekiq::Web do
       basic_authorize 'a', 'b'
 
       get '/'
-
       assert_equal 200, last_response.status
+      get '/?days=1000000'
+      assert_equal 401, last_response.status
     end
   end
 

programming_language: Ruby