CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-33169
6.9

CVE-2026-33169: Regular Expression Denial of Service (ReDoS) in ActiveSupport Number Formatting

Amit Schendel
Amit Schendel
Senior Security Researcher

Mar 24, 2026·5 min read·7 visits

PoC Available

Executive Summary (TL;DR)

A ReDoS vulnerability in Rails ActiveSupport number_to_delimited allows unauthenticated attackers to exhaust server CPU resources via excessively long numeric inputs, causing denial of service.

CVE-2026-33169 is a Regular Expression Denial of Service (ReDoS) vulnerability in the ActiveSupport component of Ruby on Rails. The flaw exists within the NumberToDelimitedConverter class, where an inefficient regular expression used for formatting numeric strings exhibits quadratic time complexity. An attacker can trigger this vulnerability by supplying excessively long numeric strings, leading to CPU exhaustion and application denial of service.

Vulnerability Overview

Active Support is a core component of the Ruby on Rails framework that provides utility classes and standard library extensions. The NumberToDelimitedConverter class is responsible for formatting numbers by inserting thousands delimiters. This functionality is commonly exposed via the number_to_delimited and number_with_delimiter helpers in Rails applications.

Prior to the patch, the formatting mechanism relied on a regular expression utilizing a positive lookahead assertion. When processing numeric strings, the Ruby regular expression engine evaluates this pattern against the input. Due to the structure of the lookahead, the evaluation exhibits quadratic time complexity relative to the length of the input string.

An attacker can exploit this behavior by supplying an extremely long string of digits to any application endpoint that eventually passes the input to the vulnerable helper. The resulting regex evaluation forces the Ruby process to consume 100 percent of the available CPU. This blocks the worker from handling other requests, leading to a Denial of Service condition.

Root Cause Analysis

The vulnerability originates from the regex pattern used to identify delimiter insertion points. The original implementation executes a global substitution utilizing a pattern structurally similar to (\d)(?=(\d{3})+(?!\d)). This pattern instructs the engine to find a digit that is followed by one or more groups of three digits, ensuring no trailing digits remain.

In a backtracking regex engine like Onigmo, the positive lookahead forces the engine to scan the remainder of the string for every single character position. For an input string of length N, the engine verifies the trailing groups of three digits approximately N times. Each verification requires scanning up to N/3 characters.

This redundant scanning results in an operational complexity of O(N^2). When processing a benign input of standard length, the performance penalty is negligible. However, when the input length scales to tens or hundreds of thousands of characters, the required operational cycles increase exponentially, saturating the CPU thread executing the request.

Code Analysis

The vulnerable implementation in activesupport/lib/active_support/number_helper/number_to_delimited_converter.rb relied entirely on the string substitution method for default delimiting. The code split the number into left and right fractional parts, then applied the regex to the left part.

def parts
  left, right = number.to_s.split(".")
  left.gsub!(delimiter_pattern) do |digit_to_delimit|
    "#{digit_to_delimit}#{options[:delimiter]}"
  end
  [left, right].compact
end

The patch introduced in commit ec1a0e215efd27a3b3911aae6df978a80f456a49 replaces the regex engine entirely for the default processing path. The new implementation uses a linear-time manual string manipulation algorithm. It calculates the initial offset using modulo arithmetic, extracts the leading characters, and iteratively slices the remaining string into discrete chunks of three.

left_parts = []
offset = left.size % 3
if offset > 0
  left_parts << left[0, offset]
end
(left.size / 3).times do |i|
  left_parts << left[offset + (i * 3), 3]
end
left = left_parts.join(options[:delimiter])

The patch maintains a conditional fallback to the vulnerable logic if a custom delimiter pattern is supplied via options. Applications that allow user-controlled delimiter patterns remain exposed to the ReDoS condition if the custom pattern exhibits similar backtracking behavior.

Exploitation

Exploitation requires identifying an endpoint that processes user-supplied numeric strings through the affected ActiveSupport formatting helpers. Common attack surfaces include e-commerce checkout flows, financial dashboards, or API endpoints handling currency conversions. The attacker does not require authentication if the vulnerable endpoint is public-facing.

The attacker submits a payload consisting of an exceptionally long sequence of digits, typically exceeding 100,000 characters. For example, a POST request to an API endpoint might include a JSON body where a specific amount field contains a continuous string of identical digits.

Upon receiving the payload, the Rails application passes the string to the formatting method. The regular expression engine begins processing the lookahead pattern. The process thread handling the request immediately consumes maximum CPU cycles and remains locked in execution. Concurrent requests to the same worker process will queue and eventually time out.

Impact Assessment

The primary security impact is application unavailability via resource exhaustion. A single maliciously crafted request can lock a Ruby worker process indefinitely. In single-threaded deployments or environments with limited worker pools, a small number of concurrent malicious requests will completely halt application responsiveness.

The vulnerability is classified under CWE-1333 for Inefficient Regular Expression Complexity and CWE-400 for Uncontrolled Resource Consumption. The CVSS 4.0 score of 6.9 reflects the network attack vector and low attack complexity. No specific privileges or user interactions are required to trigger the flaw.

While the vulnerability severely impacts availability, it does not compromise data confidentiality or integrity. The attacker cannot read memory, execute arbitrary code, or modify database records. The impact is strictly limited to the operational state of the targeted Rails application workers.

Remediation

The official remediation is to update the activesupport gem to version 7.2.3.1, 8.0.4.1, or 8.1.2.1. These releases contain the linear-time string manipulation fix. Package managers will typically resolve this by updating the overarching Rails framework dependencies.

If immediate patching is not feasible, developers must validate and truncate numeric input lengths before passing them to rendering views or formatting helpers. Implementing strict maximum length constraints on all numeric fields at the controller or model level prevents the regex engine from processing inputs large enough to cause degradation.

Security engineers must also review the application codebase for custom locale configurations or explicit helper invocations that supply a custom delimiter pattern. Ensure that custom patterns do not use nested quantifiers or positive lookaheads that reintroduce the ReDoS condition via the patched conditional branch.

Official Patches

railsRelease v8.1.2.1
railsRelease v8.0.4.1
railsRelease v7.2.3.1

Fix Analysis (3)

Technical Appendix

CVSS Score
6.9/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N

Affected Systems

Ruby on RailsActiveSupport

Affected Versions Detail

Product
Affected Versions
Fixed Version
activesupport
rails
< 7.2.3.1-
activesupport
rails
>= 8.0.0.beta1, < 8.0.4.1-
activesupport
rails
>= 8.1.0.beta1, < 8.1.2.1-
AttributeDetail
CWE IDCWE-1333, CWE-400
Attack VectorNetwork
CVSS 4.06.9
ImpactDenial of Service (DoS)
Exploit StatusPoC (Payload generation is trivial)
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-1333
Inefficient Regular Expression Complexity

The software uses a regular expression with a complexity that can lead to excessive resource consumption when evaluating crafted input.

Known Exploits & Detection

NucleiDetection Template Available

Vulnerability Timeline

Fix commits authored by Jean Boussier
2026-03-04
GHSA-cg4j-q9v8-6v38 published by the Rails security team
2026-03-23
CVE-2026-33169 published in the NVD
2026-03-24
Official releases 8.1.2.1, 8.0.4.1, 7.2.3.1 made available
2026-03-24

References & Sources

  • [1]GitHub Security Advisory for GHSA-cg4j-q9v8-6v38
  • [2]CVE Record CVE-2026-33169
  • [3]NVD Details for CVE-2026-33169

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.