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



GHSA-2X79-GWQ3-VXXM

GHSA-2x79-gwq3-vxxm: Infinite Loop Denial of Service in facil.io and iodine JSON Parser

Amit Schendel
Amit Schendel
Senior Security Researcher

Apr 15, 2026·6 min read·11 visits

Executive Summary (TL;DR)

A flaw in the JSON parser of facil.io and iodine causes an infinite loop when parsing malformed numerals starting with 'i' or 'I'. This allows unauthenticated remote attackers to exhaust CPU resources and cause a severe denial of service.

An uncontrolled resource consumption vulnerability in the facil.io C framework and the iodine Ruby gem allows remote attackers to cause a Denial of Service (DoS). The vulnerability is triggered by parsing crafted JSON payloads containing malformed numeral values, resulting in an infinite loop that exhausts CPU resources.

Vulnerability Overview

The vulnerability is located within the fio_json_parse function defined in the fio_json_parser.h header file. This parser functions as the core JSON processing unit for the facil.io C framework, which is designed for high-performance networking applications. The iodine Ruby gem heavily relies on this vendored parser for handling JSON operations in HTTP and WebSocket contexts.

The flaw represents a classic CWE-835: Loop with Unreachable Exit Condition ('Infinite Loop'). When the JSON parser encounters specific malformed inputs, the internal state machine fails to advance the read cursor. The parser continuously attempts to evaluate the same byte sequence without making forward progress or transitioning to an error state.

Attackers exploit this behavior by submitting crafted JSON payloads containing nested structures combined with bare characters like i or I. Because the framework operates as an asynchronous event loop, triggering this infinite loop inside the single-threaded parsing process locks the executing core, rendering the process incapable of handling further requests.

Root Cause Analysis

The root cause originates in the numeral parsing logic implemented between lines 434 and 468 of lib/facil/fiobj/fio_json_parser.h. The parser utilizes an internal state machine to process JSON tokens sequentially. When the parser operates inside an array or object context and identifies a character starting a new value, it checks whether the sequence represents a numerical input.

Upon encountering the characters i or I—often used in systems to denote inf or Infinity—the parser state machine jumps to the numeral: label. At this stage, the parser invokes the fio_atol function, passing a double pointer (char **)&tmp to attempt standard integer conversion. The fio_atol function relies on standard numerical characters to consume the buffer.

When fio_atol processes a bare i character, it successfully consumes zero characters and returns immediately. Crucially, the pointer tmp remains equal to the original position pointer pos. Following this operation, the parser evaluates the condition if (!tmp || JSON_NUMERAL[*tmp]). The lookup table JSON_NUMERAL['i'] evaluates to false (0), bypassing the failure detection branch.

Because the failure branch is bypassed, the parser erroneously concludes that a valid numeric sequence was processed. It executes pos = tmp, updating the main parser position to the exact same memory location it started at. Since the parsing depth remains greater than zero and the end of the buffer has not been reached, the outer while loop restarts, immediately encountering the same i character and repeating the cycle infinitely.

Code Analysis

Analyzing the source code reveals the structural oversight in pointer validation. The vulnerable logic implicitly trusts that the underlying conversion functions (fio_atol and fio_atof) will either advance the memory pointer upon success or that the subsequent character lookup (JSON_NUMERAL) will fail decisively upon error.

The patch addresses this gap by explicitly verifying whether the pointer has moved. The developer introduced a direct comparison between the temporary pointer tmp and the position pointer pos.

--- a/lib/facil/fiobj/fio_json_parser.h
+++ b/lib/facil/fiobj/fio_json_parser.h
@@
        uint8_t *tmp = pos;
        long long i = fio_atol((char **)&tmp);
        if (tmp > limit)
          goto stop;
