Version in base suite: 1.8.9-1
Base version: python-webob_1.8.9-1
Target version: python-webob_1.8.10-0+deb13u1
Base file: /srv/ftp-master.debian.org/ftp/pool/main/p/python-webob/python-webob_1.8.9-1.dsc
Target file: /srv/ftp-master.debian.org/policy/pool/main/p/python-webob/python-webob_1.8.10-0+deb13u1.dsc
.gitignore | 20 -----------------
.readthedocs.yaml | 14 ++++++++++++
CHANGES.txt | 15 +++++++++++++
PKG-INFO | 33 ++++++++++++++++++++++++++--
debian/changelog | 9 +++++++
setup.py | 3 +-
src/WebOb.egg-info/PKG-INFO | 33 ++++++++++++++++++++++++++--
src/WebOb.egg-info/SOURCES.txt | 2 -
src/WebOb.egg-info/requires.txt | 1
src/webob/response.py | 11 ++++++---
tests/test_client_functional.py | 2 -
tests/test_response.py | 46 ++++++++++++++++++++++++++++++++++++++++
tox.ini | 3 --
13 files changed, 159 insertions(+), 33 deletions(-)
dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp9w4xanl_/python-webob_1.8.9-1.dsc: no acceptable signature found
dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp9w4xanl_/python-webob_1.8.10-0+deb13u1.dsc: no acceptable signature found
diff -Nru python-webob-1.8.9/.gitignore python-webob-1.8.10/.gitignore
--- python-webob-1.8.9/.gitignore 2018-04-05 02:06:35.000000000 +0000
+++ python-webob-1.8.10/.gitignore 1970-01-01 00:00:00.000000000 +0000
@@ -1,20 +0,0 @@
-*$py.class
-*.egg
-*.pyc
-*.pyo
-*.swp
-*~
-.*.swp
-.tox/
-__pycache__/
-_build/
-build/
-dist/
-env*/
-.coverage
-.coverage.*
-.cache/
-WebOb.egg-info/
-pytest*.xml
-coverage*.xml
-.pytest_cache/
diff -Nru python-webob-1.8.9/.readthedocs.yaml python-webob-1.8.10/.readthedocs.yaml
--- python-webob-1.8.9/.readthedocs.yaml 1970-01-01 00:00:00.000000000 +0000
+++ python-webob-1.8.10/.readthedocs.yaml 2026-06-29 05:24:25.000000000 +0000
@@ -0,0 +1,14 @@
+# https://docs.readthedocs.io/en/stable/config-file/v2.html
+version: 2
+build:
+ os: ubuntu-22.04
+ tools:
+ python: '3.12'
+sphinx:
+ configuration: docs/conf.py
+python:
+ install:
+ - method: pip
+ path: .
+ extra_requirements:
+ - docs
diff -Nru python-webob-1.8.9/CHANGES.txt python-webob-1.8.10/CHANGES.txt
--- python-webob-1.8.9/CHANGES.txt 2024-10-24 03:10:29.000000000 +0000
+++ python-webob-1.8.10/CHANGES.txt 2026-06-29 05:24:25.000000000 +0000
@@ -1,3 +1,18 @@
+1.8.10 (2026-06-02)
+-------------------
+
+Security Fix
+~~~~~~~~~~~~
+
+- The fix for CVE-2024-42353 was incomplete: a Location value containing
+ ASCII tab, carriage return, or line feed characters between consecutive
+ slashes could still be interpreted as a protocol-relative URL by
+ ``urllib.parse.urljoin`` on Python 3.10+, allowing an open redirect.
+
+ See https://github.com/Pylons/webob/security/advisories/GHSA-fh3h-vg37-cc95
+
+ Thanks to Caleb Brown of Google for the report.
+
1.8.9 (2024-11-23)
------------------
diff -Nru python-webob-1.8.9/PKG-INFO python-webob-1.8.10/PKG-INFO
--- python-webob-1.8.9/PKG-INFO 2024-10-24 03:17:49.027817500 +0000
+++ python-webob-1.8.10/PKG-INFO 2026-06-29 05:24:25.000000000 +0000
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
Name: WebOb
-Version: 1.8.9
+Version: 1.8.10
Summary: WSGI request and response object
Home-page: http://webob.org/
Author: Ian Bicking
@@ -32,6 +32,20 @@
Provides-Extra: docs
Requires-Dist: Sphinx>=1.7.5; extra == "docs"
Requires-Dist: pylons-sphinx-themes; extra == "docs"
+Requires-Dist: setuptools; extra == "docs"
+Dynamic: author
+Dynamic: author-email
+Dynamic: classifier
+Dynamic: description
+Dynamic: home-page
+Dynamic: keywords
+Dynamic: license
+Dynamic: license-file
+Dynamic: maintainer
+Dynamic: provides-extra
+Dynamic: requires-dist
+Dynamic: requires-python
+Dynamic: summary
WebOb
=====
@@ -70,6 +84,21 @@
WebOb was authored by Ian Bicking and is currently maintained by the `Pylons
Project `_ and a team of contributors.
+1.8.10 (2026-06-02)
+-------------------
+
+Security Fix
+~~~~~~~~~~~~
+
+- The fix for CVE-2024-42353 was incomplete: a Location value containing
+ ASCII tab, carriage return, or line feed characters between consecutive
+ slashes could still be interpreted as a protocol-relative URL by
+ ``urllib.parse.urljoin`` on Python 3.10+, allowing an open redirect.
+
+ See https://github.com/Pylons/webob/security/advisories/GHSA-fh3h-vg37-cc95
+
+ Thanks to Caleb Brown of Google for the report.
+
1.8.9 (2024-11-23)
------------------
diff -Nru python-webob-1.8.9/debian/changelog python-webob-1.8.10/debian/changelog
--- python-webob-1.8.9/debian/changelog 2025-01-12 17:39:16.000000000 +0000
+++ python-webob-1.8.10/debian/changelog 2026-07-03 17:13:14.000000000 +0000
@@ -1,3 +1,12 @@
+python-webob (1:1.8.10-0+deb13u1) trixie; urgency=medium
+
+ * Non-maintainer upload.
+ * New upstream release.
+ - CVE-2026-44889: Location header normalization during redirect
+ leads to open redirect
+
+ -- Adrian Bunk Fri, 03 Jul 2026 20:13:14 +0300
+
python-webob (1:1.8.9-1) unstable; urgency=medium
* Team upload.
diff -Nru python-webob-1.8.9/setup.py python-webob-1.8.10/setup.py
--- python-webob-1.8.9/setup.py 2024-10-24 03:17:01.000000000 +0000
+++ python-webob-1.8.10/setup.py 2026-06-29 05:24:25.000000000 +0000
@@ -21,11 +21,12 @@
docs_extras = [
'Sphinx >= 1.7.5',
'pylons-sphinx-themes',
+ 'setuptools'
]
setup(
name='WebOb',
- version='1.8.9',
+ version='1.8.10',
description="WSGI request and response object",
long_description=README + '\n\n' + CHANGES,
classifiers=[
diff -Nru python-webob-1.8.9/src/WebOb.egg-info/PKG-INFO python-webob-1.8.10/src/WebOb.egg-info/PKG-INFO
--- python-webob-1.8.9/src/WebOb.egg-info/PKG-INFO 2024-10-24 03:17:48.000000000 +0000
+++ python-webob-1.8.10/src/WebOb.egg-info/PKG-INFO 2026-06-29 05:24:25.000000000 +0000
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
Name: WebOb
-Version: 1.8.9
+Version: 1.8.10
Summary: WSGI request and response object
Home-page: http://webob.org/
Author: Ian Bicking
@@ -32,6 +32,20 @@
Provides-Extra: docs
Requires-Dist: Sphinx>=1.7.5; extra == "docs"
Requires-Dist: pylons-sphinx-themes; extra == "docs"
+Requires-Dist: setuptools; extra == "docs"
+Dynamic: author
+Dynamic: author-email
+Dynamic: classifier
+Dynamic: description
+Dynamic: home-page
+Dynamic: keywords
+Dynamic: license
+Dynamic: license-file
+Dynamic: maintainer
+Dynamic: provides-extra
+Dynamic: requires-dist
+Dynamic: requires-python
+Dynamic: summary
WebOb
=====
@@ -70,6 +84,21 @@
WebOb was authored by Ian Bicking and is currently maintained by the `Pylons
Project `_ and a team of contributors.
+1.8.10 (2026-06-02)
+-------------------
+
+Security Fix
+~~~~~~~~~~~~
+
+- The fix for CVE-2024-42353 was incomplete: a Location value containing
+ ASCII tab, carriage return, or line feed characters between consecutive
+ slashes could still be interpreted as a protocol-relative URL by
+ ``urllib.parse.urljoin`` on Python 3.10+, allowing an open redirect.
+
+ See https://github.com/Pylons/webob/security/advisories/GHSA-fh3h-vg37-cc95
+
+ Thanks to Caleb Brown of Google for the report.
+
1.8.9 (2024-11-23)
------------------
diff -Nru python-webob-1.8.9/src/WebOb.egg-info/SOURCES.txt python-webob-1.8.10/src/WebOb.egg-info/SOURCES.txt
--- python-webob-1.8.9/src/WebOb.egg-info/SOURCES.txt 2024-10-24 03:17:49.000000000 +0000
+++ python-webob-1.8.10/src/WebOb.egg-info/SOURCES.txt 2026-06-29 05:24:25.000000000 +0000
@@ -1,5 +1,5 @@
.coveragerc
-.gitignore
+.readthedocs.yaml
CHANGES.txt
HISTORY.txt
MANIFEST.in
diff -Nru python-webob-1.8.9/src/WebOb.egg-info/requires.txt python-webob-1.8.10/src/WebOb.egg-info/requires.txt
--- python-webob-1.8.9/src/WebOb.egg-info/requires.txt 2024-10-24 03:17:48.000000000 +0000
+++ python-webob-1.8.10/src/WebOb.egg-info/requires.txt 2026-06-29 05:24:25.000000000 +0000
@@ -5,6 +5,7 @@
[docs]
Sphinx>=1.7.5
pylons-sphinx-themes
+setuptools
[testing]
pytest>=3.1.0
diff -Nru python-webob-1.8.9/src/webob/response.py python-webob-1.8.10/src/webob/response.py
--- python-webob-1.8.9/src/webob/response.py 2024-08-14 05:06:46.000000000 +0000
+++ python-webob-1.8.10/src/webob/response.py 2026-06-29 05:24:25.000000000 +0000
@@ -1281,12 +1281,17 @@
@staticmethod
def _make_location_absolute(environ, value):
+ # urllib.parse.urlsplit() (called internally by urljoin) strips
+ # ASCII tab, CR, and LF from the URL on Python 3.10+. Strip them
+ # ourselves first so they cannot be used to bypass the SCHEME_RE
+ # or protocol-relative ("//") checks below. See CVE-2024-42353,
+ # https://github.com/Pylons/webob/security/advisories/GHSA-mg3v-6m49-jhp3,
+ # and the follow-up advisory GHSA-fh3h-vg37-cc95.
+ value = value.replace("\t", "").replace("\r", "").replace("\n", "")
+
if SCHEME_RE.search(value):
return value
- # This is to fix an open redirect issue due to the way that
- # urlparse.urljoin works. See CVE-2024-42353 and
- # https://github.com/Pylons/webob/security/advisories/GHSA-mg3v-6m49-jhp3
if value.startswith("//"):
value = "/%2f{}".format(value[2:])
new_location = urlparse.urljoin(_request_uri(environ), value)
diff -Nru python-webob-1.8.9/tests/test_client_functional.py python-webob-1.8.10/tests/test_client_functional.py
--- python-webob-1.8.9/tests/test_client_functional.py 2024-08-14 05:06:43.000000000 +0000
+++ python-webob-1.8.10/tests/test_client_functional.py 2026-06-29 05:24:25.000000000 +0000
@@ -69,7 +69,6 @@
resp = Response('test')
resp.headers.add('Set-Cookie', 'a=b')
resp.headers.add('Set-Cookie', 'c=d')
- resp.headerlist.append(('X-Crazy', 'value\r\n continuation'))
return resp
@@ -79,7 +78,6 @@
req = Request.blank(server.url + '/?test')
resp = req.send(client_app)
assert resp.headers.getall('Set-Cookie') == ['a=b', 'c=d']
- assert resp.headers['X-Crazy'] == 'value, continuation', repr(resp.headers['X-Crazy'])
@wsgify
diff -Nru python-webob-1.8.9/tests/test_response.py python-webob-1.8.10/tests/test_response.py
--- python-webob-1.8.9/tests/test_response.py 2024-08-14 05:06:46.000000000 +0000
+++ python-webob-1.8.10/tests/test_response.py 2026-06-29 05:24:25.000000000 +0000
@@ -1042,6 +1042,52 @@
assert req.get_response(res).location == "http://localhost/%2fwww.example.com/test"
+@pytest.mark.parametrize("payload", [
+ "/\t/www.example.com/test",
+ "\t//www.example.com/test",
+ "//\twww.example.com/test",
+ "/\t\t/www.example.com/test",
+])
+def test_location_no_open_redirect_tab_bypass(payload):
+ # Follow-up to CVE-2024-42353. urllib.parse.urlsplit() (used internally
+ # by urljoin) strips ASCII tab on Python 3.10+, which allowed a
+ # Location value to bypass the "//" check and be parsed as
+ # protocol-relative. See GHSA-fh3h-vg37-cc95. (CR and LF are already
+ # rejected by the location header setter, so only tab is reachable
+ # via the public API.)
+ res = Response()
+ res.status = "301"
+ res.location = payload
+ req = Request.blank("/")
+ assert req.get_response(res).location == (
+ "http://localhost/%2fwww.example.com/test"
+ )
+
+
+@pytest.mark.parametrize("payload", [
+ "/\t/www.example.com/test",
+ "/\n/www.example.com/test",
+ "/\r/www.example.com/test",
+ "\t//www.example.com/test",
+ "\n//www.example.com/test",
+ "\r//www.example.com/test",
+ "//\twww.example.com/test",
+ "//\nwww.example.com/test",
+ "//\rwww.example.com/test",
+ "//\tw\nww.example.com/test",
+])
+def test__make_location_absolute_strips_url_whitespace(payload):
+ # Defense in depth for GHSA-fh3h-vg37-cc95: even when called with a
+ # Location value that bypasses the descriptor's CR/LF check (e.g. via
+ # direct manipulation of _headerlist), tab/CR/LF must not be usable to
+ # turn a relative path into a protocol-relative redirect.
+ result = Response._make_location_absolute(
+ {"wsgi.url_scheme": "http", "HTTP_HOST": "example.com:80"},
+ payload,
+ )
+ assert result == "http://example.com/%2fwww.example.com/test"
+
+
@pytest.mark.xfail(sys.version_info < (3,0),
reason="Python 2.x unicode != str, WSGI requires str. Test "
"added due to https://github.com/Pylons/webob/issues/247. "
diff -Nru python-webob-1.8.9/tox.ini python-webob-1.8.10/tox.ini
--- python-webob-1.8.9/tox.ini 2024-10-24 03:11:34.000000000 +0000
+++ python-webob-1.8.10/tox.ini 2026-06-29 05:24:25.000000000 +0000
@@ -1,7 +1,7 @@
[tox]
requires = virtualenv<20.22.0
envlist =
- py27,py34,py35,py36,py37,py313,pypy,
+ py27,py34,py35,py36,py37,pypy,
docs,coverage,pep8
skip_missing_interpreters = True
@@ -14,7 +14,6 @@
py35: python3.5
py36: python3.6
py37: python3.7
- py313: python3.13
pypy: pypy
py2: python2.7
py3: python3.5