Listen to this Post
Faraday::NestedParamsEncoder, the default nested query parameter encoder and decoder in Faraday, decodes nested query strings without enforcing a maximum nesting depth. A crafted query string such as `a
[x][bash][x]...[bash]=1` causes Faraday to build a deeply nested Ruby Hash structure. The internal `dehash` routine then recursively walks this attacker-controlled structure without any depth limit.
The affected component is `Faraday::NestedParamsEncoder` and <code>Faraday::Utils.parse_nested_query</code>. The vulnerability is triggered when an application passes attacker-controlled or attacker-influenced query strings to one of Faraday's nested parameter parsing or building paths. Confirmed reachable paths include direct use of `Faraday::Utils.parse_nested_query(untrusted_query_string)` and normal Faraday request URL building via <code>conn.build_url("/search?{untrusted_query_string}")</code>. In the second case, the crash occurs during URL construction before any network request is sent.
At sufficient depth, Ruby raises an uncaught `SystemStackError` (stack level too deep), crashing the calling thread or worker. In local tests, a payload of approximately 9.4 KB (depth=3119, bytes=9360) was sufficient to trigger the crash. 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. The issue does not provide remote code execution, authentication bypass, or data disclosure; the confirmed impact is availability loss.
The recursive `dehash` routine walks the structure without a maximum depth check. The affected file is <code>lib/faraday/encoders/nested_params_encoder.rb</code>. The relevant logic is:
[bash]
def dehash(hash, depth)
hash.each do |key, value|
hash[bash] = 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.
DailyCVE Form:
Platform: Faraday
Version: v2.14.2-2-g59334e0
Vulnerability: Uncontrolled Recursion
Severity: High
date: 2026-05-24
Prediction: 2026-06-15
What Undercode Say:
Analytics:
- Attack Vector: Network
- Payload Size: ~9.4 KB (depth 3119)
- Crash Type: SystemStackError (stack level too deep)
- Affected Component: Faraday::NestedParamsEncoder / Faraday::Utils.parse_nested_query
- Reachable Paths: Direct parser call, URL building via build_url
- Tested Ruby Version: 3.2.3
- Tested Commit: 59334e0e9b19
Bash Commands & Codes:
Clone Faraday repository and checkout vulnerable commit git clone https://github.com/lostisland/faraday.git cd faraday git checkout 59334e0e9b19 Run the proof of concept ruby -e "require 'faraday'; payload = 'a' + '[bash]' 3119 + '=1'; Faraday::Utils.parse_nested_query(payload)"
PoC 1: Direct parser crash
require 'faraday'
payload = "a{'[bash]' 3119}=1"
Faraday::Utils.parse_nested_query(payload)
=> SystemStackError: stack level too deep
PoC 2: Normal URL-building crash
require 'faraday'
conn = Faraday.new('https://api.example.com')
payload = "/search?a{'[bash]' 3500}=1"
conn.build_url(payload)
=> SystemStackError
Exploit:
An attacker can craft a query string with deeply nested brackets, such as a
[x][bash]...[bash]=1</code>, and send it to an application that passes user-controlled query strings to Faraday's nested parameter parsing or URL-building paths. The payload size required to trigger stack exhaustion is relatively small—approximately 9.4 KB in the local test environment. The attack requires no authentication or user interaction. The crash occurs during URL construction before any network request is sent, making it trivially exploitable in affected application patterns.
<h2 style="color: blue;">Protection:</h2>
<ul>
<li>Upgrade to a patched version of Faraday once available (the fix is expected to be released in a future 2.x update).</li>
<li>Apply the suggested patch to add a configurable maximum nesting depth to <code>Faraday::NestedParamsEncoder</code>, similar to Rack's <code>param_depth_limit</code>:
[bash]
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:
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
Impact:
- Denial of Service: An attacker can crash the calling Ruby thread or worker with a small payload (~9.4 KB).
- Availability Loss: Repeated requests can cause sustained denial of service against affected applications.
- No RCE/Data Disclosure: The issue does not provide remote code execution, authentication bypass, or data disclosure.
- Library-Wide Exposure: Any application that passes attacker-controlled query strings to Faraday's nested parameter parsing or URL-building paths is vulnerable.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

