Cloudanix VulnDB

CVE-2025-61770

High · 7.5

Rack's unbounded multipart preamble buffering enables DoS (memory exhaustion)

CVSS

7.5

EPSS

0.9%

Published

Oct 7, 2025

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

Attackers can send specially oversized form-upload requests that may cause affected web applications to run out of memory and become unavailable.

Exploitation
Remote Unauthenticated
Attacker needs
None
Complexity
Low
Impact
Denial Of Service
Component
Library
Class
Denial of service
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

Rack's multipart parser buffers all bytes that appear before the first multipart boundary, known as the multipart preamble, into process memory without enforcing a size limit. An unauthenticated client can send an HTTP request with Content-Type: multipart/form-data, include a very large preamble, and then eventually provide a valid boundary so the request remains syntactically acceptable. Because the preamble is accumulated in memory, each malicious request can drive excessive heap growth in the Ruby/Rack application process, causing garbage-collection pressure, latency spikes, worker crashes, or operating-system out-of-memory termination. The impact is denial of service rather than code execution or data compromise.

Why it matters to the business

Public-facing applications that accept multipart form uploads through affected Rack code can be made slow or unavailable with comparatively simple HTTP traffic. The likely consequences are service disruption, failed uploads or form submissions, elevated infrastructure costs from memory exhaustion and autoscaling, increased error rates, and possible cascading outages if application workers are repeatedly killed and restarted. The issue is not listed in CISA KEV, is not known to be used in ransomware campaigns, and has low EPSS, but it has been public for a long period, so internet-facing services should still be patched as part of normal vulnerability management.

How an attack unfolds

An attacker identifies a Ruby/Rack-backed endpoint that accepts multipart/form-data, such as a file upload or form submission path. The attacker opens one or more HTTP connections and sends a multipart request whose body starts with a very large preamble before the first declared boundary. Vulnerable Rack::Multipart::Parser behavior stores that preamble in memory while waiting for the boundary. Once the boundary is sent, the request can continue to be parsed, but by then the worker may have consumed substantial memory. Repeating this across concurrent requests or connections can exhaust available memory, trigger Ruby NoMemoryError conditions, cause application server workers to be killed by the operating system or container runtime, and make the application unavailable to legitimate users.

How to fix it

Upgrade Rack to a release or source revision that includes the fix for Rack::Multipart::Parser preamble size handling. For rack/rack from Git, ensure the deployed code includes commit 4c4ea296fdfd115377912aa7dbcb55b83bf2888e or a later trusted version containing that change. Rebuild and redeploy all applications that vendor, bundle, or indirectly depend on affected Rack code. As compensating controls, enforce maximum request body sizes at the reverse proxy, load balancer, CDN, web server, and application server; set strict upload size limits; reduce request read timeouts; limit concurrent requests per client; and ensure containers or services have memory limits plus healthy restart policies. Do not rely only on application-level validation, because the vulnerable buffering occurs during multipart parsing before application handlers may run.

How to confirm the fix worked

Confirm the deployed Rack dependency or vendored source includes commit 4c4ea296fdfd115377912aa7dbcb55b83bf2888e or a release that incorporates it. Review lockfiles, dependency manifests, container images, and runtime package inventories to ensure no vulnerable Rack copy remains. Exercise upload and multipart endpoints in a staging environment with oversized multipart preambles and verify the request is rejected, bounded, or handled without unbounded memory growth. Confirm reverse proxies and application servers enforce request size limits before traffic reaches Rack. Monitor memory usage, worker restarts, HTTP 5xx rates, and request rejection logs during validation to ensure controls are effective and do not break legitimate uploads.

Typical attack path

  1. Discover an application endpoint that accepts multipart/form-data requests.
  2. Send an HTTP request with a valid multipart Content-Type header and boundary value.
  3. Place an unusually large amount of data before the first multipart boundary in the request body.
  4. Optionally complete the request with the expected boundary so parsing proceeds far enough to trigger the vulnerable buffering behavior.
  5. Repeat the request or run multiple concurrent requests to increase memory pressure.
  6. Cause application workers, containers, or hosts to slow down, restart, or terminate from out-of-memory conditions.

How to detect it

