Skip to content

Instantly share code, notes, and snippets.

@keeganparr1
Last active September 15, 2023 07:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keeganparr1/1dffd3c017339b7ed5371ed3d81e6b2a to your computer and use it in GitHub Desktop.
Save keeganparr1/1dffd3c017339b7ed5371ed3d81e6b2a to your computer and use it in GitHub Desktop.
Sidekiq DoS
When testing Sidekiq version 6.5.8 and reviewing the code for the current main release on their Github, the same functionality exists, which should indicate the newest version is vulnerable as well.
In the version 6.x of their codebase the vulnerability is on line 6 of https://github.com/sidekiq/sidekiq/blob/6-x/web/assets/javascripts/dashboard.js:
var timeInterval = parseInt(localStorage.sidekiqTimeInterval) || 5000;
If you look at the latest release in MAIN on line 60 in https://github.com/sidekiq/sidekiq/blob/main/web/assets/javascripts/dashboard-charts.js the localStorage.sidekiqTimeInterval is parsed using parseInt and set as the delay:
this.delay = parseInt(localStorage.sidekiqTimeInterval) || 5000;
this.startPolling();
document.addEventListener("interval:update", this.handleUpdate.bind(this));
This is then used on line 68 to set the polling interval:
this._interval = setInterval(this.poll.bind(this), this.delay);
When inserting values such as 1 here it correlates to 1000 polling requests a second (by default if nothing is set it is set to a value of 5000 which is 5000 milliseconds/5 seconds). The localstorage value sidekiqTimeInterval is not sanitized user input which causes a Denial of Service if a value such as "1", is used. The heavy traffic from the polling makes the site unusable and can potentially bring the site and server down.
The front end HTML input type="range" code for the app sets maximum and minimum values, but the local storage value being used doesn't get validated in the back end code to prevent abuse. For example, see line 18 https://github.com/sidekiq/sidekiq/blob/main/web/views/dashboard.erb:
<input id="sldr" type="range" min="2000" max="20000" step="1000" value="5000"/>
The "attacking" POC payload entered into the local storage value is "1". This is entered by loading the main/default Sidekiq page dashboard, opening developer tools in the browser, going to Memory-->Local Storage and changing the only local storage value there is to "1". Reload/refresh the page and then the site tries to load and freezes uncontrollably because of the 1000 polling requests a second
This vulnerability impacts the availability of the entire site using Sidekiq. The value that is not sanitized user input is in local storage, not the cookie. If cross-site scripting is found anywhere in the application an attacker can run JavaScript to pull or insert values in the local storage value, causing the Denial of Service. In my testing, I'm seeing at minimum hundreds/thousands of requests per second.
This specific instance of Sidekiq is running on an enterprise grade server that can take thousands of requests a second. Also, I'm not entirely sure what would happen if multiple users that had access to the dashboard performed the POC payload in the localstorage value. My guess is the attack would be amplified by 1000 requests a second per user.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment