Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
💎
💎 RubyGems
Not in CISA KEV
MEDIUM severity

Mechanize sends credential headers to another origin after a meta refreshGHSA-c6rp-p8xm-4q9f

MEDIUMFix: sparklemotion/mechanize#676

GHSA-c6rp-p8xm-4q9f is a medium-severity (CVSS 6.8) Information Exposure vulnerability in mechanize. A fix is available for mechanize — see the affected versions and patch details below.

Also known asCVE-2026-107399
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 23, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for GHSA-c6rp-p8xm-4q9f.

EPSS Exploitation Probability

via FIRST.org ↗
0.4%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs29th percentile — riskier than 29% of all scored CVEsHighest risk

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

GHSA-c6rp-p8xm-4q9f by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.

Where this sits among everything scored

Of 395,249 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.

Real-World Exposure

1 pkg affected
💎mechanize

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects RubyGems packages — download data is not available via public APIs for these ecosystems.

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.

Patches

Fixed in mechanize v2.14.1. A meta refresh that points at another origin is now subject to the same rule as an HTTP redirect: credentials and cookies are withheld from the request that follows it.

Workarounds

Leave Mechanize#follow_meta_refresh at its default of false, or avoid request_headers= for credentials when it is enabled.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
💎RubyGemsmechanizeall versions2.14.1bundle update mechanize --conservative

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for mechanize, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update mechanize to 2.14.1 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-c6rp-p8xm-4q9f is resolved across your whole dependency graph.

  3. Workarounds

    Stop reflecting attacker-controlled destinations: resolve every redirect target against an allowlist of paths or hosts you own, prefer a server-side key over a full URL in the request, and reject absolute URLs entirely where the flow only ever needs a relative one.

Fixing This On Your OS

If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.

Red HatModerate

A moderate information disclosure flaw was found in the mechanize Ruby library, which is included in the Red Hat 3scale API Management Platform system container. When an application enables automatic meta refresh following (Mechanize#follow_meta_refresh, which is disabled by default) and configures default request…

Workaround published by Red Hat
A workaround is available: keep automatic meta refresh following disabled by leaving Mechanize#follow_meta_refresh at its default value of false, which is the non-affected default configuration. If meta refresh following must be enabled, avoid configuring sensitive headers such as Authorization or Cookie via Mechanize#request_headers= so that they are not replayed to cross-origin refresh targets. The affected Red Hat 3scale API Management 2.15 stream is out of support scope, so no Red Hat update is planned for it; upstream fixed this issue in mechanize version 2.14.1.
Source: Red Hat security advisory for GHSA-c6rp-p8xm-4q9f (CC BY 4.0)

Frequently Asked Questions

## 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 o
O3 Security · Impact-Aware SCA

Is GHSA-c6rp-p8xm-4q9f in your dependencies?

Find it across RubyGems, including transitive dependencies.

Mechanize sends credential headers to another origin…