{
  "ticket_id": "CVE-2026-25765",
  "code_root": "external/faraday",
  "source": {
    "type": "cve",
    "cve_id": "CVE-2026-25765",
    "advisory_id": "GHSA-33mh-2634-fwr2",
    "advisory_url": "https://github.com/lostisland/faraday/security/advisories/GHSA-33mh-2634-fwr2",
    "vendor": "lostisland",
    "product": "faraday",
    "repo": "https://github.com/lostisland/faraday"
  },
  "facts": {
    "cve_id": "CVE-2026-25765",
    "advisory_id": "GHSA-33mh-2634-fwr2",
    "issue_summary": "SSRF in faraday. build_exclusive_url uses Ruby's URI#merge to combine the connection base URL with a request path. Per RFC 3986 a protocol-relative URL ('//evil.com/path') is a network-path reference that overrides the base URL's authority. A user-controlled path passed to get()/post() therefore redirects the request to an attacker-chosen host instead of the configured base host.",
    "vulnerability_type": "Server-Side Request Forgery",
    "suspected_cwe": ["CWE-918"],
    "affected_versions": "1.0.0 - 1.10.4 and 2.0.0 - 2.14.0",
    "fixed_versions": ["1.10.5", "2.14.1"],
    "reproduce_version": "2.14.0",
    "verify_fixed_version": "2.14.1",
    "repo_url": "https://github.com/lostisland/faraday.git",
    "fix_commit": "a6d3a3a0bf59c2ab307d0abd91bc126aef5561bc",
    "code_root": "external/faraday",
    "ecosystem": "rubygems",
    "package": "faraday",
    "affected_functions": ["build_exclusive_url"],
    "install_recipe": "In a scratch directory run `gem install faraday -v 2.14.0` (vulnerable) or `gem install faraday -v 2.14.1` (fixed). The published RubyGems gem is the canonical artifact; git tags v2.14.0 / v2.14.1 on the repo are equivalent.",
    "attacker_access": "Any code path that forwards an attacker-influenced request path into a Faraday connection's get()/post() while the base URL is a trusted host.",
    "exploit_outline": "Build a Faraday connection with base URL `http://safe.local`, then issue a request whose path is a protocol-relative URL such as `//127.0.0.1:<port>/x`. build_exclusive_url merges it via URI#merge, and the protocol-relative authority overrides the base host.",
    "vulnerable_indicator": "The request is resolved to the attacker-chosen host: a local listener on `127.0.0.1:<port>` receives the request even though the base URL was `http://safe.local`.",
    "fixed_indicator": "In 1.10.5 / 2.14.1 the request stays bound to the base host (`safe.local`); the protocol-relative path no longer overrides the authority.",
    "reproduction_requirements": "Ruby plus the faraday gem at the specified version. A minimal local TCP/HTTP listener bound to 127.0.0.1 is used as the attacker host to observe whether the request lands there. No external network, database, or browser required.",
    "notes": "Do not invent specific version numbers beyond those stated here. The fix commit is a6d3a3a0bf59c2ab307d0abd91bc126aef5561bc. The Pruva repro agent reads the patch diff itself (git diff v2.14.0..v2.14.1, or git show a6d3a3a0bf59c2ab307d0abd91bc126aef5561bc) to confirm the root cause and guard."
  }
}
