CVE-2026-54904: concurrent-ruby AtomicReference NaN Infinite Loop DoS
concurrent-ruby, a popular Ruby concurrency library, contains a critical flaw in its AtomicReference#update method. When an AtomicReference contains the special floating-point value NaN (Not-a-Number), calling update() causes the application to enter an infinite retry loop. This happens because NaN has a unique mathematical property: NaN never equals itself, even when compared to itself. The update method keeps retrying indefinitely, consuming CPU resources and potentially freezing requests or background jobs. This affects applications that store numeric data derived from external sources in AtomicReferences and then attempt to update them.
Source data · NVD / CISA · public domain
- CVSS
- 3.1 · 7.5 HIGH · CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
- Weaknesses (CWE)
- CWE-835
- Affected products
- 1 configuration(s)
- Published / Modified
- 2026-06-24 / 2026-06-26
NVD description (verbatim)
concurrent-ruby is a modern concurrency tools for Ruby. Prior to 1.3.7, Concurrent::AtomicReference#update can enter a permanent busy retry loop when the current value is Float::NAN. The issue is caused by the interaction between AtomicReference#update, which retries until compare_and_set(old_value, new_value) succeeds; Numeric compare_and_set, which checks old == old_value before attempting the underlying atomic swap.; and Ruby NaN semantics, where Float::NAN == Float::NAN is always false. As a result, once an AtomicReference contains Float::NAN, calling #update repeatedly evaluates the caller's block and never returns. In services that store externally derived numeric values in an AtomicReference, this can cause CPU exhaustion or permanent request/job hangs. This vulnerability is fixed in 1.3.7.
2 reference(s) · View on NVD →
SEC.co analysis · AI-assisted, reviewed against source
Technical summary
The vulnerability stems from a semantic mismatch between three components: (1) AtomicReference#update, which implements optimistic locking by repeatedly calling compare_and_set() until success; (2) the Numeric compare_and_set implementation, which validates old == old_value before attempting the atomic swap; and (3) IEEE 754 NaN semantics, where Float::NAN == Float::NAN evaluates to false. When an AtomicReference holds Float::NAN, the equality check always fails, the compare_and_set operation never succeeds, and update() never returns—creating a permanent busy-wait loop. This is classified as an Infinite Loop vulnerability (CWE-835). The fix in version 1.3.7 addresses the NaN comparison semantics within the update retry logic.
Business impact
Applications relying on concurrent-ruby for thread-safe numeric operations face two critical risks: denial of service through CPU exhaustion if update() is called on an AtomicReference containing NaN, and request/job hangs if the update operation is performed synchronously in web request handlers or background job workers. This is particularly dangerous in services ingesting external numeric data (APIs, sensors, financial feeds) that may produce NaN values. A single malformed data input could crash or freeze an entire service thread or worker process.
Affected systems
concurrent-ruby versions prior to 1.3.7 are affected. Any Ruby application using the concurrent-ruby gem that stores or processes floating-point numbers in AtomicReference objects and calls the update() method is at risk. The vulnerability is most acute in services that accept external numeric inputs without validation, or in multi-threaded data processing pipelines where NaN values might propagate into atomic references.
Exploitability
Exploitation is straightforward and requires no special privileges or user interaction. An attacker who can influence numeric data flowing into an application using concurrent-ruby (e.g., via API requests, sensor data, or third-party feeds) can deliberately inject NaN values. Once a NaN reaches an AtomicReference, any subsequent update() call will hang. No special attack tools, authentication, or network position is required—only the ability to supply crafted numeric input. The attack surface is broad in data-ingestion applications.
Remediation
Upgrade concurrent-ruby to version 1.3.7 or later immediately. For applications unable to patch immediately, implement input validation to reject or sanitize NaN values before storing them in AtomicReferences. Consider replacing AtomicReference#update with non-retry-based approaches for numeric values if update semantics cannot be avoided. Review all code paths that call update() on AtomicReferences to identify exposure points.
Patch guidance
Apply the upgrade to concurrent-ruby 1.3.7 as part of your next dependency update cycle, prioritizing this above routine patches due to the HIGH severity rating. Verify the upgrade in a staging environment to ensure no other gem dependencies conflict. The patch should be applied to all Ruby applications in your environment that depend on concurrent-ruby, whether directly or transitively. Check your Gemfile.lock and dependency trees for indirect dependencies on concurrent-ruby and ensure the updated version is propagated across the entire fleet.
Detection guidance
Look for applications using concurrent-ruby versions < 1.3.7 via dependency scanning (bundler-audit, Dependabot, or software composition analysis tools). Monitor for increased CPU usage or thread hangs in Ruby processes, especially those handling external numeric data. Enable application-level logging around AtomicReference#update calls and watch for indefinite blocking. In staging, inject NaN test values into numeric fields and verify they do not cause update() hangs. Consider adding a timeout wrapper around update() calls as a temporary detective control.
Why prioritize this
This vulnerability merits immediate attention due to its HIGH CVSS score (7.5), trivial exploitability, and severe impact on availability. Unlike many high-severity vulnerabilities that require specific configurations or user actions, this one is triggered automatically once NaN reaches an AtomicReference, making it a reliable denial-of-service vector. The fix is simple and well-tested, with no known breaking changes in version 1.3.7. Any delay in patching leaves services vulnerable to request hangs and CPU exhaustion.
Risk score, explained
The CVSS 3.1 score of 7.5 (HIGH) reflects: Network-accessible attack vector (AV:N), low attack complexity requiring only crafted input (AC:L), no privileges required (PR:N), no user interaction (UI:N), and a scope limited to the affected service (S:U). The impact is purely on availability (A:H)—requests hang indefinitely—with no confidentiality or integrity impact. The score would be higher if the vulnerability allowed remote code execution, but CPU exhaustion and service degradation alone justify the HIGH rating.
Frequently asked questions
Can this vulnerability be triggered accidentally, or does it require deliberate attack?
Both are possible. Accidental triggers occur when external data sources naturally produce NaN values (e.g., IEEE 754 results from division by zero, or invalid sensor readings). Deliberate attackers can inject NaN by crafting API requests or data feeds. Either way, once NaN enters an AtomicReference, update() will hang regardless of intent.
Does this affect all uses of concurrent-ruby or only AtomicReference#update?
Only AtomicReference#update with NaN is affected. Other concurrent-ruby data structures and methods are not impacted. However, any code path that calls update() on an AtomicReference storing numeric data is a potential exposure point.
What's the performance impact of upgrading to 1.3.7?
The fix is a targeted adjustment to the NaN comparison semantics and should have negligible performance impact. No algorithmic changes were made to the core update retry loop. Testing in the concurrent-ruby project has confirmed compatibility and performance parity.
Can input validation alone protect us if we cannot patch immediately?
Yes, partially. Stripping, rejecting, or replacing NaN values before storing them in AtomicReferences will prevent the hang. However, this is a workaround, not a fix. Patching to 1.3.7 is strongly recommended as soon as possible to eliminate the root cause and reduce code complexity.
This analysis is based on CVE-2026-54904 and the published vulnerability description as of June 2026. CVSS scores reflect the National Vulnerability Database methodology. Organizations should validate patch applicability and test in staging environments before production deployment. No exploit code, proof-of-concept, or weaponized tooling is provided. This vulnerability is not yet listed in CISA's Known Exploited Vulnerabilities catalog, but public awareness and exploit development should be anticipated. Consult the official concurrent-ruby security advisory and your vendor documentation for the most current remediation guidance. Source: NVD (public-domain), retrieved 2026-08-02. Analysis generated by SEC.co (claude-haiku-4-5).
Related vulnerabilities
- CVE-2025-71319HIGHimage-size Denial of Service via Malformed JXL/HEIF Images
- CVE-2025-71329HIGHInfinite Loop DoS in image-size Library—Vulnerability Explanation & Patch Guidance
- CVE-2025-71330HIGHDenial of Service in image-size ICNS Parser
- CVE-2026-44186HIGHApache HTTP Server mod_proxy_ftp Infinite Loop Denial of Service
- CVE-2026-46385HIGHiskorotkov/avro Denial-of-Service via Unbounded Block Iteration
- CVE-2026-46522HIGHImageMagick MIFF Decoder Infinite Loop DoS Vulnerability
- CVE-2026-52933HIGHLinux Kernel io_uring Signed Integer Comparison Privilege Escalation
- CVE-2026-54417HIGHInteger Overflow in rxi microtar Causes Denial of Service