Executive brief
WebOb is a Python library that handles HTTP requests and responses in web applications. When processing redirect responses, it normalizes the Location header to prevent attackers from redirecting users to external sites. However, due to how Python's urllib handles URLs, leading whitespace and control characters can bypass these checks, allowing an attacker to craft a redirect that sends users to a malicious site. This enables phishing attacks and credential theft, especially when combined with OAuth flows.
Technical details
This is an open redirect vulnerability in WebOb's Location header normalization. The vulnerable code uses `urllib.parse.urljoin()` to make relative redirect targets absolute, checking first for URI schemes and protocol-relative URLs (`//`). However, on Python 3.10+, `urljoin()` silently strips leading and trailing C0 control characters (U+0000–U+001F) and spaces before parsing. Because WebOb's guard checks run on the un-stripped value, a single leading space or control byte bypasses both the scheme regex and `startswith("//")` check, then `urljoin()` removes it and parses the remainder as a protocol-relative or absolute URL. For example, `" //www.example.com/test"` passes validation but redirects to `http://www.example.com/test`. The vulnerability affects three code paths: `Response.location`, `Request.relative_url()`, and HTTP exception classes like `HTTPFound`. The fix replaces `urllib.parse.urljoin()` with WebOb's own RFC 3986 reference-resolution implementation that does not strip whitespace.
Affected products
- Pylons Project WebOb < 1.8.11
Timeline
- 2026-08-27: disclosed: Advisory published
- 2026-08-02: advisory: GitHub Advisory Database entry created
- 2026-08-27: patched: Fixed in version 1.8.11