Rack QueryParser has an unsafe default allowing params_limit bypass via semicolon-separated parameters
Description
Rack is a modular Ruby web server interface. Prior to version 2.2.18, Rack::QueryParser enforces its params_limit only for parameters separated by &, while still splitting on both & and ;. As a result, attackers could use ; separators to bypass the parameter count limit and submit more parameters than intended. Applications or middleware that directly invoke Rack::QueryParser with its default configuration (no explicit delimiter) could be exposed to increased CPU and memory consumption. This can be abused as a limited denial-of-service vector. This issue has been patched in version 2.2.18.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
rackRubyGems | < 2.2.18 | 2.2.18 |
Affected products
1Patches
154e4ffdd5affUnbounded parameter parsing in `Rack::QueryParser`.
3 files changed · +12 −1
CHANGELOG.md+4 −0 modified@@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. For info on how to format all future additions to this file please reference [Keep A Changelog](https://keepachangelog.com/en/1.0.0/). +## [2.2.18] - 2025-09-25 + +- [CVE-2025-59830](https://github.com/rack/rack/security/advisories/GHSA-625h-95r8-8xpm) Unbounded parameter parsing in `Rack::QueryParser` can lead to memory exhaustion via semicolon-separated parameters. + ## [2.2.17] - 2025-06-03 - Backport `Rack::MediaType#params` now handles parameters without values. ([#2263](https://github.com/rack/rack/pull/2263), [@AllyMarthaJ](https://github.com/AllyMarthaJ))
lib/rack/query_parser.rb+1 −1 modified@@ -188,7 +188,7 @@ def check_query_string(qs, sep) raise QueryLimitError, "total query size (#{qs.bytesize}) exceeds limit (#{@bytesize_limit})" end - if (param_count = qs.count(sep.is_a?(String) ? sep : '&')) >= @params_limit + if (param_count = qs.count(sep.is_a?(String) ? sep : '&;')) >= @params_limit raise QueryLimitError, "total number of query parameters (#{param_count+1}) exceeds limit (#{@params_limit})" end
test/spec_query_parser.rb+7 −0 modified@@ -29,5 +29,12 @@ proc { query_parser.parse_query("a=a&b=b&c=c") }.must_raise Rack::QueryParser::QueryLimitError proc { query_parser.parse_nested_query("a=a&b=b&c=c", '&') }.must_raise Rack::QueryParser::QueryLimitError proc { query_parser.parse_query("b[]=a&b[]=b&b[]=c") }.must_raise Rack::QueryParser::QueryLimitError + + query_parser.parse_query("a=a;b=b").must_equal({"a" => "a", "b" => "b"}) + query_parser.parse_nested_query("a=a;b=b").must_equal({"a" => "a", "b" => "b"}) + query_parser.parse_nested_query("a=a;b=b", ';').must_equal({"a" => "a", "b" => "b"}) + proc { query_parser.parse_query("a=a;b=b;c=c") }.must_raise Rack::QueryParser::QueryLimitError + proc { query_parser.parse_nested_query("a=a;b=b;c=c", ';') }.must_raise Rack::QueryParser::QueryLimitError + proc { query_parser.parse_query("b[]=a;b[]=b;b[]=c") }.must_raise Rack::QueryParser::QueryLimitError end end
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-625h-95r8-8xpmghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-59830ghsaADVISORY
- github.com/rack/rack/commit/54e4ffdd5affebcb0c015cc6ae74635c0831ed71ghsax_refsource_MISCWEB
- github.com/rack/rack/security/advisories/GHSA-625h-95r8-8xpmghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.