Skip to content

Commit a6847b0

Browse files
authored
Merge pull request #1260 from jasnow/ghsa-syncbot-2026-10-09-09_28_51
GHSA/SYNC: Two new machanize advisories @simi - Thanks for reviewing and approving this PR.
2 parents b6604fa + c4c4a4d commit a6847b0

2 files changed

Lines changed: 124 additions & 0 deletions

File tree

‎gems/mechanize/CVE-2026-107399.yml‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
gem: mechanize
3+
cve: 2026-107399
4+
ghsa: c6rp-p8xm-4q9f
5+
url: https://nvd.nist.gov/vuln/detail/CVE-2026-107399
6+
title: Mechanize sends credential headers to another origin after
7+
a meta refresh
8+
date: 2026-10-08
9+
description: |
10+
## Summary
11+
12+
`mechanize` applied no trust boundary to a `meta` refresh, so credentials
13+
set through `Mechanize#request_headers=` followed a refresh that
14+
pointed at another origin.
15+
16+
## Details
17+
18+
`Mechanize::HTTP::Agent#response_follow_meta_refresh` fetched the refresh
19+
target with no notion of a crossed origin, so `@request_headers` were
20+
re-applied in full. An attacker who could place a `meta` refresh in a
21+
page the agent fetched — through stored content, an open redirect, or
22+
control of any page in the crawl — collected the same credentials as
23+
through an HTTP redirect, on a code path that had none of the redirect
24+
path's protections.
25+
26+
The refresh fetch passes an empty per-request headers hash, so only
27+
headers set through `Mechanize#request_headers=` were exposed.
28+
29+
This requires `Mechanize#follow_meta_refresh = true`. It is `false`
30+
by default, so an agent in its default configuration is not affected.
31+
Crawlers commonly enable it.
32+
33+
## Impact
34+
35+
An attacker who can place a `meta` refresh in any page the agent fetches
36+
captures bearer tokens and session cookies set through `request_headers=`.
37+
Disclosure only; no integrity or availability impact.
38+
cvss_v3: 6.8
39+
patched_versions:
40+
- ">= 2.14.1"
41+
related:
42+
url:
43+
- https://nvd.nist.gov/vuln/detail/CVE-2026-107399
44+
- https://rubygems.org/gems/mechanize/versions/2.14.1
45+
- https://github.com/sparklemotion/mechanize/releases/tag/v2.14.1
46+
- https://github.com/sparklemotion/mechanize/blob/main/CHANGELOG.md#2141--2026-08-22
47+
- https://github.com/sparklemotion/mechanize/pull/676
48+
- https://github.com/sparklemotion/mechanize/commit/02a1235842d6eda8d4a5a3d8f13aba2cecf52e4f
49+
- https://github.com/sparklemotion/mechanize/commit/84c74df87d15f5d119df268ba6aa79bc1e16a2c3
50+
- https://advisories.gitlab.com/gem/mechanize/CVE-2026-107399
51+
- https://github.com/sparklemotion/mechanize/security/advisories/GHSA-c6rp-p8xm-4q9f
52+
- https://github.com/advisories/GHSA-c6rp-p8xm-4q9f
53+
notes: |
54+
- cvss_v3 from GHSA and nvd.nist.gov URLs.

‎gems/mechanize/CVE-2026-107715.yml‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
gem: mechanize
3+
cve: 2026-107715
4+
ghsa: 2mwr-xjcg-37j7
5+
url: https://nvd.nist.gov/vuln/detail/CVE-2026-107715
6+
title: Mechanize sends credential headers to another host after
7+
an HTTP redirect
8+
date: 2026-10-08
9+
description: |
10+
## Summary
11+
12+
`mechanize` leaked credentials to the redirect target when an HTTP
13+
redirect crossed to another host. Credentials set through
14+
`Mechanize#request_headers=` leaked even when they were `Authorization`.
15+
16+
## Details
17+
18+
Two defects, both in `lib/mechanize/http/agent.rb`.
19+
20+
**1. `Mechanize#request_headers=` bypassed the redirect strip entirely.**
21+
22+
`#request_add_headers` copied `@request_headers` onto every request
23+
unconditionally, with no host check, including the request issued
24+
after a redirect. The strip in `#response_redirect` mutated only
25+
the per-request headers hash and never touched agent state. Because
26+
`request_headers=` is the documented way to set a default credential
27+
for every request, the header the code explicitly protected —
28+
`Authorization` — was the one most likely to leak.
29+
30+
**2. The strip list omitted `Proxy-Authorization` and `Cookie2`.**
31+
32+
Only `CREDENTIAL_HEADERS = ['Authorization']` and
33+
`COOKIE_HEADERS = ['Cookie']` were removed from the per-request
34+
headers hash on a cross-host redirect.
35+
36+
Cookies held in `Mechanize#cookie_jar` and credentials held in
37+
`Mechanize::HTTP::AuthStore` are **not** affected. Both are looked
38+
up per-URI, so they never follow a redirect to a foreign host.
39+
The exposure was limited to headers the caller set by hand.
40+
41+
## Impact
42+
43+
An attacker who controls a redirect target — through an open redirect
44+
on the site being fetched, an attacker-supplied fetch URL, DNS rebinding,
45+
or MITM — captures bearer tokens and session cookies from any
46+
`mechanize` agent that sets credentials through `request_headers=` or
47+
the per-request `headers` argument. Disclosure only; no integrity or
48+
availability impact.
49+
50+
## Credit
51+
52+
Reported by @SnailSploit.
53+
cvss_v3: 6.8
54+
patched_versions:
55+
- ">= 2.14.1"
56+
related:
57+
url:
58+
- https://nvd.nist.gov/vuln/detail/CVE-2026-107715
59+
- https://rubygems.org/gems/mechanize/versions/2.14.1
60+
- https://github.com/sparklemotion/mechanize/releases/tag/v2.14.1
61+
- https://github.com/sparklemotion/mechanize/blob/main/CHANGELOG.md#2141--2026-08-22
62+
- https://github.com/sparklemotion/mechanize/pull/676
63+
- https://github.com/sparklemotion/mechanize/commit/02a1235842d6eda8d4a5a3d8f13aba2cecf52e4f
64+
- https://github.com/sparklemotion/mechanize/commit/94e0902867296be804f36eccbb47acf7d5018745
65+
- https://github.com/sparklemotion/mechanize/commit/ac49abf2869297d83c3b11bbfb8b18e63b588c95
66+
- https://advisories.gitlab.com/gem/mechanize/CVE-2026-107715
67+
- https://github.com/sparklemotion/mechanize/security/advisories/GHSA-2mwr-xjcg-37j7
68+
- https://github.com/advisories/GHSA-2mwr-xjcg-37j7
69+
notes: |
70+
- cvss_v3 from GHSA and nvd.nist.gov URLs.

0 commit comments

Comments
 (0)