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

CVE-2026-44889 — webob

MEDIUMFix: Pylons/webob@1f681a4

CVE-2026-44889 is a medium-severity (CVSS 6.1) Open Redirect vulnerability in webob. A fix is available for webob — see the affected versions and patch details below.

WebOb: Location header normalization during redirect leads to open redirect

Also known asGHSA-fh3h-vg37-cc95PYSEC-2026-251
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 16, 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 CVE-2026-44889.

EPSS Exploitation Probability

via FIRST.org ↗
0.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs18th percentile — riskier than 18% of all scored CVEsHighest risk
0.00%0.26%0.51%0.77%0.2%0.2%0.3%0.3%0.3%Jul 26Sep 26Oct 26

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

How urgent is this, really

CVE-2026-44889 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.

Where this sits among everything scored

Of 390,400 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
🐍webob

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

Description

Impact

When WebOb normalizes the HTTP Location header to include the request hostname, it does so by parsing the URL that the user is to be redirected to with Python's urllib.parse, and joining it to the base URL. urlsplit (called internally by urljoin) however treats a // at the start of a string as a URI without a scheme, and then treats the next part as the hostname. urljoin will then use that hostname from the second part as the hostname replacing the original one from the request.

In a previous advisory https://github.com/Pylons/webob/security/advisories/GHSA-mg3v-6m49-jhp3 an attempt to fix this was made by forcing the replacement of // with /%2f, however this did not take into account that since Python 3.10 urlsplit internally strips ASCII tab, carriage return, and newline characters from the string, so /\t/attacker.com gets turned into //attacker.com and the attacker is able to bypass the changes introduced in that previous advisory, thereby bringing back the problem that was attempted to be fixed.

>>> parse.urlparse("//attacker.com/some/path")
ParseResult(scheme='', netloc='attacker.com', path='/some/path', params='', query='', fragment='')

WebOb uses urljoin to take the request URI and join the redirect location to it, so assuming the request URI is https://example.org/ and the URL to redirect to is /\t/attacker.com/some/path/:

>>> parse.urljoin("https://example.org/", "/\t/attacker.com/some/path/")
'https://attacker.com/some/path/'

Which redirects from example.org where we want the user to stay to attacker.com.

Patches

This issue has been fixed in WebOb 1.8.10.

Workarounds

Any use of the Response class that includes a location can be rewritten to make sure to always pass a full URI that includes the hostname to redirect the user to, or to validate that the redirect target starts with a scheme (e.g. http:// or https://) before assigning to Response.location.

References

Thanks

  • Caleb Brown of Google

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPIweboball versions1.8.10pip install --upgrade 'webob==1.8.10'

Affected Products

1 product · 1 configurations
Application
webobpylonsproject
< 1.8.10
range

Detection & mitigation playbook

Open-source dependency
  1. Detect

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

  2. Fix

    Update webob to 1.8.10 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-44889 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

This is rated as Moderate (CVSS 6.1) because exploitation requires user interaction — a victim must click a crafted link that triggers the redirect (UI:R). While the attack is network-accessible (AV:N) and requires no privileges (PR:N), the impact is limited to low confidentiality and integrity effects typical of an…

Workaround published by Red Hat
This vulnerability in WebOb is only exploitable when running under Python 3.10 or later, where urllib.parse.urlsplit strips ASCII tab, carriage return, and newline characters before parsing. Red Hat Enterprise Linux, OpenShift Container Platform, Red Hat OpenStack Platform, Red Hat Ceph Storage, and Red Hat Quay all ship python-webob with Python 3.9 or earlier as the platform Python runtime, and are therefore not affected by this vulnerability. Fedora and EPEL ship python-webob under Python 3.12+, where the vulnerability is exploitable. Users running WebOb on Python 3.10+ should upgrade to WebOb 1.8.10. As a workaround, applications can validate that redirect targets start with a scheme…
Source: Red Hat security advisory for CVE-2026-44889 (CC BY 4.0)

Frequently Asked Questions

### Impact When WebOb normalizes the HTTP Location header to include the request hostname, it does so by parsing the URL that the user is to be redirected to with Python's `urllib.parse`, and joining it to the base URL. `urlsplit` (called internally by `urljoin`) however treats a `//` at the start of a string as a URI without a scheme, and then treats the next part as the hostname. `urljoin` will then use that hostname from the second part as the hostname replacing the original one from the request. In a previous advisory https://github.com/Pylons/webob/security/advisories/GHSA-mg3v-6m49-jhp
O3 Security · Impact-Aware SCA

Is CVE-2026-44889 in your dependencies?

Find it across PyPI, including transitive dependencies.

CVE-2026-44889: webob — Fixed in 1.8.10