CVE-2024-41128
Description
Action Pack is a framework for handling and responding to web requests. Starting in version 3.1.0 and prior to versions 6.1.7.9, 7.0.8.5, 7.1.4.1, and 7.2.1.1, there is a possible ReDoS vulnerability in the query parameter filtering routines of Action Dispatch. Carefully crafted query parameters can cause query parameter filtering to take an unexpected amount of time, possibly resulting in a DoS vulnerability. All users running an affected release should either upgrade to version 6.1.7.9, 7.0.8.5, 7.1.4.1, or 7.2.1.1 or apply the relevant patch immediately. One may use Ruby 3.2 as a workaround. Ruby 3.2 has mitigations for this problem, so Rails applications using Ruby 3.2 or newer are unaffected. Rails 8.0.0.beta1 depends on Ruby 3.2 or greater so is unaffected.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
actionpackRubyGems | >= 3.1.0, < 6.1.7.9 | 6.1.7.9 |
actionpackRubyGems | >= 7.0.0, < 7.0.8.5 | 7.0.8.5 |
actionpackRubyGems | >= 7.1.0, < 7.1.4.1 | 7.1.4.1 |
actionpackRubyGems | >= 7.2.0, < 7.2.1.1 | 7.2.1.1 |
Patches
8b2fbbfbcaa3df61f4ef957f85b5f0da552f6a1f6a13f691efb493bebae1aAvoid backtracking in filtered_query_string
1 file changed · +9 −4
actionpack/lib/action_dispatch/http/filter_parameters.rb+9 −4 modified@@ -73,12 +73,17 @@ def parameter_filter_for(filters) # :doc: ActiveSupport::ParameterFilter.new(filters) end - KV_RE = "[^&;=]+" - PAIR_RE = %r{(#{KV_RE})=(#{KV_RE})} def filtered_query_string # :doc: - query_string.gsub(PAIR_RE) do |_| - parameter_filter.filter($1 => $2).first.join("=") + parts = query_string.split(/([&;])/) + filtered_parts = parts.map do |part| + if part.include?("=") + key, value = part.split("=", 2) + parameter_filter.filter(key => value).first.join("=") + else + part + end end + filtered_parts.join("") end end end
27121e80f6dbAvoid backtracking in filtered_query_string
2 files changed · +18 −6
actionpack/lib/action_dispatch/http/filter_parameters.rb+9 −4 modified@@ -68,12 +68,17 @@ def parameter_filter_for(filters) # :doc: ActiveSupport::ParameterFilter.new(filters) end - KV_RE = "[^&;=]+" - PAIR_RE = %r{(#{KV_RE})=(#{KV_RE})} def filtered_query_string # :doc: - query_string.gsub(PAIR_RE) do |_| - parameter_filter.filter($1 => $2).first.join("=") + parts = query_string.split(/([&;])/) + filtered_parts = parts.map do |part| + if part.include?("=") + key, value = part.split("=", 2) + parameter_filter.filter(key => value).first.join("=") + else + part + end end + filtered_parts.join("") end end end
actionpack/lib/action_dispatch/http/filter_redirect.rb+9 −2 modified@@ -37,9 +37,16 @@ def location_filter_match? def parameter_filtered_location uri = URI.parse(location) unless uri.query.nil? || uri.query.empty? - uri.query.gsub!(FilterParameters::PAIR_RE) do - request.parameter_filter.filter($1 => $2).first.join("=") + parts = uri.query.split(/([&;])/) + filtered_parts = parts.map do |part| + if part.include?("=") + key, value = part.split("=", 2) + request.parameter_filter.filter(key => value).first.join("=") + else + part + end end + uri.query = filtered_parts.join("") end uri.to_s rescue URI::Error
b0fe99fa854eAvoid backtracking in filtered_query_string
1 file changed · +9 −4
actionpack/lib/action_dispatch/http/filter_parameters.rb+9 −4 modified@@ -64,12 +64,17 @@ def parameter_filter_for(filters) # :doc: ActiveSupport::ParameterFilter.new(filters) end - KV_RE = "[^&;=]+" - PAIR_RE = %r{(#{KV_RE})=(#{KV_RE})} def filtered_query_string # :doc: - query_string.gsub(PAIR_RE) do |_| - parameter_filter.filter($1 => $2).first.join("=") + parts = query_string.split(/([&;])/) + filtered_parts = parts.map do |part| + if part.include?("=") + key, value = part.split("=", 2) + parameter_filter.filter(key => value).first.join("=") + else + part + end end + filtered_parts.join("") end end end
b1241f468d1bAvoid backtracking in filtered_query_string
1 file changed · +9 −4
actionpack/lib/action_dispatch/http/filter_parameters.rb+9 −4 modified@@ -58,12 +58,17 @@ def parameter_filter_for(filters) # :doc: ActiveSupport::ParameterFilter.new(filters) end - KV_RE = "[^&;=]+" - PAIR_RE = %r{(#{KV_RE})=(#{KV_RE})} def filtered_query_string # :doc: - query_string.gsub(PAIR_RE) do |_| - parameter_filter.filter($1 => $2).first.join("=") + parts = query_string.split(/([&;])/) + filtered_parts = parts.map do |part| + if part.include?("=") + key, value = part.split("=", 2) + parameter_filter.filter(key => value).first.join("=") + else + part + end end + filtered_parts.join("") end 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
10- github.com/advisories/GHSA-x76w-6vjr-8xgjghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-41128ghsaADVISORY
- access.redhat.com/security/cve/cve-2024-41128nvdWEB
- bugzilla.redhat.com/show_bug.cginvdWEB
- github.com/rails/rails/commit/27121e80f6dbb260f5a9f0452cd8411cb681f075nvdWEB
- github.com/rails/rails/commit/b0fe99fa854ec8ff4498e75779b458392d1560efnvdWEB
- github.com/rails/rails/commit/b1241f468d1b32235f438c2e2203386e6efd3891nvdWEB
- github.com/rails/rails/commit/fb493bebae1a9b83e494fe7edbf01f6167d606fdnvdWEB
- github.com/rails/rails/security/advisories/GHSA-x76w-6vjr-8xgjnvdWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/actionpack/CVE-2024-41128.ymlghsaWEB
News mentions
0No linked articles in our index yet.