-       if (!tmp || JSON_NUMERAL[*tmp]) {
+       if (!tmp || tmp == pos || JSON_NUMERAL[*tmp]) {
          tmp = pos;
          double f = fio_atof((char **)&tmp);
          if (tmp > limit)
            goto stop;
-         if (!tmp || JSON_NUMERAL[*tmp])
+         if (!tmp || tmp == pos || JSON_NUMERAL[*tmp])
            goto error;
          fio_json_on_float(parser, f);
          pos = tmp;

By injecting the tmp == pos check, the condition enforces forward progress. If fio_atol or fio_atof consumes zero characters, tmp will equal pos. The logical OR condition will immediately trigger, causing the routine to recognize the invalid input and correctly jump to the error label, terminating the loop and gracefully failing the parse operation.

Exploitation Methodology

Exploitation requires no authentication, specific configurations, or complex interaction chains. An attacker merely needs network access to an endpoint that parses JSON payloads using facil.io or iodine. This typically involves sending an HTTP POST request with the Content-Type: application/json header and a specially crafted body.

The minimal payload required to trigger the vulnerability is simply [i. This string initiates an array and immediately introduces the malformed numeral character. Alternative payloads such as {"a":i or [""i achieve the same outcome by tricking the parser into evaluating the i character as a new value context.

The following Ruby code demonstrates a minimal proof-of-concept for an iodine server. When the Iodine::JSON.parse method is invoked on the request body containing [i, the worker thread immediately locks.

require "iodine"
 
APP = proc do |env|
  body = env["rack.input"].read.to_s
  warn "Parsing JSON: #{body.inspect}"
  Iodine::JSON.parse(body) # Triggers infinite loop on '[i'
  [200, { "Content-Type" => "text/plain" }, ["ok"]]
end
 
Iodine.listen service: :http, port: "3000", handler: APP
Iodine.threads = 1
Iodine.start

To execute the exploit against the vulnerable server, an attacker utilizes standard HTTP clients. The command printf '[i' | curl -X POST --data-binary @- http://127.0.0.1:3000/ dispatches the payload without URL encoding or trailing line breaks, guaranteeing the parser processes the exact bytes required to stall the state machine.

Impact Assessment

The operational impact of this vulnerability is a complete localized Denial of Service. When the infinite loop initiates, the underlying thread consumes 100% of the assigned CPU core's cycles. It will never timeout natively because the thread is actively processing code rather than blocking on I/O.

In architectures like facil.io and iodine which utilize asynchronous event loops, a blocked worker thread ceases processing all other queued connections assigned to that thread. If the application runs a single-threaded event loop, a single malformed request brings down the entire application.

In multi-threaded deployments, an attacker can achieve a total service outage by sending concurrent requests equal to the number of configured worker threads. Once all threads are trapped in the infinite loop parsing [i, the application becomes entirely unresponsive to legitimate traffic. The system administrator must forcefully terminate and restart the process to restore functionality.

Remediation Guidance

The primary remediation strategy requires updating the vulnerable packages to their patched versions. Applications relying on the iodine Ruby gem must upgrade to version greater than 0.7.58. Applications utilizing the facil.io C framework directly must integrate the latest commits from the master branch, specifically ensuring the fio_json_parser.h changes are applied.

For environments where immediate patching is impossible, network-level mitigations can provide temporary defense. Web Application Firewalls (WAFs) can be configured to inspect incoming JSON bodies for the specific byte sequences used in the exploit. Regular expressions targeting \[\s*i or :\s*i can intercept the most common variants of the payload before they reach the application layer.

Developers should verify their deployment architectures include adequate resource monitoring and process supervision. Configuring orchestration tools to health-check the application and restart uncooperative containers can reduce the total downtime during an active attack, though it does not eliminate the underlying vulnerability.

Official Patches

boazsegevOfficial Security Advisory and Patch Details

Technical Appendix

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

Affected Systems

facil.io C framework versions 0.7.5 and 0.7.6iodine Ruby gem versions <= 0.7.58

Affected Versions Detail

Product
Affected Versions
Fixed Version
facil.io
boazsegev
0.7.5, 0.7.6-
iodine
boazsegev
<= 0.7.58> 0.7.58
AttributeDetail
Vulnerability IDGHSA-2x79-gwq3-vxxm
CWECWE-835: Loop with Unreachable Exit Condition ('Infinite Loop')
Attack VectorNetwork
CVSS v4.0 Score8.7 (High)
Exploit StatusProof of Concept Available
ImpactDenial of Service (CPU Exhaustion)

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-835
Loop with Unreachable Exit Condition ('Infinite Loop')

The program contains an iteration or loop with an exit condition that cannot be reached, i.e., an infinite loop.

Known Exploits & Detection

Advisory PoCMinimal curl payload and Ruby testing server configuration.

Vulnerability Timeline

Advisory Published on GitHub
2026-04-14

References & Sources

  • [1]GitHub Security Advisory GHSA-2x79-gwq3-vxxm

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.

More Reports

•about 2 hours ago•CVE-2026-53766
6.1

CVE-2026-53766: Workspace Boundary Bypass in chrome-devtools-mcp via Symbolic Link Resolution Failure

A workspace boundary bypass vulnerability exists in the Chrome DevTools for Agents (chrome-devtools-mcp) Model Context Protocol (MCP) server from version 0.24.0 up to 1.1.0. The vulnerability allows an agent or malicious workspace containing symbolic links to read or modify arbitrary files outside the configured project workspace root directory. This occurs because the path validation function resolves paths lexically rather than physically.

Alon Barad
Alon Barad
2 views•7 min read
•about 3 hours ago•CVE-2026-56677
8.6

CVE-2026-56677: Unauthenticated Server-Side Request Forgery in 9Router OIDC Test Endpoint

A high-severity security vulnerability exists in 9Router, an AI router and token saver dashboard. When dashboard authentication features are disabled or left in default configurations, the application exposes administrative testing routines directly to the public internet. Unauthenticated network adversaries can exploit the OIDC configuration validation endpoint to initiate arbitrary HTTP requests, routing unauthorized traffic to local loops, adjacent container ports, and cloud resource metadata interfaces.

Amit Schendel
Amit Schendel
2 views•5 min read
•about 4 hours ago•CVE-2026-64849
9.3

CVE-2026-64849: Server-Side Request Forgery (SSRF) in MLflow Webhooks via DNS Rebinding

CVE-2026-64849 is a critical Server-Side Request Forgery (SSRF) vulnerability affecting MLflow tracking servers prior to version 3.15.0. It allows unauthenticated remote attackers to bypass outbound request destination filters using DNS rebinding or HTTP redirects. This exposure risks compromising sensitive cloud infrastructure metadata and internal microservices.

Alon Barad
Alon Barad
3 views•5 min read
•about 5 hours ago•CVE-2026-69146
6.5

CVE-2026-69146: Missing Authorization Bypass in MLflow Basic Authentication Middleware

This technical report details a missing authorization vulnerability (CVE-2026-69146 / GHSA-3p64-6gvh-82v5) affecting the MLflow platform from version 3.13.0 to 3.15.0. When MLflow is configured with the built-in basic-auth plugin, authenticated users can bypass run-level UPDATE authorization checks, enabling unauthorized dataset and model lineage metadata injection.

Alon Barad
Alon Barad
2 views•7 min read
•about 6 hours ago•CVE-2026-69148
7.1

CVE-2026-69148: Broken Object Level Authorization (BOLA) in MLflow Model Registry

MLflow prior to version 3.15.0 fails to perform proper authorization checks when registering model versions, allowing authenticated users with access to a registered model to link and access artifacts from runs and models belonging to other users without authorization.

Amit Schendel
Amit Schendel
5 views•7 min read
•about 7 hours ago•CVE-2026-59893
7.5

CVE-2026-59893: Regular Expression Denial of Service in sqlparse Lexer

A high-severity Regular Expression Denial of Service (ReDoS) vulnerability in the sqlparse Python library prior to version 0.6.0 allows unauthenticated remote attackers to trigger CPU exhaustion and application denial of service via crafted SQL inputs containing unmatched dollar-quoted literals or unclosed multiline comments.

Alon Barad
Alon Barad
6 views•6 min read