{"id":"GHSA-m875-3xf6-mf78","summary":"unpoly-rails Denial of Service vulnerability","details":"There is a possible Denial of Service (DoS) vulnerability in the unpoly-rails gem that implements the [Unpoly server protocol](https://unpoly.com/up.protocol) for Rails applications.\n\n### Impact\n\nThis issues affects Rails applications that operate as an upstream of a load balancer's that uses [passive health checks](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/#passive-health-checks).\n\nThe [unpoly-rails](https://github.com/unpoly/unpoly-rails/) gem echoes the request URL as an `X-Up-Location` response header. By making a request with exceedingly long URLs (paths or query string), an attacker can cause unpoly-rails to write a exceedingly large response header.\n\nIf the response header is too large to be parsed by a load balancer downstream of the Rails application, it may cause the load balancer to remove the upstream from a load balancing group. This causes that application instance to become unavailable until a configured timeout is reached or until an active healthcheck succeeds.\n\n\n### Patches\n\nThe fixed release 2.7.2.2+ is available via RubyGems and GitHub.\n\n\n### Workarounds\n\nIf you cannot upgrade to a fixed release, several workarounds are available:\n\n- Configure your load balancer to use active health checks, e.g. by periodically requesting a route with a known response that indicates healthiness.\n- Configure your load balancer so the [maximum size of response headers](https://makandracards.com/operations/537537-nginx-proxy-buffer-tuning) is at least twice the [maximum size of a URL](https://tryhexadecimal.com/guides/http/414-request-uri-too-long).\n- Instead of changing your server configuration you may also configure your Rails application to delete redundant `X-Up-Location` headers set by unpoly-rails:\n  \n  ```ruby\n  class ApplicationController \u003c ActionController::Base\n  \n    after_action :remove_redundant_up_location_header\n    \n    private\n    \n    def remove_redundant_up_location_header\n      if request.original_url == response.headers['X-Up-Location']\n        response.headers.delete('X-Up-Location')\n      end\n    end\n  \n  end\n  ```","aliases":["CVE-2023-28846"],"modified":"2026-09-10T03:49:52.979637587Z","published":"2023-03-30T22:58:38Z","database_specific":{"nvd_published_at":"2023-03-30T20:15:00Z","cwe_ids":["CWE-400"],"severity":"MODERATE","github_reviewed":true,"github_reviewed_at":"2023-03-30T22:58:38Z"},"references":[{"type":"WEB","url":"https://github.com/unpoly/unpoly-rails/security/advisories/GHSA-m875-3xf6-mf78"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2023-28846"},{"type":"WEB","url":"https://github.com/unpoly/unpoly-rails/commit/cd9ad0007daceeb3b2354fdcab4f88350427bf16"},{"type":"WEB","url":"https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/#passive-health-checks"},{"type":"WEB","url":"https://github.com/rubysec/ruby-advisory-db/blob/master/gems/unpoly-rails/CVE-2023-28846.yml"},{"type":"PACKAGE","url":"https://github.com/unpoly/unpoly-rails"},{"type":"WEB","url":"https://makandracards.com/operations/537537-nginx-proxy-buffer-tuning"},{"type":"WEB","url":"https://tryhexadecimal.com/guides/http/414-request-uri-too-long"},{"type":"WEB","url":"https://unpoly.com/up.protocol"}],"affected":[{"package":{"name":"unpoly-rails","ecosystem":"RubyGems","purl":"pkg:gem/unpoly-rails"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.7.2.2"}]}],"versions":["0.20.0","0.21.0","0.22.0","0.22.1","0.23.0","0.24.0","0.24.1","0.25.0","0.25.1","0.25.2","0.26.0","0.26.1","0.26.2","0.27.0","0.27.1","0.27.2","0.27.3","0.28.0","0.28.1","0.29.0","0.30.0","0.30.1","0.31.0","0.31.1","0.31.2","0.32.0","0.33.0","0.34.0","0.34.1","0.34.2","0.35.0","0.35.1","0.35.2","0.36.0","0.36.1","0.36.2","0.37.0","0.50.0","0.50.1","0.50.2","0.51.0","0.51.1","0.52.0","0.53.0","0.53.1","0.53.2","0.53.3","0.53.4","0.54.0","0.54.1","0.55.0","0.55.1","0.56.0","0.56.1","0.56.2","0.56.3","0.56.4","0.56.5","0.56.6","0.56.7","0.57.0","0.60.0","0.60.1","0.60.2","0.60.3","0.61.0","0.61.1","0.62.0","0.62.1","1.0.0","1.0.1","1.0.3","2.0.0","2.0.0.pre.rc10","2.0.0.pre.rc11","2.0.0.pre.rc2","2.0.0.pre.rc3","2.0.0.pre.rc4","2.0.0.pre.rc5","2.0.0.pre.rc6","2.0.0.pre.rc7","2.0.0.pre.rc8","2.0.0.pre.rc9","2.0.1","2.1.0","2.2.0","2.2.0.pre.rc1","2.2.1","2.3.0","2.4.0","2.4.1","2.5.0","2.5.1","2.5.2","2.5.3","2.6.0","2.6.1","2.7.1","2.7.1.1","2.7.2","2.7.2.1"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2023/03/GHSA-m875-3xf6-mf78/GHSA-m875-3xf6-mf78.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H"}]}