CVE-2026-107715
Mechanize sends credential headers to another host after an HTTP redirect
The Mechanize library is used for automating interaction with websites. Prior to 2.14.1, Mechanize sends caller-supplied credential headers to a different host after an HTTP redirect. Mechanize#request_headers= is reapplied by Mechanize::HTTP::Agent#request_add_headers even after Mechanize::HTTP::Agent#response_redirect strips per-request headers, and the protected header lists omit Proxy-Authorization and Cookie2. An attacker who controls a redirect target can capture bearer tokens or session cookies supplied through request_headers= or the per-request headers argument, while Mechanize#cookie_jar and Mechanize::HTTP::AuthStore are not affected. This issue is fixed in version 2.14.1.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
6.8
Mechanize sends credential headers to another host after an HTTP redirect
The Mechanize library is used for automating interaction with websites. Prior to 2.14.1, Mechanize sends caller-supplied credential headers to a different host after an HTTP redirect. Mechanize#request_headers= is reapplied by Mechanize::HTTP::Agent#request_add_headers even after Mechanize::HTTP::Agent#response_redirect strips per-request headers, and the protected header lists omit Proxy-Authorization and Cookie2. An attacker who controls a redirect target can capture bearer tokens or session cookies supplied through request_headers= or the per-request headers argument, while Mechanize#cookie_jar and Mechanize::HTTP::AuthStore are not affected. This issue is fixed in version 2.14.1.
- Record
CVE-2026-107715- CVSS 3.1
- 6.8 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N - Weakness
- CWE-200, CWE-522
- Updated
- 2026-11-02
EUVDEUVD-2026-95321
6.8
The Mechanize library is used for automating interaction with websites. Prior to 2.14.1, Mechanize sends caller-supplied credential headers to a different host after an HTTP redirect. Mechanize#request_headers= is reapplied by Mechanize::HTTP::Agent#request_add_headers even after Mechanize::HTTP::Agent#response_redirect strips per-request headers, and the protected header lists omit Proxy-Authorization and Cookie2. An attacker who controls a redirect target can capture bearer tokens or session cookies supplied through request_headers= or the per-request headers argument, while Mechanize#cookie_jar and Mechanize::HTTP::AuthStore are not affected. This issue is fixed in version 2.14.1.
- Record
EUVD-2026-95321- CVSS 3.1
- 6.8 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-2mwr-xjcg-37j7
6.8
Mechanize sends credential headers to another host after an HTTP redirect
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.
PoC
agent = Mechanize.new
agent.request_headers = { 'Authorization' => 'Bearer secret' }
agent.get('https://example.test/redirects-to-attacker')
# the request to the attacker's host carries "Authorization: Bearer secret"
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.
Patches
Fixed in mechanize v2.14.1.
- Credentials and cookies are withheld from a request that follows a redirect across an origin, from both header sources: the per-request
headersargument andMechanize#request_headers=. CREDENTIAL_HEADERSgainsProxy-Authorization;COOKIE_HEADERSgainsCookie2.
Proxy-Authorization is withheld here although curl does not withhold it, because Net::HTTP tunnels https: requests with CONNECT, so a caller-supplied Proxy-Authorization travels inside the tunnel to the origin server rather than to the proxy.
Headers set through Mechanize#request_headers= no longer reach a redirect target on another origin when they are credentials. Callers that relied on the previous behavior will see those headers withheld.
What this fix does not cover
Only the headers in CREDENTIAL_HEADERS and COOKIE_HEADERS are withheld. A caller-supplied header that carries a credential under some other name — X-API-Key, X-Vault-Token, or any bespoke token header — still follows a redirect to another origin, matching the behavior of curl's CURLOPT_HTTPHEADER. If you set such a header, do not enable redirect following for requests that carry it, or scope it to a single request whose destination you control.
Workarounds
Set Mechanize#redirect_ok = false and handle redirects explicitly, or avoid request_headers= for credentials and pass them per-request only to hosts you intend to authenticate to.
Credit
Reported by @SnailSploit.
- Record
GHSA-2mwr-xjcg-37j7- CVSS 3.1
- 6.8 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N - Weakness
- CWE-200, CWE-522
- Updated
- 2026-11-02
NVD
6.8
The Mechanize library is used for automating interaction with websites. Prior to 2.14.1, Mechanize sends caller-supplied credential headers to a different host after an HTTP redirect. Mechanize#request_headers= is reapplied by Mechanize::HTTP::Agent#request_add_headers even after Mechanize::HTTP::Agent#response_redirect strips per-request headers, and the protected header lists omit Proxy-Authorization and Cookie2. An attacker who controls a redirect target can capture bearer tokens or session cookies supplied through request_headers= or the per-request headers argument, while Mechanize#cookie_jar and Mechanize::HTTP::AuthStore are not affected. This issue is fixed in version 2.14.1.
- Record
CVE-2026-107715- CVSS 3.1
- 6.8 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N - Weakness
- CWE-200, CWE-522
- Updated
- 2026-11-02
OSV
6.8
Mechanize sends credential headers to another host after an HTTP redirect
The Mechanize library is used for automating interaction with websites. Prior to 2.14.1, Mechanize sends caller-supplied credential headers to a different host after an HTTP redirect. Mechanize#request_headers= is reapplied by Mechanize::HTTP::Agent#request_add_headers even after Mechanize::HTTP::Agent#response_redirect strips per-request headers, and the protected header lists omit Proxy-Authorization and Cookie2. An attacker who controls a redirect target can capture bearer tokens or session cookies supplied through request_headers= or the per-request headers argument, while Mechanize#cookie_jar and Mechanize::HTTP::AuthStore are not affected. This issue is fixed in version 2.14.1.
- Record
CVE-2026-107715- CVSS 3.1
- 6.8 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N - Weakness
- CWE-200, CWE-522
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-107715
6.8
The Mechanize library is used for automating interaction with websites. Prior to 2.14.1, Mechanize sends caller-supplied credential headers to a different host after an HTTP redirect. Mechanize#request_headers= is reapplied by Mechanize::HTTP::Agent#request_add_headers even after Mechanize::HTTP::Agent#response_redirect strips per-request headers, and the protected header lists omit Proxy-Authorization and Cookie2. An attacker who controls a redirect target can capture bearer tokens or session cookies supplied through request_headers= or the per-request headers argument, while Mechanize#cookie_jar and Mechanize::HTTP::AuthStore are not affected. This issue is fixed in version 2.14.1.
- Record
DEBIAN-CVE-2026-107715- CVSS 3.1
- 6.8 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N - Updated
- 2026-11-02
OSVGHSA-2mwr-xjcg-37j7
6.8
Mechanize sends credential headers to another host after an HTTP redirect
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.
PoC
agent = Mechanize.new
agent.request_headers = { 'Authorization' => 'Bearer secret' }
agent.get('https://example.test/redirects-to-attacker')
# the request to the attacker's host carries "Authorization: Bearer secret"
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.
Patches
Fixed in mechanize v2.14.1.
- Credentials and cookies are withheld from a request that follows a redirect across an origin, from both header sources: the per-request
headersargument andMechanize#request_headers=. CREDENTIAL_HEADERSgainsProxy-Authorization;COOKIE_HEADERSgainsCookie2.
Proxy-Authorization is withheld here although curl does not withhold it, because Net::HTTP tunnels https: requests with CONNECT, so a caller-supplied Proxy-Authorization travels inside the tunnel to the origin server rather than to the proxy.
Headers set through Mechanize#request_headers= no longer reach a redirect target on another origin when they are credentials. Callers that relied on the previous behavior will see those headers withheld.
What this fix does not cover
Only the headers in CREDENTIAL_HEADERS and COOKIE_HEADERS are withheld. A caller-supplied header that carries a credential under some other name — X-API-Key, X-Vault-Token, or any bespoke token header — still follows a redirect to another origin, matching the behavior of curl's CURLOPT_HTTPHEADER. If you set such a header, do not enable redirect following for requests that carry it, or scope it to a single request whose destination you control.
Workarounds
Set Mechanize#redirect_ok = false and handle redirects explicitly, or avoid request_headers= for credentials and pass them per-request only to hosts you intend to authenticate to.
Credit
Reported by @SnailSploit.
- Record
GHSA-2mwr-xjcg-37j7- CVSS 3.1
- 6.8 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N - Weakness
- CWE-200, CWE-522
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-107715
6.8
The Mechanize library is used for automating interaction with websites. Prior to 2.14.1, Mechanize sends caller-supplied credential headers to a different host after an HTTP redirect. Mechanize#request_headers= is reapplied by Mechanize::HTTP::Agent#request_add_headers even after Mechanize::HTTP::Agent#response_redirect strips per-request headers, and the protected header lists omit Proxy-Authorization and Cookie2. An attacker who controls a redirect target can capture bearer tokens or session cookies supplied through request_headers= or the per-request headers argument, while Mechanize#cookie_jar and Mechanize::HTTP::AuthStore are not affected. This issue is fixed in version 2.14.1.
- Record
UBUNTU-CVE-2026-107715- CVSS 3.1
- 6.8 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
mechanizeRubyGems |
before 2.14.1 | 2.14.1 |
ruby-mechanizeDebian:12 |
All versions, plus listed versions 2.10.1-12.10.1-1.12.14.0-12.14.0-22.14.1-12.8.5-1 |
None known |
ruby-mechanizeDebian:13 |
All versions, plus listed versions 2.10.1-12.10.1-1.12.14.0-12.14.0-22.14.1-1 |
None known |
ruby-mechanizeDebian:14 |
before 2.14.1-1, plus listed versions 2.10.1-12.10.1-1.12.14.0-12.14.0-2 |
2.14.1-1 |
mechanizeRubyGems |
before 2.14.1, plus listed versions 0.1.00.1.10.1.20.1.30.2.0 Show 45 moreShow less0.2.10.2.20.2.30.3.00.3.10.4.00.4.10.4.20.4.30.4.40.4.50.4.60.4.70.5.00.5.10.5.20.5.30.5.40.6.00.6.10.6.100.6.110.6.20.6.30.6.40.6.50.6.60.6.70.6.80.6.90.7.00.7.10.7.20.7.30.7.40.7.50.7.60.7.70.7.80.8.00.8.10.8.20.8.30.8.40.8.5 |
2.14.1 |
ruby-mechanizeUbuntu:16.04:LTS |
All versions, plus listed versions 2.7.3-1 |
None known |
ruby-mechanizeUbuntu:18.04:LTS |
All versions, plus listed versions 2.7.5-12.7.5-2 |
None known |
ruby-mechanizeUbuntu:20.04:LTS |
All versions, plus listed versions 2.7.6-1 |
None known |
ruby-mechanizeUbuntu:22.04:LTS |
All versions, plus listed versions 2.7.7-12.7.7-3 |
None known |
ruby-mechanizeUbuntu:24.04:LTS |
All versions, plus listed versions 2.8.5-1 |
None known |
ruby-mechanizeUbuntu:26.10 |
All versions, plus listed versions 2.10.1-1.12.14.0-2 |
None known |
ruby-mechanizeUbuntu:26.04:LTS |
All versions, plus listed versions 2.10.1-1.1 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-107715 is a medium vulnerability (CVSS 6.8) in Python-mechanize Mechanize, published October 8, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.50%, the 43rd percentile. Fixed in mechanize 2.14.1.
References
github.com/sparklemotion/mechanize/security/advisories/GHSA-2mwr-xjcg-37j7
github.com/sparklemotion/mechanize/pull/676
github.com/sparklemotion/mechanize/commit/02a1235842d6eda8d4a5a3d8f13aba2cecf52e4f
github.com/sparklemotion/mechanize/commit/94e0902867296be804f36eccbb47acf7d5018745
github.com/sparklemotion/mechanize/commit/ac49abf2869297d83c3b11bbfb8b18e63b588c95
github.com/sparklemotion/mechanize/releases/tag/v2.14.1
Show 7 moreShow less
github.com/advisories/GHSA-2mwr-xjcg-37j7
github.com/CVEProject/cvelistV5/tree/main/cves/2026/107xxx/CVE-2026-107715.json
nvd.nist.gov/vuln/detail/CVE-2026-107715
security-tracker.debian.org/tracker/CVE-2026-107715
github.com/sparklemotion/mechanize
ubuntu.com/security/CVE-2026-107715
cve.org/CVERecord?id=CVE-2026-107715
Left out here: 45 versions. The JSON record has them.