Skip to content

Commit

Permalink
Address CVE-2025-0938
Browse files Browse the repository at this point in the history
  • Loading branch information
Kanishk-Bansal committed Feb 6, 2025
1 parent 925884a commit b1a42dd
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 21 deletions.
108 changes: 108 additions & 0 deletions SPECS/python3/CVE-2025-0938.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
From 1b82e5457cf4494a2c7d16f2d023968d993f8a9d Mon Sep 17 00:00:00 2001
From: Kanishk Bansal <[email protected]>
Date: Thu, 6 Feb 2025 08:10:16 +0000
Subject: [PATCH] Address CVE-2025-0938

---
Lib/test/test_urlparse.py | 37 ++++++++++++++++++++++++++++++++++++-
Lib/urllib/parse.py | 20 ++++++++++++++++++--
2 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py
index 236b6e4..12d6b6b 100644
--- a/Lib/test/test_urlparse.py
+++ b/Lib/test/test_urlparse.py
@@ -1169,16 +1169,51 @@ class UrlParseTestCase(unittest.TestCase):
self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af::2309::fae7:1234]/Path?Query')
self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af:2309::fae7:1234:2342:438e:192.0.2.146]/Path?Query')
self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@]v6a.ip[/Path')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]/')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix/')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]?')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix?')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]/')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix/')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]?')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix?')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:a')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:a')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:a1')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:a1')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:1a')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:1a')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:/')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:?')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://user@prefix.[v6a.ip]')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://user@[v6a.ip].suffix')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip]')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://]v6a.ip[')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://]v6a.ip')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip].suffix')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip[suffix')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[suffix')

def test_splitting_bracketed_hosts(self):
- p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]/path?query')
+ p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]:1234/path?query')
self.assertEqual(p1.hostname, 'v6a.ip')
self.assertEqual(p1.username, 'user')
self.assertEqual(p1.path, '/path')
+ self.assertEqual(p1.port, 1234)
p2 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7%test]/path?query')
self.assertEqual(p2.hostname, '0439:23af:2309::fae7%test')
self.assertEqual(p2.username, 'user')
self.assertEqual(p2.path, '/path')
+ self.assertIs(p2.port, None)
p3 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7:1234:192.0.2.146%test]/path?query')
self.assertEqual(p3.hostname, '0439:23af:2309::fae7:1234:192.0.2.146%test')
self.assertEqual(p3.username, 'user')
diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py
index fc9e7c9..fdc8832 100644
--- a/Lib/urllib/parse.py
+++ b/Lib/urllib/parse.py
@@ -436,6 +436,23 @@ def _checknetloc(netloc):
raise ValueError("netloc '" + netloc + "' contains invalid " +
"characters under NFKC normalization")

+def _check_bracketed_netloc(netloc):
+ # Note that this function must mirror the splitting
+ # done in NetlocResultMixins._hostinfo().
+ hostname_and_port = netloc.rpartition('@')[2]
+ before_bracket, have_open_br, bracketed = hostname_and_port.partition('[')
+ if have_open_br:
+ # No data is allowed before a bracket.
+ if before_bracket:
+ raise ValueError("Invalid IPv6 URL")
+ hostname, _, port = bracketed.partition(']')
+ # No data is allowed after the bracket but before the port delimiter.
+ if port and not port.startswith(":"):
+ raise ValueError("Invalid IPv6 URL")
+ else:
+ hostname, _, port = hostname_and_port.partition(':')
+ _check_bracketed_host(hostname)
+
# Valid bracketed hosts are defined in
# https://www.rfc-editor.org/rfc/rfc3986#page-49 and https://url.spec.whatwg.org/
def _check_bracketed_host(hostname):
@@ -496,8 +513,7 @@ def urlsplit(url, scheme='', allow_fragments=True):
(']' in netloc and '[' not in netloc)):
raise ValueError("Invalid IPv6 URL")
if '[' in netloc and ']' in netloc:
- bracketed_host = netloc.partition('[')[2].partition(']')[0]
- _check_bracketed_host(bracketed_host)
+ _check_bracketed_netloc(netloc)
if allow_fragments and '#' in url:
url, fragment = url.split('#', 1)
if '?' in url:
--
2.43.0

