From c4c4a4df654917474c2cdd58bcab924f48445c13 Mon Sep 17 00:00:00 2001 From: Al Snow <43523+jasnow@users.noreply.github.com> Date: Fri, 9 Oct 2026 10:09:39 -0400 Subject: [PATCH] GHSA/SYNC: Two new machanize advisories --- gems/mechanize/CVE-2026-107399.yml | 54 +++++++++++++++++++++++ gems/mechanize/CVE-2026-107715.yml | 70 ++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 gems/mechanize/CVE-2026-107399.yml create mode 100644 gems/mechanize/CVE-2026-107715.yml diff --git a/gems/mechanize/CVE-2026-107399.yml b/gems/mechanize/CVE-2026-107399.yml new file mode 100644 index 0000000000..6472196f52 --- /dev/null +++ b/gems/mechanize/CVE-2026-107399.yml @@ -0,0 +1,54 @@ +--- +gem: mechanize +cve: 2026-107399 +ghsa: c6rp-p8xm-4q9f +url: https://nvd.nist.gov/vuln/detail/CVE-2026-107399 +title: Mechanize sends credential headers to another origin after + a meta refresh +date: 2026-10-08 +description: | + ## Summary + + `mechanize` applied no trust boundary to a `meta` refresh, so credentials + set through `Mechanize#request_headers=` followed a refresh that + pointed at another origin. + + ## Details + + `Mechanize::HTTP::Agent#response_follow_meta_refresh` fetched the refresh + target with no notion of a crossed origin, so `@request_headers` were + re-applied in full. An attacker who could place a `meta` refresh in a + page the agent fetched — through stored content, an open redirect, or + control of any page in the crawl — collected the same credentials as + through an HTTP redirect, on a code path that had none of the redirect + path's protections. + + The refresh fetch passes an empty per-request headers hash, so only + headers set through `Mechanize#request_headers=` were exposed. + + This requires `Mechanize#follow_meta_refresh = true`. It is `false` + by default, so an agent in its default configuration is not affected. + Crawlers commonly enable it. + + ## Impact + + An attacker who can place a `meta` refresh in any page the agent fetches + captures bearer tokens and session cookies set through `request_headers=`. + Disclosure only; no integrity or availability impact. +cvss_v3: 6.8 +patched_versions: + - ">= 2.14.1" +related: + url: + - https://nvd.nist.gov/vuln/detail/CVE-2026-107399 + - https://rubygems.org/gems/mechanize/versions/2.14.1 + - https://github.com/sparklemotion/mechanize/releases/tag/v2.14.1 + - https://github.com/sparklemotion/mechanize/blob/main/CHANGELOG.md#2141--2026-08-22 + - https://github.com/sparklemotion/mechanize/pull/676 + - https://github.com/sparklemotion/mechanize/commit/02a1235842d6eda8d4a5a3d8f13aba2cecf52e4f + - https://github.com/sparklemotion/mechanize/commit/84c74df87d15f5d119df268ba6aa79bc1e16a2c3 + - https://advisories.gitlab.com/gem/mechanize/CVE-2026-107399 + - https://github.com/sparklemotion/mechanize/security/advisories/GHSA-c6rp-p8xm-4q9f + - https://github.com/advisories/GHSA-c6rp-p8xm-4q9f +notes: | + - cvss_v3 from GHSA and nvd.nist.gov URLs. diff --git a/gems/mechanize/CVE-2026-107715.yml b/gems/mechanize/CVE-2026-107715.yml new file mode 100644 index 0000000000..9569cc4053 --- /dev/null +++ b/gems/mechanize/CVE-2026-107715.yml @@ -0,0 +1,70 @@ +--- +gem: mechanize +cve: 2026-107715 +ghsa: 2mwr-xjcg-37j7 +url: https://nvd.nist.gov/vuln/detail/CVE-2026-107715 +title: Mechanize sends credential headers to another host after + an HTTP redirect +date: 2026-10-08 +description: | + ## Summary + + `mechanize` leaked credentials to the redirect target when an HTTP + redirect crossed to another host. Credentials set through + `Mechanize#request_headers=` leaked even when they were `Authorization`. + + ## Details + + Two defects, both in `lib/mechanize/http/agent.rb`. + + **1. `Mechanize#request_headers=` bypassed the redirect strip entirely.** + + `#request_add_headers` copied `@request_headers` onto every request + unconditionally, with no host check, including the request issued + after a redirect. The strip in `#response_redirect` mutated only + the per-request headers hash and never touched agent state. Because + `request_headers=` is the documented way to set a default credential + for every request, the header the code explicitly protected — + `Authorization` — was the one most likely to leak. + + **2. The strip list omitted `Proxy-Authorization` and `Cookie2`.** + + Only `CREDENTIAL_HEADERS = ['Authorization']` and + `COOKIE_HEADERS = ['Cookie']` were removed from the per-request + headers hash on a cross-host redirect. + + Cookies held in `Mechanize#cookie_jar` and credentials held in + `Mechanize::HTTP::AuthStore` are **not** affected. Both are looked + up per-URI, so they never follow a redirect to a foreign host. + The exposure was limited to headers the caller set by hand. + + ## Impact + + An attacker who controls a redirect target — through an open redirect + on the site being fetched, an attacker-supplied fetch URL, DNS rebinding, + or MITM — captures bearer tokens and session cookies from any + `mechanize` agent that sets credentials through `request_headers=` or + the per-request `headers` argument. Disclosure only; no integrity or + availability impact. + + ## Credit + + Reported by @SnailSploit. +cvss_v3: 6.8 +patched_versions: + - ">= 2.14.1" +related: + url: + - https://nvd.nist.gov/vuln/detail/CVE-2026-107715 + - https://rubygems.org/gems/mechanize/versions/2.14.1 + - https://github.com/sparklemotion/mechanize/releases/tag/v2.14.1 + - https://github.com/sparklemotion/mechanize/blob/main/CHANGELOG.md#2141--2026-08-22 + - https://github.com/sparklemotion/mechanize/pull/676 + - https://github.com/sparklemotion/mechanize/commit/02a1235842d6eda8d4a5a3d8f13aba2cecf52e4f + - https://github.com/sparklemotion/mechanize/commit/94e0902867296be804f36eccbb47acf7d5018745 + - https://github.com/sparklemotion/mechanize/commit/ac49abf2869297d83c3b11bbfb8b18e63b588c95 + - https://advisories.gitlab.com/gem/mechanize/CVE-2026-107715 + - https://github.com/sparklemotion/mechanize/security/advisories/GHSA-2mwr-xjcg-37j7 + - https://github.com/advisories/GHSA-2mwr-xjcg-37j7 +notes: | + - cvss_v3 from GHSA and nvd.nist.gov URLs.