CVE-2023-27539
NoneCVSS
—
EPSS
1.1%
Published
Mar 22, 2023
CISA due date
—
Cloudanix analysis
A flaw in a common Ruby web component can let someone slow down or knock web services offline by sending specially crafted web requests.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Moderate
- Impact
- Denial Of Service
- Component
- Library
- Class
- Denial of service
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
Rack’s HTTP header parsing can be forced into excessive resource consumption when it receives specially crafted header values. Because Rack sits early in the request-handling path for many Ruby web applications, the parsing cost can be incurred before application authorization or routing logic runs. Successful exploitation causes denial of service through CPU exhaustion, worker/thread starvation, elevated memory pressure, request queue buildup, or process restarts; it does not indicate code execution or direct data disclosure by itself.
Why it matters to the business
Public Ruby/Rack-based services may become slow or unavailable if an attacker sends malicious or high-volume malformed HTTP requests. The issue is not listed in CISA KEV, is not marked as ransomware-used, and has low EPSS with no mature public exploit noted in the supplied data, so it is generally a patch-management and availability-risk item rather than an emergency compromise indicator. However, because Rack is a foundational dependency for many Ruby web stacks, exposure can be widespread through downstream applications, especially internet-facing APIs, Rails/Sinatra services, and systems with limited request-worker capacity.
How an attack unfolds
An attacker identifies a service that ultimately passes HTTP requests through a vulnerable Rack version. They send requests containing unusually large, malformed, or parser-stressing HTTP header values. The vulnerable parser spends disproportionate CPU time or memory handling those headers, tying up Rack application workers. By repeating the requests or opening multiple concurrent connections, the attacker can exhaust available application capacity, causing elevated latency, 5xx responses, health-check failures, autoscaling events, or application restarts. If the service is behind an HTTP/2-capable proxy, the observable edge traffic may look like a burst of many quickly generated requests, but the vulnerable behavior is in Rack’s header handling after traffic is forwarded to the Ruby application.
How to fix it
Upgrade Rack to a fixed version or source revision that includes commit 27addc7f1ae290b6b84c1c351e5b6d75a05bb40b. For applications built from source, ensure the deployed Rack code contains that commit or a later trusted release. For Bundler-managed applications, update the `rack` gem through the application dependency lockfile and redeploy all affected services, jobs, containers, and images. Where immediate upgrade is not possible, reduce exposure by enforcing strict maximum HTTP header size and header count at the reverse proxy/load balancer, enabling request and upstream timeouts, limiting concurrent connections and request rates per source, rejecting malformed headers at the edge, and ensuring application workers are supervised and horizontally scalable. Mitigations should be treated as temporary because they may not cover every parser-stressing input.
How to confirm the fix worked
Confirm the running application no longer uses a vulnerable Rack build. Review `Gemfile.lock`, SBOMs, container image manifests, and dependency scanner results for `rack`; at runtime, verify with commands such as `bundle info rack` or `ruby -e 'require "rack"; puts Rack.release'` where appropriate. For source-based deployments, verify the Rack checkout includes commit 27addc7f1ae290b6b84c1c351e5b6d75a05bb40b or a later release containing the fix. In staging, replay safe synthetic requests with oversized or malformed headers and confirm the service returns a quick 4xx/431/400 response or the edge rejects the request, without sustained CPU spikes, memory growth, worker starvation, or application restarts. Also validate reverse proxy limits for maximum header size, total request header bytes, request timeouts, and per-client rate limits.
Typical attack path
- Reconnoiter internet-facing Ruby/Rack-backed endpoints and confirm they accept HTTP traffic through a Rack application stack.
- Craft HTTP requests with abnormal header structure, size, repetition, whitespace, delimiters, or other values that stress Rack header parsing.
- Send the crafted requests repeatedly or concurrently to maximize request-worker occupancy.
- Observe latency increases, 5xx responses, connection resets, queue buildup, or process restarts.
- Continue the request pattern to sustain denial of service until rate limits, proxy limits, or patched Rack code prevents the parser exhaustion condition.
How to detect it
Look for evidence of denial-of-service activity rather than persistence or post-exploitation artifacts. Review reverse proxy, load balancer, CDN/WAF, web server, and application logs for bursts of requests with abnormal or very large headers, repeated malformed-header errors, 400/431 responses, upstream timeouts, and connection resets. Correlate these with application telemetry showing high CPU in Ruby/Rack application processes, increased request duration before routing, saturated Puma/Unicorn/Passenger workers, queue depth growth, memory pressure, health-check failures, container restarts, or autoscaling events. Useful log sources include NGINX/Apache/Envoy/HAProxy access and error logs, CDN/WAF events, Kubernetes pod restart events, application performance monitoring traces, process metrics, and Rack/Rails application logs. Because this is a denial-of-service flaw, there may be no durable host artifact after traffic stops; detection depends heavily on retaining edge and application performance logs from the suspected window.
- HTTP 431 Request Header Fields Too Large
- Request Header Fields Too Large
- client sent too long header line
- upstream timed out
- upstream prematurely closed connection
- request header or cookie too large
- Bad request syntax or unsupported method
- Puma::MiniSSL::SSLError
- Puma::HttpParserError
- Rack::Lint::LintError
- ActionDispatch::Http::Parameters::ParseError
- status=431
- status=400
- status=502
- status=503
- status=504
What your security team should do
- Inventory all Ruby applications and container images that include Rack, prioritizing internet-facing services and high-availability APIs.
- Upgrade Rack everywhere to a fixed release or source revision containing commit 27addc7f1ae290b6b84c1c351e5b6d75a05bb40b, then rebuild and redeploy dependent applications.
- Enforce edge controls for maximum request header size, maximum number of headers, request timeouts, and per-source request-rate limits.
- Monitor for availability symptoms including spikes in 400/431/500/502/503/504 responses, application worker saturation, high CPU in Ruby processes, request queue growth, and repeated restarts.
- Create detection logic for bursts of malformed, oversized, or repetitive HTTP headers reaching Rack-backed services, especially when correlated with latency or worker exhaustion.
- Do not treat this as evidence of data compromise by default; focus incident response on availability impact unless other indicators suggest intrusion.
The record
Possible Denial of Service Vulnerability in Rack’s header parsing
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| RubyGems | rack | 2.0.0 | 2.2.6.4 |
| RubyGems | rack | 3.0.0 | 3.0.6.1 |
| AlmaLinux:8 | pcs | 0 | 0.10.15-4.el8_8.1.alma |
| AlmaLinux:8 | pcs-snmp | 0 | 0.10.15-4.el8_8.1.alma |
| AlmaLinux:9 | pcs | 0 | 0.11.4-7.el9_2 |
| AlmaLinux:9 | pcs-snmp | 0 | 0.11.4-7.el9_2 |
| Debian:10 | ruby-rack | 0 | 2.0.6-3+deb10u3 |
| Debian:11 | ruby-rack | 0 | 2.1.4-3+deb11u1 |
| Debian:12 | ruby-rack | 0 | 2.2.6.4-1 |
| Debian:13 | ruby-rack | 0 | 2.2.6.4-1 |
| Mageia:9 | ruby-rack | 0 | 2.2.8-1.mga9 |
| Red Hat:enterprise_linux:8::highavailability | pcs | 0 | 0:0.10.15-4.el8_8.1 |
| Red Hat:enterprise_linux:8::highavailability | pcs-snmp | 0 | 0:0.10.15-4.el8_8.1 |
| Red Hat:enterprise_linux:8::resilientstorage | pcs | 0 | 0:0.10.15-4.el8_8.1 |
| Red Hat:enterprise_linux:8::resilientstorage | pcs-snmp | 0 | 0:0.10.15-4.el8_8.1 |
| Red Hat:enterprise_linux:9::highavailability | pcs | 0 | 0:0.11.4-7.el9_2 |
| Red Hat:enterprise_linux:9::highavailability | pcs-snmp | 0 | 0:0.11.4-7.el9_2 |
| Red Hat:enterprise_linux:9::resilientstorage | pcs | 0 | 0:0.11.4-7.el9_2 |
| Red Hat:enterprise_linux:9::resilientstorage | pcs-snmp | 0 | 0:0.11.4-7.el9_2 |
| Red Hat:rhel_eus:8.4::highavailability | pcs | 0 | 0:0.10.8-1.el8_4.4 |
| Red Hat:rhel_eus:8.4::highavailability | pcs-snmp | 0 | 0:0.10.8-1.el8_4.4 |
| Red Hat:rhel_eus:8.4::resilientstorage | pcs | 0 | 0:0.10.8-1.el8_4.4 |
| Red Hat:rhel_eus:8.4::resilientstorage | pcs-snmp | 0 | 0:0.10.8-1.el8_4.4 |
| Red Hat:rhel_eus:8.6::highavailability | pcs | 0 | 0:0.10.12-6.el8_6.4 |
| Red Hat:rhel_eus:8.6::highavailability | pcs-snmp | 0 | 0:0.10.12-6.el8_6.4 |
| Red Hat:rhel_eus:8.6::resilientstorage | pcs | 0 | 0:0.10.12-6.el8_6.4 |
| Red Hat:rhel_eus:8.6::resilientstorage | pcs-snmp | 0 | 0:0.10.12-6.el8_6.4 |
| Red Hat:rhel_eus:9.0::highavailability | pcs | 0 | 0:0.11.1-10.el9_0.4 |
| Red Hat:rhel_eus:9.0::highavailability | pcs-snmp | 0 | 0:0.11.1-10.el9_0.4 |
| Red Hat:rhel_eus:9.0::resilientstorage | pcs | 0 | 0:0.11.1-10.el9_0.4 |
| Red Hat:rhel_eus:9.0::resilientstorage | pcs-snmp | 0 | 0:0.11.1-10.el9_0.4 |
| Red Hat:satellite:6.14::el8 | foreman | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-cli | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-debug | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-dynflow-sidekiq | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-ec2 | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-journald | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-libvirt | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-openstack | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-ovirt | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-postgresql | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-redis | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-service | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-telemetry | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-vmware | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | puppet-agent | 0 | 0:7.26.0-3.el8sat |
| Red Hat:satellite:6.14::el8 | puppetserver | 0 | 0:7.11.0-1.el8sat |
| Red Hat:satellite:6.14::el8 | python-django | 0 | 0:3.2.21-1.el8pc |
| Red Hat:satellite:6.14::el8 | python-future | 0 | 0:0.18.3-1.el8pc |
| Red Hat:satellite:6.14::el8 | python-gitpython | 0 | 0:3.1.32-1.el8pc |
| Red Hat:satellite:6.14::el8 | python-pulp-ansible | 0 | 1:0.16.0-1.el8pc |
| Red Hat:satellite:6.14::el8 | python-requests | 0 | 0:2.31.0-1.el8pc |
| Red Hat:satellite:6.14::el8 | python-sqlparse | 0 | 0:0.4.4-1.el8pc |
| Red Hat:satellite:6.14::el8 | python39-django | 0 | 0:3.2.21-1.el8pc |
| Red Hat:satellite:6.14::el8 | python39-future | 0 | 0:0.18.3-1.el8pc |
| Red Hat:satellite:6.14::el8 | python39-gitpython | 0 | 0:3.1.32-1.el8pc |
| Red Hat:satellite:6.14::el8 | python39-pulp-ansible | 0 | 1:0.16.0-1.el8pc |
| Red Hat:satellite:6.14::el8 | python39-requests | 0 | 0:2.31.0-1.el8pc |
| Red Hat:satellite:6.14::el8 | python39-sqlparse | 0 | 0:0.4.4-1.el8pc |
| Red Hat:satellite:6.14::el8 | rubygem-actionpack | 0 | 0:6.1.7.3-1.el8sat |
| Red Hat:satellite:6.14::el8 | rubygem-activerecord | 0 | 0:6.1.7.3-1.el8sat |
| Red Hat:satellite:6.14::el8 | rubygem-activesupport | 0 | 0:6.1.7.3-1.el8sat |
| Red Hat:satellite:6.14::el8 | rubygem-git | 0 | 0:1.18.0-1.el8sat |
| Red Hat:satellite:6.14::el8 | rubygem-globalid | 0 | 0:1.1.0-1.el8sat |
| Red Hat:satellite:6.14::el8 | rubygem-kubeclient | 0 | 0:4.10.1-1.el8sat |
| Red Hat:satellite:6.14::el8 | rubygem-rack | 0 | 0:2.2.7-1.el8sat |
| Red Hat:satellite:6.14::el8 | yggdrasil-worker-forwarder | 0 | 0:0.0.3-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-cli | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-debug | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-dynflow-sidekiq | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-ec2 | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-journald | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-libvirt | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-openstack | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-ovirt | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-postgresql | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-redis | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-service | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-telemetry | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-vmware | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | puppet-agent | 0 | 0:7.26.0-3.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | puppetserver | 0 | 0:7.11.0-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | python-django | 0 | 0:3.2.21-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python-future | 0 | 0:0.18.3-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python-gitpython | 0 | 0:3.1.32-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python-pulp-ansible | 0 | 1:0.16.0-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python-requests | 0 | 0:2.31.0-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python-sqlparse | 0 | 0:0.4.4-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python39-django | 0 | 0:3.2.21-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python39-future | 0 | 0:0.18.3-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python39-gitpython | 0 | 0:3.1.32-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python39-pulp-ansible | 0 | 1:0.16.0-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python39-requests | 0 | 0:2.31.0-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python39-sqlparse | 0 | 0:0.4.4-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | rubygem-rack | 0 | 0:2.2.7-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-cli | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-debug | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-dynflow-sidekiq | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-ec2 | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-journald | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-libvirt | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-openstack | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-ovirt | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-postgresql | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-redis | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-service | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-telemetry | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-vmware | 0 | 0:3.7.0.9-1.el8sat |
| Rocky Linux:8 | pcs | 0 | 0:0.10.15-4.el8_8.1 |
| Rocky Linux:9 | pcs | 0 | 0:0.11.4-7.el9_2 |
| SUSE:Linux Enterprise High Availability Extension 15 SP1 | rubygem-rack | 0 | 2.0.8-150000.3.18.1 |
| SUSE:Linux Enterprise High Availability Extension 15 SP2 | rubygem-rack | 0 | 2.0.8-150000.3.18.1 |
| SUSE:Linux Enterprise High Availability Extension 15 SP3 | rubygem-rack | 0 | 2.0.8-150000.3.18.1 |
| SUSE:Linux Enterprise High Availability Extension 15 SP4 | rubygem-rack | 0 | 2.0.8-150000.3.18.1 |
| SUSE:OpenStack Cloud Crowbar 8 | rubygem-rack | 0 | 1.6.13-3.19.1 |
| SUSE:OpenStack Cloud Crowbar 9 | rubygem-rack | 0 | 1.6.13-3.19.1 |
| Ubuntu:20.04:LTS | ruby-rack | 0 | No fix |
| Ubuntu:22.04:LTS | ruby-rack | 0 | No fix |
| Ubuntu:22.04:LTS | ruby-rack | 0 | 2.1.4-5ubuntu1.1 |
| Ubuntu:23.10 | ruby-rack | 0 | 2.2.4-3ubuntu0.1 |
| Ubuntu:24.04:LTS | ruby-rack | 0 | 2.2.7-1 |
| Ubuntu:24.10 | ruby-rack | 0 | 2.2.7-1 |
| Ubuntu:Pro:14.04:LTS | ruby-rack | 0 | 1.5.2-3+deb8u3ubuntu1~esm7 |
| Ubuntu:Pro:16.04:LTS | ruby-rack | 0 | 1.6.4-3ubuntu0.2+esm5 |
| Ubuntu:Pro:18.04:LTS | ruby-rack | 0 | 1.6.4-4ubuntu0.2+esm5 |
| Ubuntu:Pro:20.04:LTS | ruby-rack | 0 | 2.0.7-2ubuntu0.1+esm4 |
| Ubuntu:Pro:22.04:LTS | ruby-rack | 0 | 2.1.4-5ubuntu1+esm4 |
| gem | rack | 2.0.0 | 2.2.6.4 |
| gem | rack | 3.0.0 | 3.0.6.1 |
| openSUSE:Leap 15.4 | rubygem-rack | 0 | 2.0.8-150000.3.18.1 |
| openSUSE:Tumbleweed | rubygem-rack | 0 | 3.0.7-1.1 |
| openSUSE:Tumbleweed | rubygem-rack | 0 | 3.0.9.1-1.1 |
| openSUSE:Tumbleweed | rubygem-rack | 0 | 3.1.12-1.1 |
| openSUSE:Tumbleweed | rubygem-rack | 0 | 3.1.18-1.3 |
| openSUSE:Tumbleweed | rubygem-rack-2.2 | 0 | 2.2.6.4-1.1 |
| openSUSE:Tumbleweed | rubygem-rack-2.2 | 0 | 2.2.8.1-1.1 |
| openSUSE:Tumbleweed | rubygem-rack-2.2 | 0 | 2.2.11-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-61919 Rack is vulnerable to a memory-exhaustion DoS through unbounded URL-encoded body parsing 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