6 changes: 5 additions & 1 deletion SPECS/python3/python3.spec
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Summary: A high-level scripting language
Name: python3
Version: 3.12.3
Release: 6%{?dist}
Release: 7%{?dist}
License: PSF
Vendor: Microsoft Corporation
Distribution: Azure Linux
Expand All @@ -23,6 +23,7 @@ Patch3: CVE-2024-6232.patch
Patch4: CVE-2024-8088.patch
Patch5: CVE-2024-12254.patch
Patch6: CVE-2023-27043.patch
Patch7: CVE-2025-0938.patch

BuildRequires: bzip2-devel
BuildRequires: expat-devel >= 2.1.0
Expand Down Expand Up @@ -244,6 +245,9 @@ rm -rf %{buildroot}%{_bindir}/__pycache__
%{_libdir}/python%{majmin}/test/*

%changelog
* Thu Feb 06 2025 Kanishk Bansal <[email protected]> - 3.12.3-7
- Patch CVE-2025-0938

* Thu Jan 30 2025 Bala <[email protected]> - 3.12.3-6
- Patch CVE-2023-27043

Expand Down
6 changes: 3 additions & 3 deletions toolkit/resources/manifests/package/pkggen_core_aarch64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,9 @@ ca-certificates-base-3.0.0-8.azl3.noarch.rpm
ca-certificates-3.0.0-8.azl3.noarch.rpm
dwz-0.14-2.azl3.aarch64.rpm
unzip-6.0-21.azl3.aarch64.rpm
python3-3.12.3-6.azl3.aarch64.rpm
python3-devel-3.12.3-6.azl3.aarch64.rpm
python3-libs-3.12.3-6.azl3.aarch64.rpm
python3-3.12.3-7.azl3.aarch64.rpm
python3-devel-3.12.3-7.azl3.aarch64.rpm
python3-libs-3.12.3-7.azl3.aarch64.rpm
python3-setuptools-69.0.3-4.azl3.noarch.rpm
python3-pygments-2.7.4-2.azl3.noarch.rpm
which-2.21-8.azl3.aarch64.rpm
Expand Down
6 changes: 3 additions & 3 deletions toolkit/resources/manifests/package/pkggen_core_x86_64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,9 @@ ca-certificates-base-3.0.0-8.azl3.noarch.rpm
ca-certificates-3.0.0-8.azl3.noarch.rpm
dwz-0.14-2.azl3.x86_64.rpm
unzip-6.0-21.azl3.x86_64.rpm
python3-3.12.3-6.azl3.x86_64.rpm
python3-devel-3.12.3-6.azl3.x86_64.rpm
python3-libs-3.12.3-6.azl3.x86_64.rpm
python3-3.12.3-7.azl3.x86_64.rpm
python3-devel-3.12.3-7.azl3.x86_64.rpm
python3-libs-3.12.3-7.azl3.x86_64.rpm
python3-setuptools-69.0.3-4.azl3.noarch.rpm
python3-pygments-2.7.4-2.azl3.noarch.rpm
which-2.21-8.azl3.x86_64.rpm
Expand Down
14 changes: 7 additions & 7 deletions toolkit/resources/manifests/package/toolchain_aarch64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -529,18 +529,18 @@ pyproject-rpm-macros-1.12.0-2.azl3.noarch.rpm
pyproject-srpm-macros-1.12.0-2.azl3.noarch.rpm
python-markupsafe-debuginfo-2.1.3-1.azl3.aarch64.rpm
python-wheel-wheel-0.43.0-1.azl3.noarch.rpm
python3-3.12.3-6.azl3.aarch64.rpm
python3-3.12.3-7.azl3.aarch64.rpm
python3-audit-3.1.2-1.azl3.aarch64.rpm
python3-cracklib-2.9.11-1.azl3.aarch64.rpm
python3-curses-3.12.3-6.azl3.aarch64.rpm
python3-curses-3.12.3-7.azl3.aarch64.rpm
python3-Cython-3.0.5-2.azl3.aarch64.rpm
python3-debuginfo-3.12.3-6.azl3.aarch64.rpm
python3-devel-3.12.3-6.azl3.aarch64.rpm
python3-debuginfo-3.12.3-7.azl3.aarch64.rpm
python3-devel-3.12.3-7.azl3.aarch64.rpm
python3-flit-core-3.9.0-1.azl3.noarch.rpm
python3-gpg-1.23.2-2.azl3.aarch64.rpm
python3-jinja2-3.1.2-2.azl3.noarch.rpm
python3-libcap-ng-0.8.4-1.azl3.aarch64.rpm
python3-libs-3.12.3-6.azl3.aarch64.rpm
python3-libs-3.12.3-7.azl3.aarch64.rpm
python3-libxml2-2.11.5-3.azl3.aarch64.rpm
python3-lxml-4.9.3-1.azl3.aarch64.rpm
python3-magic-5.45-1.azl3.noarch.rpm
Expand All @@ -552,8 +552,8 @@ python3-pygments-2.7.4-2.azl3.noarch.rpm
python3-rpm-4.18.2-1.azl3.aarch64.rpm
python3-rpm-generators-14-11.azl3.noarch.rpm
python3-setuptools-69.0.3-4.azl3.noarch.rpm
python3-test-3.12.3-6.azl3.aarch64.rpm
python3-tools-3.12.3-6.azl3.aarch64.rpm
python3-test-3.12.3-7.azl3.aarch64.rpm
python3-tools-3.12.3-7.azl3.aarch64.rpm
python3-wheel-0.43.0-1.azl3.noarch.rpm
readline-8.2-1.azl3.aarch64.rpm
readline-debuginfo-8.2-1.azl3.aarch64.rpm
Expand Down
14 changes: 7 additions & 7 deletions toolkit/resources/manifests/package/toolchain_x86_64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -537,18 +537,18 @@ pyproject-rpm-macros-1.12.0-2.azl3.noarch.rpm
pyproject-srpm-macros-1.12.0-2.azl3.noarch.rpm
python-markupsafe-debuginfo-2.1.3-1.azl3.x86_64.rpm
python-wheel-wheel-0.43.0-1.azl3.noarch.rpm
python3-3.12.3-6.azl3.x86_64.rpm
python3-3.12.3-7.azl3.x86_64.rpm
python3-audit-3.1.2-1.azl3.x86_64.rpm
python3-cracklib-2.9.11-1.azl3.x86_64.rpm
python3-curses-3.12.3-6.azl3.x86_64.rpm
python3-curses-3.12.3-7.azl3.x86_64.rpm
python3-Cython-3.0.5-2.azl3.x86_64.rpm
python3-debuginfo-3.12.3-6.azl3.x86_64.rpm
python3-devel-3.12.3-6.azl3.x86_64.rpm
python3-debuginfo-3.12.3-7.azl3.x86_64.rpm
python3-devel-3.12.3-7.azl3.x86_64.rpm
python3-flit-core-3.9.0-1.azl3.noarch.rpm
python3-gpg-1.23.2-2.azl3.x86_64.rpm
python3-jinja2-3.1.2-2.azl3.noarch.rpm
python3-libcap-ng-0.8.4-1.azl3.x86_64.rpm
python3-libs-3.12.3-6.azl3.x86_64.rpm
python3-libs-3.12.3-7.azl3.x86_64.rpm
python3-libxml2-2.11.5-3.azl3.x86_64.rpm
python3-lxml-4.9.3-1.azl3.x86_64.rpm
python3-magic-5.45-1.azl3.noarch.rpm
Expand All @@ -560,8 +560,8 @@ python3-pygments-2.7.4-2.azl3.noarch.rpm
python3-rpm-4.18.2-1.azl3.x86_64.rpm
python3-rpm-generators-14-11.azl3.noarch.rpm
python3-setuptools-69.0.3-4.azl3.noarch.rpm
python3-test-3.12.3-6.azl3.x86_64.rpm
python3-tools-3.12.3-6.azl3.x86_64.rpm
python3-test-3.12.3-7.azl3.x86_64.rpm
python3-tools-3.12.3-7.azl3.x86_64.rpm
python3-wheel-0.43.0-1.azl3.noarch.rpm
readline-8.2-1.azl3.x86_64.rpm
readline-debuginfo-8.2-1.azl3.x86_64.rpm
Expand Down

0 comments on commit b1a42dd

Please sign in to comment.