Look for evidence of denial-of-service activity rather than data theft. Useful sources include reverse proxy and load balancer access logs, web application firewall logs, application server logs, Ruby/Rack exception logs, container runtime events, kernel or host OOM logs, APM traces, and infrastructure metrics. Focus on multipart/form-data requests with unusually large request bodies, long request durations, incomplete uploads, repeated requests from the same source, spikes in HTTP 499/500/502/503/504 responses, and time-correlated increases in application memory usage. On containerized platforms, search for OOMKilled events or restarts of Ruby application containers around bursts of multipart traffic. In host logs, search for operating-system out-of-memory messages that reference Ruby, Puma, Unicorn, Passenger, or other Rack-hosting processes. Because exploitation may leave no unique payload marker after the request body is discarded, correlation between large multipart requests and memory exhaustion is the strongest indicator.

  • Content-Type: multipart/form-data; boundary=
  • Rack::Multipart::Parser
  • NoMemoryError
  • failed to allocate memory
  • Cannot allocate memory
  • Out of memory
  • out of memory: Kill process
  • Killed process
  • OOMKilled
  • SIGKILL
  • worker timeout
  • PumaWorkerKiller
  • puma: cluster worker
  • unicorn worker
  • passenger-status
  • HTTP 503
  • HTTP 502
  • HTTP 504

What your security team should do

  • Prioritize patching internet-facing Ruby/Rack applications that accept file uploads or multipart forms.
  • Update Rack to a fixed release or ensure source deployments include commit 4c4ea296fdfd115377912aa7dbcb55b83bf2888e or later.
  • Inventory transitive Rack usage across Ruby applications, containers, and vendored dependencies; do not assume only directly declared Rack packages are affected.
  • Enforce maximum request body size and upload size limits at the edge before requests reach the Rack application.
  • Add rate limiting and connection concurrency controls for multipart/form-data endpoints, especially unauthenticated paths.
  • Tune container, process manager, and application server memory limits so individual worker failures do not destabilize the full service.
  • Review historical logs and runtime telemetry for unexplained memory spikes, OOM kills, worker restarts, and large multipart requests.
  • Create SIEM or observability alerts for multipart requests with unusually large request bodies, high request duration, client disconnects, and correlated application memory growth.

The record

`Rack::Multipart::Parser` buffers the entire multipart **preamble** (bytes before the first boundary) in memory without any size limit. A client can send a large preamble followed by a valid boundary, causing significant memory use and potential process termination due to out-of-memory (OOM) conditions.

Affected packages

