CVE-2023-22796
High · 7.5CVSS
7.5
EPSS
1.7%
Published
Feb 9, 2023
CISA due date
—
Cloudanix analysis
A flaw in a common Ruby application component can let someone knock an affected service offline by sending specially crafted input.
- 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
This is a regular-expression denial-of-service vulnerability in the Active Support `underscore` method. When a specially crafted string is passed to `underscore`, the underlying Ruby regular expression engine can perform catastrophic backtracking, consuming excessive CPU and memory. Because the CVSS vector indicates network reachability, low complexity, no privileges, and no user interaction, applications that pass attacker-controlled input into affected Active Support code paths may be remotely forced into high resource consumption and service degradation. The impact is availability-only; it does not directly provide code execution, data disclosure, or data modification.
Why it matters to the business
An affected application can be made slow or unavailable by crafted input, potentially causing failed transactions, degraded user experience, increased infrastructure costs from resource exhaustion, and operational incidents requiring scaling or restarts. Although this issue is not listed in CISA KEV and has low EPSS, it is old enough that mature remediation should already be in place, and internet-facing Ruby on Rails or Active Support services should treat lingering exposure as technical debt with availability risk.
How an attack unfolds
An attacker first identifies an application endpoint or background processing path that accepts attacker-controlled strings and eventually calls Active Support's `underscore` method on that input, either directly or through framework/application logic. The attacker then submits a deliberately malformed or unusually structured string designed to trigger catastrophic backtracking in the vulnerable regular expression. The Ruby process spends disproportionate time evaluating the expression, driving CPU utilization high and potentially increasing memory pressure. By sending one or more such requests, the attacker can tie up application workers, exhaust process resources, increase latency, and cause denial of service. No authentication or user interaction is required if the vulnerable input path is externally reachable.
How to fix it
Upgrade Active Support/Rails to a fixed release. For the affected branches described, use Active Support 6.1.7.1 or later for the 6.1 line, and Active Support 7.0.4.1 or later for the 7.0 line. If Active Support is pulled in through Rails, upgrade the Rails dependency set to a release that includes the fixed Active Support version. Run dependency resolution carefully so `Gemfile.lock` no longer pins a vulnerable `activesupport` version. If immediate upgrade is not possible, reduce exposure by rejecting or bounding excessively long untrusted strings before they reach normalization routines, applying request/body size limits, rate limiting unauthenticated endpoints, adding worker timeouts, and isolating expensive background processing from user-facing request workers. Mitigations reduce exploitability but should not replace upgrading.
How to confirm the fix worked
Confirm the deployed dependency inventory shows `activesupport` at 6.1.7.1 or later, 7.0.4.1 or later, or another non-vulnerable supported release. Review `Gemfile.lock`, software composition analysis results, container image SBOMs, and deployed artifact manifests rather than only source manifests. Restart or redeploy application processes after upgrading so the fixed gem is loaded. Validate that application endpoints handling untrusted strings enforce length limits and that request rate limits and worker timeouts are active. In staging, use safe performance tests with representative long malformed strings to confirm requests are rejected or handled quickly and do not cause sustained CPU spikes.
Typical attack path
- Identify a Ruby/Rails application or service using a vulnerable Active Support version before 6.1.7.1 or before 7.0.4.1.
- Find an externally reachable parameter, API field, header, route segment, uploaded metadata field, or job input that is normalized or transformed using `underscore`.
- Send a specially crafted long or complex string that causes the vulnerable regular expression to backtrack catastrophically.
- Repeat requests or submit concurrent payloads to consume application worker CPU and memory.
- Cause elevated latency, worker exhaustion, failed health checks, process restarts, or service unavailability.
How to detect it
There is no reliable public, CVE-specific payload indicator for confirmed exploitation because the malicious string depends on how an application passes input to `underscore`. To investigate possible prior exploitation, review web access logs, API gateway logs, reverse proxy logs, WAF events, application logs, APM traces, and infrastructure metrics for periods of sudden Ruby process CPU saturation, memory growth, request latency, 499/500/502/503/504 errors, worker timeouts, or restarts that correlate with requests containing unusually long, repetitive, or malformed string parameters. Focus on unauthenticated endpoints and requests with oversized path segments, query parameters, JSON fields, form fields, headers, or metadata that are later normalized by application code. In Ruby/Rails telemetry, look for repeated slow requests where application time is high but database and external service time are low. Correlate suspicious request source IPs, user agents, and payload shapes across logs. Also review dependency history to determine whether the vulnerable Active Support version was deployed during the suspicious time window.
What your security team should do
- Inventory Ruby applications, Rails services, containers, and background workers for vulnerable `activesupport` versions.
- Prioritize internet-facing, unauthenticated, API-heavy, or multi-tenant services where attacker-controlled strings may reach Active Support transformations.
- Upgrade to Active Support 6.1.7.1 or later, 7.0.4.1 or later, or a current supported Rails release that includes the fix.
- Verify deployed artifacts and lockfiles after remediation; do not rely solely on package manifest intent.
- Add application-layer input length validation and rate limiting on unauthenticated endpoints as defense in depth.
- Monitor for unexplained Ruby worker CPU saturation, memory pressure, request timeouts, 5xx spikes, and repeated long malformed input patterns.
- Ensure autoscaling, process supervision, and health checks are configured to recover from worker exhaustion without cascading failure.
The record
A regular expression based DoS vulnerability in Active Support <6.1.7.1 and <7.0.4.1. A specially crafted string passed to the underscore method can cause the regular expression engine to enter a state of catastrophic backtracking. This can cause the process to use large amounts of CPU and memory, leading to a possible DoS vulnerability.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| RubyGems | activesupport | 0 | 6.1.7.1 |
| RubyGems | activesupport | 7.0.0 | 7.0.4.1 |
| Debian:11 | rails | 0 | 2:6.0.3.7+dfsg-2+deb11u1 |
| Debian:12 | rails | 0 | 2:6.1.7.3+dfsg-1 |
| Debian:13 | rails | 0 | 2:6.1.7.3+dfsg-1 |
| 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 |
| SUSE:Linux Enterprise High Availability Extension 15 SP1 | rubygem-activesupport-5_1 | 0 | 5.1.4-150000.3.12.1 |
| SUSE:Linux Enterprise High Availability Extension 15 SP2 | rubygem-activesupport-5_1 | 0 | 5.1.4-150000.3.12.1 |
| SUSE:Linux Enterprise High Availability Extension 15 SP3 | rubygem-activesupport-5_1 | 0 | 5.1.4-150000.3.12.1 |
| SUSE:Linux Enterprise High Availability Extension 15 SP4 | rubygem-activesupport-5_1 | 0 | 5.1.4-150000.3.12.1 |
| SUSE:OpenStack Cloud Crowbar 8 | rubygem-activesupport-4_2 | 0 | 4.2.9-7.15.1 |
| SUSE:OpenStack Cloud Crowbar 9 | rubygem-activesupport-4_2 | 0 | 4.2.9-7.15.1 |
| Ubuntu:20.04:LTS | rails | 0 | No fix |
| Ubuntu:22.04:LTS | rails | 0 | No fix |
| Ubuntu:24.04:LTS | rails | 0 | No fix |
| Ubuntu:24.10 | rails | 0 | No fix |
| Ubuntu:25.04 | rails | 0 | No fix |
| Ubuntu:25.10 | rails | 0 | No fix |
| Ubuntu:Pro:16.04:LTS | rails | 0 | No fix |
| Ubuntu:Pro:18.04:LTS | rails | 0 | No fix |
| Ubuntu:Pro:20.04:LTS | rails | 0 | No fix |
| Ubuntu:Pro:22.04:LTS | rails | 0 | No fix |
| gem | activesupport | 7.0.0 | 7.0.4.1 |
| openSUSE:Leap 15.4 | rubygem-activesupport-5_1 | 0 | 5.1.4-150000.3.12.1 |
| openSUSE:Tumbleweed | rubygem-activesupport-7.0 | 0 | 7.0.4.1-1.1 |
| openSUSE:Tumbleweed | rubygem-activesupport-7.0 | 0 | 7.0.8.6-1.3 |
| openSUSE:Tumbleweed | rubygem-activesupport-7.0 | 0 | 7.0.8.4-1.1 |
Related vulnerabilities
- CVE-2023-28120 There is a vulnerability in ActiveSupport if the new bytesplice method is called on a… Also affects activesupport
- CVE-2023-38037 ActiveSupport::EncryptedFile writes contents that will be encrypted to a temporary file. Also affects activesupport
- CVE-2013-0333 lib/active_support/json/backends/yaml.rb in Ruby on Rails 2.3.x before 2.3.16 and 3.0.x… Also affects activesupport
- CVE-2025-55193 Active Record connects classes to relational database tables. Also affects rails
- CVE-2023-23913 There is a potential DOM based cross-site scripting issue in rails-ujs which leverages… Also affects rails
- CVE-2023-28362 The redirect_to method in Rails allows provided values to contain characters which are… Also affects rails
- CVE-2024-54133 Action Pack is a framework for handling and responding to web requests. Also affects rails
- CVE-2024-47889 Action Mailer is a framework for designing email service layers. Also affects rails