CVE-2025-61919
High · 7.5Rack is vulnerable to a memory-exhaustion DoS through unbounded URL-encoded body parsing
CVSS
7.5
EPSS
0.6%
Published
Oct 10, 2025
CISA due date
—
Cloudanix analysis
A flaw in a common Ruby web component can let someone knock a website offline by sending oversized form submissions that consume the server’s memory.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Moderate
- Impact
- Denial Of Service
- Component
- Library
- Class
- Denial of service
- Remediation
- Patch
- Effort
- Low
- Patch risk
- Low
What it actually does
Rack::Request#POST can read an entire HTTP request body into memory when handling requests with Content-Type: application/x-www-form-urlencoded. Because the read path calls rack.input.read(nil) without a reliable maximum size cap, an unauthenticated remote client can send very large form-encoded POST bodies that are fully buffered by the Ruby/Rack process before parsing. This can exhaust process or host memory, trigger garbage collection pressure, raise allocation errors, cause worker crashes, or lead the operating system/container runtime to kill the process. The vulnerability affects Rack-based applications that parse form POST bodies through vulnerable rack/rack code prior to the fixed commit 6ef591522bb44f80654ad1a80654ba46cafdc7c1.
Why it matters to the business
Successful exploitation can make Rack-based web applications slow, unstable, or unavailable by consuming memory with oversized HTTP requests. Internet-facing services are the highest concern because exploitation does not require authentication and can be repeated or distributed to cause sustained denial of service. Although EPSS is currently low and the issue is not listed in CISA KEV or known ransomware use, the CVSS 7.5 availability impact and the broad use of Rack in Ruby web stacks make remediation important for public-facing and business-critical applications.
How an attack unfolds
An attacker identifies a Rack-based application endpoint that accepts or causes parsing of application/x-www-form-urlencoded POST data. The attacker sends one or more HTTP POST requests with an extremely large request body and the form URL-encoded content type. When the vulnerable Rack request parsing path is invoked, Rack reads the body without an enforced cap and buffers it into application process memory. As memory consumption rises, the process may become unresponsive, spend excessive time in garbage collection, raise Ruby memory allocation errors, or be terminated by the container runtime or operating system OOM killer. The attacker can repeat the requests or use multiple clients to keep workers recycling and degrade or fully deny service.
How to fix it
Upgrade rack/rack to a version that includes the fix at commit 6ef591522bb44f80654ad1a80654ba46cafdc7c1, or use a vendor/package release that incorporates that commit. If using Rack through a framework or platform, update the framework bundle, lockfile, container image, and runtime dependencies so the effective Rack version contains the fix. As defense in depth, enforce maximum request body sizes at the earliest possible layer, such as CDN, WAF, reverse proxy, ingress controller, load balancer, application server, and Rack middleware. Configure web servers such as NGINX, Apache, Envoy, HAProxy, or cloud load balancers to reject oversized POST bodies before they reach Ruby application workers. Apply request rate limits, per-client connection limits, and worker memory limits with safe restart behavior. Ensure application endpoints that do not require large form submissions explicitly reject them with 413 Payload Too Large.
How to confirm the fix worked
Confirm the deployed Rack code includes commit 6ef591522bb44f80654ad1a80654ba46cafdc7c1 or a package release containing it. Validate dependency resolution using the application lockfile, software composition analysis, container image scan, or runtime package inspection rather than only checking source manifests. Test that oversized application/x-www-form-urlencoded POST requests are rejected with 413 or equivalent before significant application memory growth occurs. Monitor memory usage during controlled testing to ensure request bodies are capped at the edge or middleware layer. Confirm reverse proxy, ingress, WAF, and application server maximum body-size settings are active in production-equivalent configuration. Re-run regression tests for legitimate large form submissions to ensure business workflows still function within approved limits.
Typical attack path
- Discover or select a Rack/Ruby web application exposed over HTTP or HTTPS.
- Find an endpoint that accepts POST requests or otherwise triggers Rack::Request#POST form parsing.
- Send a POST request with Content-Type: application/x-www-form-urlencoded and an abnormally large request body.
- Force the vulnerable Rack code path to call rack.input.read(nil) and buffer the full body into memory.
- Repeat or parallelize requests until application workers exhaust memory, crash, or are killed.
- Maintain pressure to cause intermittent or sustained service unavailability.
How to detect it
Investigate historical web access logs, reverse proxy logs, WAF/CDN logs, application logs, container runtime events, process supervisor logs, and host kernel logs. Look for unusually large POST requests with Content-Type: application/x-www-form-urlencoded, especially to unauthenticated endpoints, followed by increased latency, 5xx responses, worker restarts, memory allocation errors, or OOM-kill events. In proxy logs, correlate high request body sizes, long request times, upstream connection resets, 502/503/504 responses, or repeated requests from the same source addresses. In Ruby/Rack application logs, search for NoMemoryError, failed memory allocation messages, abrupt worker exits, and request-processing failures around the same timestamps. In Kubernetes or containerized deployments, review pod events and container status for OOMKilled, restart count increases, and memory-limit terminations. In host-based telemetry, correlate Ruby process RSS growth and kernel OOM killer messages with inbound large form POST traffic. Because exploit attempts may use otherwise normal HTTP semantics, behavioral correlation between oversized form bodies and memory-related service failure is more reliable than a single static indicator.
- Content-Type: application/x-www-form-urlencoded
- application/x-www-form-urlencoded
- NoMemoryError
- failed to allocate memory
- out of memory
- Out of memory
- OOMKilled
- Killed process
- Memory cgroup out of memory
- rack.input.read(nil)
- POST
What your security team should do
- Prioritize patching internet-facing Rack-based applications and any service with unauthenticated POST endpoints.
- Upgrade rack/rack or dependent framework packages to include fixed commit 6ef591522bb44f80654ad1a80654ba46cafdc7c1.
- Add or verify maximum HTTP request body-size limits at CDN, WAF, reverse proxy, ingress, and application layers.
- Deploy rate limiting for repeated large POST requests, especially from unauthenticated clients and new source IPs.
- Review application and infrastructure logs for large form-encoded POST requests followed by memory spikes, worker crashes, 5xx errors, or OOM events.
- Create monitoring alerts for abnormal Ruby process RSS growth, container memory-limit kills, worker restarts, and elevated 413/499/500/502/503 responses.
- Include this issue in dependency governance for Ruby/Rack applications so vulnerable transitive Rack versions are not reintroduced.
The record
`Rack::Request#POST` reads the entire request body into memory for `Content-Type: application/x-www-form-urlencoded`, calling `rack.input.read(nil)` without enforcing a length or cap. Large request bodies can therefore be buffered completely into process memory before parsing, leading to denial of service (DoS) through memory exhaustion.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| RubyGems | rack | 0 | 2.2.20 |
| RubyGems | rack | 3.0 | 3.1.18 |
| RubyGems | rack | 3.2 | 3.2.3 |
| 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.3 | 0 | 18.3.5-r0 |
| Chainguard | gitaly-config-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-base-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-base-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-certificates-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-certificates-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-cfssl-self-sign-scripts-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-cfssl-self-sign-scripts-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-cng-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-cng-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-container-registry-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-container-registry-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-container-registry-scripts-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-container-registry-scripts-18.4 | 0 | 18.4.4-r0 |
| Chainguard | gitlab-exporter-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-exporter-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-exporter-scripts-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-exporter-scripts-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-gitaly-scripts-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-gitaly-scripts-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-logger-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-logger-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-pages-scripts-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-pages-scripts-18.4 | 0 | 18.4.3-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.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-rails-scripts-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-shell-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-shell-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-shell-scripts-18.3 | 0 | 18.3.6-r0 |
| Chainguard | gitlab-shell-scripts-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-sidekiq-ce-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-sidekiq-ce-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-toolbox-ce-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-toolbox-ce-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-webservice-ce-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-webservice-ce-18.4 | 0 | 18.4.3-r0 |
| Chainguard | gitlab-workhorse-scripts-18.3 | 0 | 18.3.5-r0 |
| Chainguard | gitlab-workhorse-scripts-18.4 | 0 | 18.4.3-r0 |
| Chainguard | kube-fluentd-operator | 0 | 1.18.2-r49 |
| Chainguard | kube-fluentd-operator-compat | 0 | 1.18.2-r49 |
| Chainguard | kube-fluentd-operator-default-config | 0 | 1.18.2-r49 |
| Chainguard | kube-fluentd-operator-oci-entrypoint | 0 | 1.18.2-r49 |
| Chainguard | logstash-8.17 | 0 | 8.17.10-r4 |
| Chainguard | logstash-8.17-bitnami-compat | 0 | 8.17.10-r4 |
| Chainguard | logstash-8.17-compat | 0 | 8.17.10-r4 |
| Chainguard | logstash-8.17-env2yaml | 0 | 8.17.10-r4 |
| Chainguard | logstash-8.17-iamguarded-compat | 0 | 8.17.10-r4 |
| Chainguard | logstash-8.17-with-output-opensearch | 0 | 8.17.10-r4 |
| Chainguard | logstash-8.18 | 0 | 8.18.8-r2 |
| Chainguard | logstash-8.18-bitnami-compat | 0 | 8.18.8-r2 |
| Chainguard | logstash-8.18-compat | 0 | 8.18.8-r2 |
| Chainguard | logstash-8.18-env2yaml | 0 | 8.18.8-r2 |
| Chainguard | logstash-8.18-iamguarded-compat | 0 | 8.18.8-r2 |
| Chainguard | logstash-8.18-with-output-opensearch | 0 | 8.18.8-r2 |
| Chainguard | logstash-8.19 | 0 | 8.19.5-r2 |
| Chainguard | logstash-8.19-compat | 0 | 8.19.5-r2 |
| Chainguard | logstash-8.19-env2yaml | 0 | 8.19.5-r2 |
| Chainguard | logstash-8.19-iamguarded-compat | 0 | 8.19.5-r2 |
| Chainguard | logstash-8.19-with-output-opensearch | 0 | 8.19.5-r2 |
| Chainguard | logstash-9.0 | 0 | 9.0.8-r2 |
| Chainguard | logstash-9.0-bitnami-compat | 0 | 9.0.8-r2 |
| Chainguard | logstash-9.0-compat | 0 | 9.0.8-r2 |
| Chainguard | logstash-9.0-env2yaml | 0 | 9.0.8-r2 |
| Chainguard | logstash-9.0-iamguarded-compat | 0 | 9.0.8-r2 |
| Chainguard | logstash-9.0-with-output-opensearch | 0 | 9.0.8-r2 |
| Chainguard | logstash-9.1 | 0 | 9.1.5-r2 |
| Chainguard | logstash-9.1-bitnami-compat | 0 | 9.1.5-r2 |
| Chainguard | logstash-9.1-compat | 0 | 9.1.5-r2 |
| Chainguard | logstash-9.1-env2yaml | 0 | 9.1.5-r2 |
| Chainguard | logstash-9.1-iamguarded-compat | 0 | 9.1.5-r2 |
| Chainguard | logstash-9.1-with-output-opensearch | 0 | 9.1.5-r2 |
| 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-r2 |
| Chainguard | ruby3.2-rails-7.2-compat | 0 | 7.2.2.2-r2 |
| Chainguard | ruby3.2-rails-8.0 | 0 | 8.0.3-r2 |
| Chainguard | ruby3.2-rails-8.0-compat | 0 | 8.0.3-r2 |
| 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-r2 |
| Chainguard | ruby3.3-rails-7.2-compat | 0 | 7.2.2.2-r2 |
| Chainguard | ruby3.3-rails-8.0 | 0 | 8.0.3-r2 |
| Chainguard | ruby3.3-rails-8.0-compat | 0 | 8.0.3-r2 |
| 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-r2 |
| Chainguard | ruby3.4-rails-7.2-compat | 0 | 7.2.2.2-r2 |
| Chainguard | ruby3.4-rails-8.0 | 0 | 8.0.3-r2 |
| Chainguard | ruby3.4-rails-8.0-compat | 0 | 8.0.3-r2 |
| Mageia:9 | ruby-rack | 0 | 2.2.21-1.mga9 |
| SUSE:Linux Enterprise High Availability Extension 15 SP3 | rubygem-rack | 0 | 2.2.20-150000.3.34.1 |
| SUSE:Linux Enterprise High Availability Extension 15 SP4 | rubygem-rack | 0 | 2.2.20-150000.3.34.1 |
| SUSE:Linux Enterprise High Availability Extension 15 SP5 | rubygem-rack | 0 | 2.2.20-150000.3.34.1 |
| SUSE:Linux Enterprise High Availability Extension 15 SP6 | rubygem-rack | 0 | 2.2.20-150000.3.34.1 |
| SUSE:Linux Enterprise High Availability Extension 15 SP7 | rubygem-rack | 0 | 2.2.20-150000.3.34.1 |
| Wolfi | kube-fluentd-operator | 0 | 1.18.2-r49 |
| Wolfi | kube-fluentd-operator-compat | 0 | 1.18.2-r49 |
| Wolfi | kube-fluentd-operator-default-config | 0 | 1.18.2-r49 |
| Wolfi | kube-fluentd-operator-oci-entrypoint | 0 | 1.18.2-r49 |
| Wolfi | logstash-9.1 | 0 | 9.1.5-r2 |
| Wolfi | logstash-9.1-bitnami-compat | 0 | 9.1.5-r2 |
| Wolfi | logstash-9.1-compat | 0 | 9.1.5-r2 |
| Wolfi | logstash-9.1-env2yaml | 0 | 9.1.5-r2 |
| Wolfi | logstash-9.1-iamguarded-compat | 0 | 9.1.5-r2 |
| Wolfi | logstash-9.1-with-output-opensearch | 0 | 9.1.5-r2 |
| Wolfi | ruby3.2-rails-8.0 | 0 | 8.0.3-r2 |
| Wolfi | ruby3.2-rails-8.0-compat | 0 | 8.0.3-r2 |
| Wolfi | ruby3.3-rack-2.2 | 0 | 2.2.22-r0 |
| Wolfi | ruby3.3-rails-8.0 | 0 | 8.0.3-r2 |
| Wolfi | ruby3.3-rails-8.0-compat | 0 | 8.0.3-r2 |
| Wolfi | ruby3.4-rails-8.0 | 0 | 8.0.3-r2 |
| Wolfi | ruby3.4-rails-8.0-compat | 0 | 8.0.3-r2 |
| gem | rack | 3.0 | 3.1.18 |
| gem | rack | 3.2 | 3.2.3 |
| openSUSE:Leap 15.6 | rubygem-rack | 0 | 2.2.20-150000.3.34.1 |
| openSUSE:Leap 16.0 | hawk2 | 0 | 2.7.0+git.1742310530.bfcd0e2c-160000.3.1 |
| openSUSE:Tumbleweed | rubygem-rack-2.2 | 0 | 2.2.20-1.1 |
| openSUSE:Tumbleweed | rubygem-rack-2.2 | 0 | 2.2.22-1.1 |
Related vulnerabilities
- CVE-2026-25500 Rack is a modular Ruby web server interface. Also affects rack
- CVE-2026-22860 Rack is a modular Ruby web server interface. Also affects rack
- CVE-2025-61780 Rack has a Possible Information Disclosure Vulnerability Also affects rack
- CVE-2025-61770 Rack's unbounded multipart preamble buffering enables DoS (memory exhaustion) Also affects rack
- CVE-2025-61771 Rack: Multipart parser buffers large non‑file fields entirely in memory, enabling DoS… Also affects rack
- CVE-2025-61772 Rack's multipart parser buffers unbounded per-part headers, enabling DoS (memory… Also affects rack
- CVE-2025-59830 Rack has an unsafe default in Rack::QueryParser allows params_limit bypass via… Also affects rack
- CVE-2025-46336 Rack::Session is a session management implementation for Rack. Also affects rack