---
id: "CVE-2026-125109"
page: "https://infrastack.ai/live/CVE-2026-125109"
kind: "vulnerability"
aliases: ["CVE-2026-125109", "GHSA-2j8w-xcrc-x985"]
title: "`Rack::Request#host_with_port` and `#base_url` return an invalid `Host` verbatim, enabling URL and allowlist bypass."
severity: "medium"
cvss: 4.8
epss: null
exploited: false
status: "open"
category: "package"
products: [{"name": "rack", "fixed": ["3.1.23"], "affected": ">= 3.0, < 3.1.23", "ecosystem": "rubygems"}, {"name": "rack", "fixed": ["3.2.8"], "affected": ">= 3.2, < 3.2.8", "ecosystem": "rubygems"}]
ecosystems: ["rubygems"]
tags: ["cwe-1286", "package", "rack", "ruby", "self-hosted", "sinatra"]
not_affected_if: ["host-allowlist-enforced", "proxy-overwrites-forwarded-host", "rails"]
published_at: "2026-10-30T02:18:58+00:00"
first_seen_at: "2026-11-09T22:53:30+00:00"
updated_at: "2026-11-09T22:57:07+00:00"
sources: [{"source": "ghsa-repo", "url": "https://github.com/rack/rack/security/advisories/GHSA-2j8w-xcrc-x985", "first_seen_at": "2026-11-09T22:53:30+00:00"}, {"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-125109", "first_seen_at": "2026-11-10T00:28:47+00:00"}]
exploit_sources: []
---

# `Rack::Request#host_with_port` and `#base_url` return an invalid `Host` verbatim, enabling URL and allowlist bypass.

Link for people: https://infrastack.ai/live/CVE-2026-125109 (this .md is for agents)

Rack's host_with_port, base_url and url methods return an invalid Host, X-Forwarded-Host or Forwarded value unchanged, so URLs the application builds can carry attacker-chosen characters. An attacker can use this to bypass URL or host allowlist checks and redirect generated links or Location headers.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- rubygems:rack affected >= 3.0, < 3.1.23 fixed 3.1.23
- rubygems:rack affected >= 3.2, < 3.2.8 fixed 3.2.8

## How to check

- Check the rack version in the Gemfile.lock: `bundle exec gem list rack` should show a fixed version.
- Look for code that builds absolute URLs, redirects or origin checks from `req.url`, `req.base_url` or `req.host_with_port` without a host allowlist.
- Confirm whether `Rack::Protection::HostAuthorization` or `config.hosts` is enabled.

## Fix

- rack 3.1 series: `3.1.23`
- rack 3.2 series: `3.2.8`
- Rack 2.2 is not patched by this advisory; the sources say it returns the raw value from every host method.

## Timeline

- 2026-11-09T22:53:30+00:00 ghsa-repo https://github.com/rack/rack/security/advisories/GHSA-2j8w-xcrc-x985
- 2026-11-10T00:28:47+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-125109

## Documents

- [advisory] Maintainer's advisory: github.com https://github.com/rack/rack/security/advisories/GHSA-2j8w-xcrc-x985
- [fix] Patch: github.com https://github.com/rack/rack/commit/4380381a56dc52556a436d6d794c8e18dc8b0565
- [fix] Patch: github.com https://github.com/rack/rack/commit/49386f460286b7346c7003b69a839de782cc8a39
- [fix] Release notes: github.com https://github.com/rack/rack/releases/tag/v3.1.23
- [fix] Release notes: github.com https://github.com/rack/rack/releases/tag/v3.2.8

## From the sources

## Summary

`Rack::Request#host_with_port`, and therefore `#base_url` and `#url`, return the raw authority string when it fails validation. An attacker-controlled `Host`, `X-Forwarded-Host`, or `Forwarded: host=` value containing characters that are not permitted in an authority is embedded verbatim in URLs generated by the application.

This completes the fix for CVE-2026-34835 (GHSA-g2pf-xv49-m2h5), which made `#host` and `#hostname` return `nil` for an invalid authority but left this path unchanged.

## Details

`Rack::Request#host_with_port` splits the authority with `split_authority`. When the `AUTHORITY` pattern does not match, no components are returned and `host_with_port` falls back to returning the unvalidated authority string. `base_url` is `"#{scheme}://#{host_with_port}"` and `url` appends the full path, so both inherit the raw value.

For a request with `Host: evil.com/@legit.com`, `host` returns `nil` while `host_with_port` returns `evil.com/@legit.com` and `base_url` returns `http://evil.com/@legit.com`. A valid `Host` together with an invalid `X-Forwarded-Host` produces the same result, because forwarded headers take priority by default.

## Impact

Applications that build absolute URLs, redirects, or origin-dependent checks from `req.url`, `req.base_url`, or `req.host_with_port`, and that do not enforce a host allowlist, may emit URLs containing attacker-chosen characters such as `@`, `/`, `?`, `#`, spaces, or angle brackets. Generated links and `Location` headers can be redirected through userinfo tricks, string-based URL checks can be bypassed, and markup is reflected where the application does not escape the value. For example, `redirect` in Sinatra behind a proxy that forwards `X-Forwarded-Host` emits the raw invalid authority in `Location`.

Rails overrides these methods in Action Dispatch and is not expected to be affected. Rack 3.1 and 3.2 are affected. Rack 2.2 did not receive the CVE-2026-34835 change and returns the raw value from every host method.

## Mitigation

* Update to a patched version of Rack, in which `host_with_port` returns `nil` for an invalid authority and `base_url` falls back to the server's own name.
* Enforce a host allowlist with `Rack::Protection::HostAuthorization`, `config.hosts` in Rails, or at the reverse proxy, and configure the proxy to overwrite `X-Forwarded-Host` and `Forwarded`.
* Pin the authority with the `rack.request.config` `:authority` key where available.

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