Ecosystem Package Introduced Fixed
RubyGems rack 0 2.2.19
RubyGems rack 3.1 3.1.17
RubyGems rack 3.2 3.2.2
AlmaLinux:10 cockpit-ha-cluster 0 0.12.1-1.el10_1.1
AlmaLinux:10 pcs 0 0.12.1-1.el10_1.1
AlmaLinux:10 pcs-snmp 0 0.12.1-1.el10_1.1
AlmaLinux:8 pcs 0 0.10.18-2.el8_10.7.alma.1
AlmaLinux:8 pcs-snmp 0 0.10.18-2.el8_10.7.alma.1
AlmaLinux:9 pcs 0 0.11.10-1.el9_7.1
AlmaLinux:9 pcs-snmp 0 0.11.10-1.el9_7.1
Chainguard gitaly-config-18.2 0 18.2.8-r0
Chainguard gitaly-config-18.3 0 18.3.4-r0
Chainguard gitaly-config-18.4 0 18.4.2-r0
Chainguard gitlab-base-18.2 0 18.2.8-r0
Chainguard gitlab-base-18.3 0 18.3.4-r0
Chainguard gitlab-base-18.4 0 18.4.2-r0
Chainguard gitlab-certificates-18.2 0 18.2.8-r0
Chainguard gitlab-certificates-18.3 0 18.3.4-r0
Chainguard gitlab-certificates-18.4 0 18.4.2-r0
Chainguard gitlab-cfssl-self-sign-scripts-18.2 0 18.2.8-r0
Chainguard gitlab-cfssl-self-sign-scripts-18.3 0 18.3.4-r0
Chainguard gitlab-cfssl-self-sign-scripts-18.4 0 18.4.2-r0
Chainguard gitlab-cng-18.2 0 18.2.8-r0
Chainguard gitlab-cng-18.3 0 18.3.4-r0
Chainguard gitlab-cng-18.4 0 18.4.2-r0
Chainguard gitlab-container-registry-18.2 0 18.2.8-r0
Chainguard gitlab-container-registry-18.3 0 18.3.4-r0
Chainguard gitlab-container-registry-18.4 0 18.4.2-r0
Chainguard gitlab-container-registry-scripts-18.2 0 18.2.8-r0
Chainguard gitlab-container-registry-scripts-18.3 0 18.3.4-r0
Chainguard gitlab-container-registry-scripts-18.4 0 18.4.2-r0
Chainguard gitlab-exporter-18.2 0 18.2.8-r0
Chainguard gitlab-exporter-18.3 0 18.3.4-r0
Chainguard gitlab-exporter-18.4 0 18.4.2-r0
Chainguard gitlab-exporter-scripts-18.2 0 18.2.8-r0
Chainguard gitlab-exporter-scripts-18.3 0 18.3.4-r0
Chainguard gitlab-exporter-scripts-18.4 0 18.4.2-r0
Chainguard gitlab-gitaly-scripts-18.2 0 18.2.8-r0
Chainguard gitlab-gitaly-scripts-18.3 0 18.3.4-r0
Chainguard gitlab-gitaly-scripts-18.4 0 18.4.2-r0
Chainguard gitlab-logger-18.2 0 18.2.8-r0
Chainguard gitlab-logger-18.3 0 18.3.4-r0
Chainguard gitlab-logger-18.4 0 18.4.2-r0
Chainguard gitlab-logger-compat-18.2 0 18.2.8-r0
Chainguard gitlab-logger-compat-18.3 0 18.3.4-r0
Chainguard gitlab-pages-scripts-18.2 0 18.2.8-r0
Chainguard gitlab-pages-scripts-18.3 0 18.3.4-r0
Chainguard gitlab-pages-scripts-18.4 0 18.4.2-r0
Chainguard gitlab-rails-ce-18.1 0 18.1.6-r3
Chainguard gitlab-rails-ce-18.2 0 18.2.8-r3
Chainguard gitlab-rails-ce-18.3 0 18.3.6-r0
Chainguard gitlab-rails-ce-18.4 0 18.4.4-r0
Chainguard gitlab-rails-ce-18.5 0 18.5.2-r0
Chainguard gitlab-rails-ce-assets-18.1 0 18.1.6-r1
Chainguard gitlab-rails-ce-assets-18.2 0 18.2.8-r1
Chainguard gitlab-rails-ce-assets-18.3 0 18.3.5-r0
Chainguard gitlab-rails-ce-assets-18.4 0 18.4.3-r0
Chainguard gitlab-rails-ce-assets-18.5 0 18.5.1-r0
Chainguard gitlab-rails-ce-assets-fips-18.1 0 18.1.6-r2
Chainguard gitlab-rails-ce-assets-fips-18.2 0 18.2.8-r2
Chainguard gitlab-rails-ce-assets-fips-18.3 0 18.3.5-r2
Chainguard gitlab-rails-ce-assets-fips-18.4 0 18.4.3-r3
Chainguard gitlab-rails-ce-assets-fips-18.5 0 18.5.1-r2
Chainguard gitlab-rails-ce-doc-18.1 0 18.1.6-r1
Chainguard gitlab-rails-ce-doc-18.2 0 18.2.8-r1
Chainguard gitlab-rails-ce-doc-18.3 0 18.3.5-r0
Chainguard gitlab-rails-ce-doc-18.4 0 18.4.3-r0
Chainguard gitlab-rails-ce-doc-18.5 0 18.5.1-r0
Chainguard gitlab-rails-ce-doc-fips-18.1 0 18.1.6-r2
Chainguard gitlab-rails-ce-doc-fips-18.2 0 18.2.8-r2
Chainguard gitlab-rails-ce-doc-fips-18.3 0 18.3.5-r2
Chainguard gitlab-rails-ce-doc-fips-18.4 0 18.4.3-r3
Chainguard gitlab-rails-ce-doc-fips-18.5 0 18.5.1-r2
Chainguard gitlab-rails-ce-fips-18.1 0 18.1.6-r4
Chainguard gitlab-rails-ce-fips-18.2 0 18.2.8-r4
Chainguard gitlab-rails-ce-fips-18.3 0 18.3.6-r0
Chainguard gitlab-rails-ce-fips-18.4 0 18.4.4-r0
Chainguard gitlab-rails-ce-fips-18.5 0 18.5.2-r0
Chainguard gitlab-rails-scripts-18.2 0 18.2.8-r0
Chainguard gitlab-rails-scripts-18.3 0 18.3.4-r0
Chainguard gitlab-rails-scripts-18.4 0 18.4.2-r0
Chainguard gitlab-shell-18.2 0 18.2.8-r0
Chainguard gitlab-shell-18.3 0 18.3.4-r0
Chainguard gitlab-shell-18.4 0 18.4.2-r0
Chainguard gitlab-shell-scripts-18.2 0 18.2.8-r0
Chainguard gitlab-shell-scripts-18.3 0 18.3.4-r0
Chainguard gitlab-shell-scripts-18.4 0 18.4.2-r0
Chainguard gitlab-shell-scripts-compat-18.2 0 18.2.8-r0
Chainguard gitlab-shell-scripts-compat-18.3 0 18.3.4-r0
Chainguard gitlab-sidekiq-ce-18.2 0 18.2.8-r0
Chainguard gitlab-sidekiq-ce-18.3 0 18.3.4-r0
Chainguard gitlab-sidekiq-ce-18.4 0 18.4.2-r0
Chainguard gitlab-toolbox-ce-18.2 0 18.2.8-r0
Chainguard gitlab-toolbox-ce-18.3 0 18.3.4-r0
Chainguard gitlab-toolbox-ce-18.4 0 18.4.2-r0
Chainguard gitlab-webservice-ce-18.2 0 18.2.8-r0
Chainguard gitlab-webservice-ce-18.3 0 18.3.4-r0
Chainguard gitlab-webservice-ce-18.4 0 18.4.2-r0
Chainguard gitlab-workhorse-scripts-18.2 0 18.2.8-r0
Chainguard gitlab-workhorse-scripts-18.3 0 18.3.4-r0
Chainguard gitlab-workhorse-scripts-18.4 0 18.4.2-r0
Chainguard logstash-8.17 0 8.17.10-r3
Chainguard logstash-8.17-bitnami-compat 0 8.17.10-r3
Chainguard logstash-8.17-compat 0 8.17.10-r3
Chainguard logstash-8.17-env2yaml 0 8.17.10-r3
Chainguard logstash-8.17-iamguarded-compat 0 8.17.10-r3
Chainguard logstash-8.17-with-output-opensearch 0 8.17.10-r3
Chainguard logstash-8.18 0 8.18.8-r1
Chainguard logstash-8.18-bitnami-compat 0 8.18.8-r1
Chainguard logstash-8.18-compat 0 8.18.8-r1
Chainguard logstash-8.18-env2yaml 0 8.18.8-r1
Chainguard logstash-8.18-iamguarded-compat 0 8.18.8-r1
Chainguard logstash-8.18-with-output-opensearch 0 8.18.8-r1
Chainguard logstash-8.19 0 8.19.5-r1
Chainguard logstash-8.19-compat 0 8.19.5-r1
Chainguard logstash-8.19-env2yaml 0 8.19.5-r1
Chainguard logstash-8.19-iamguarded-compat 0 8.19.5-r1
Chainguard logstash-8.19-with-output-opensearch 0 8.19.5-r1
Chainguard logstash-9.0 0 9.0.8-r1
Chainguard logstash-9.0-bitnami-compat 0 9.0.8-r1
Chainguard logstash-9.0-compat 0 9.0.8-r1
Chainguard logstash-9.0-env2yaml 0 9.0.8-r1
Chainguard logstash-9.0-iamguarded-compat 0 9.0.8-r1
Chainguard logstash-9.0-with-output-opensearch 0 9.0.8-r1
Chainguard logstash-9.1 0 9.1.5-r1
Chainguard logstash-9.1-bitnami-compat 0 9.1.5-r1
Chainguard logstash-9.1-compat 0 9.1.5-r1
Chainguard logstash-9.1-env2yaml 0 9.1.5-r1
Chainguard logstash-9.1-iamguarded-compat 0 9.1.5-r1
Chainguard logstash-9.1-with-output-opensearch 0 9.1.5-r1
Chainguard ruby3.2-rails-7.1 0 7.1.6-r0
Chainguard ruby3.2-rails-7.1-compat 0 7.1.6-r0
Chainguard ruby3.2-rails-7.2 0 7.2.2.2-r1
Chainguard ruby3.2-rails-7.2-compat 0 7.2.2.2-r1
Chainguard ruby3.2-rails-8.0 0 8.0.3-r1
Chainguard ruby3.2-rails-8.0-compat 0 8.0.3-r1
Chainguard ruby3.3-rack-2.2 0 2.2.22-r0
Chainguard ruby3.3-rails-7.1 0 7.1.6-r0
Chainguard ruby3.3-rails-7.1-compat 0 7.1.6-r0
Chainguard ruby3.3-rails-7.2 0 7.2.2.2-r1
Chainguard ruby3.3-rails-7.2-compat 0 7.2.2.2-r1
Chainguard ruby3.3-rails-8.0 0 8.0.3-r1
Chainguard ruby3.3-rails-8.0-compat 0 8.0.3-r1
Chainguard ruby3.4-rails-7.1 0 7.1.6-r0
Chainguard ruby3.4-rails-7.1-compat 0 7.1.6-r0
Chainguard ruby3.4-rails-7.2 0 7.2.2.2-r1
Chainguard ruby3.4-rails-7.2-compat 0 7.2.2.2-r1
Chainguard ruby3.4-rails-8.0 0 8.0.3-r1
Chainguard ruby3.4-rails-8.0-compat 0 8.0.3-r1
Mageia:9 ruby-rack 0 2.2.21-1.mga9
Wolfi gitaly-config-18.2 0 18.2.8-r0
Wolfi gitlab-base-18.2 0 18.2.8-r0
Wolfi gitlab-certificates-18.2 0 18.2.8-r0
Wolfi gitlab-cfssl-self-sign-scripts-18.2 0 18.2.8-r0
Wolfi gitlab-cng-18.2 0 18.2.8-r0
Wolfi gitlab-container-registry-18.2 0 18.2.8-r0
Wolfi gitlab-container-registry-scripts-18.2 0 18.2.8-r0
Wolfi gitlab-exporter-18.2 0 18.2.8-r0
Wolfi gitlab-exporter-scripts-18.2 0 18.2.8-r0
Wolfi gitlab-gitaly-scripts-18.2 0 18.2.8-r0
Wolfi gitlab-logger-18.2 0 18.2.8-r0
Wolfi gitlab-logger-compat-18.2 0 18.2.8-r0
Wolfi gitlab-pages-scripts-18.2 0 18.2.8-r0
Wolfi gitlab-shell-18.2 0 18.2.8-r0
Wolfi gitlab-shell-scripts-18.2 0 18.2.8-r0
Wolfi gitlab-shell-scripts-compat-18.2 0 18.2.8-r0
Wolfi logstash-9.1 0 9.1.5-r1
Wolfi logstash-9.1-bitnami-compat 0 9.1.5-r1
Wolfi logstash-9.1-compat 0 9.1.5-r1
Wolfi logstash-9.1-env2yaml 0 9.1.5-r1
Wolfi logstash-9.1-iamguarded-compat 0 9.1.5-r1
Wolfi logstash-9.1-with-output-opensearch 0 9.1.5-r1
Wolfi ruby3.2-rails-8.0 0 8.0.3-r1
Wolfi ruby3.2-rails-8.0-compat 0 8.0.3-r1
Wolfi ruby3.3-rack-2.2 0 2.2.22-r0
Wolfi ruby3.3-rails-8.0 0 8.0.3-r1
Wolfi ruby3.3-rails-8.0-compat 0 8.0.3-r1
Wolfi ruby3.4-rails-8.0 0 8.0.3-r1
Wolfi ruby3.4-rails-8.0-compat 0 8.0.3-r1
gem rack 3.1 3.1.17
gem rack 3.2 3.2.2
openSUSE:Tumbleweed rubygem-rack-2.2 0 2.2.19-1.1
openSUSE:Tumbleweed rubygem-rack-2.2 0 2.2.22-1.1

Related vulnerabilities