Medium severityOSV Advisory· Published Jan 20, 2026· Updated Apr 15, 2026
CVE-2025-15282
CVE-2025-15282
Description
User-controlled data URLs parsed by urllib.request.DataHandler allow injecting headers through newlines in the data URL mediatype.
Affected products
1- Range: v0.9.8, v0.9.9, v1.0.1, …
Patches
6a35ca3be5842[3.13] gh-143925: Reject control characters in data: URL mediatypes (#144111)
3 files changed · +14 −0
Lib/test/test_urllib.py+8 −0 modified@@ -12,6 +12,7 @@ from test.support import os_helper from test.support import socket_helper from test.support import warnings_helper +from test.support import control_characters_c0 from test.support.testcase import ExtraAssertions import os try: @@ -677,6 +678,13 @@ def test_invalid_base64_data(self): # missing padding character self.assertRaises(ValueError,urllib.request.urlopen,'data:;base64,Cg=') + def test_invalid_mediatype(self): + for c0 in control_characters_c0(): + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html;{c0},data') + for c0 in control_characters_c0(): + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html{c0};base64,ZGF0YQ==') class urlretrieve_FileTests(unittest.TestCase): """Test urllib.urlretrieve() on local files"""
Lib/urllib/request.py+5 −0 modified@@ -1636,6 +1636,11 @@ def data_open(self, req): scheme, data = url.split(":",1) mediatype, data = data.split(",",1) + # Disallow control characters within mediatype. + if re.search(r"[\x00-\x1F\x7F]", mediatype): + raise ValueError( + "Control characters not allowed in data: mediatype") + # even base64 encoded data URLs might be quoted so unquote in any case: data = unquote_to_bytes(data) if mediatype.endswith(";base64"):
Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst+1 −0 added@@ -0,0 +1 @@ +Reject control characters in ``data:`` URL media types.
4ed11d3cd288[3.12] gh-143925: Reject control characters in data: URL mediatypes (#144113)
3 files changed · +14 −0
Lib/test/test_urllib.py+8 −0 modified@@ -12,6 +12,7 @@ from test.support import os_helper from test.support import socket_helper from test.support import warnings_helper +from test.support import control_characters_c0 import os try: import ssl @@ -688,6 +689,13 @@ def test_invalid_base64_data(self): # missing padding character self.assertRaises(ValueError,urllib.request.urlopen,'data:;base64,Cg=') + def test_invalid_mediatype(self): + for c0 in control_characters_c0(): + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html;{c0},data') + for c0 in control_characters_c0(): + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html{c0};base64,ZGF0YQ==') class urlretrieve_FileTests(unittest.TestCase): """Test urllib.urlretrieve() on local files"""
Lib/urllib/request.py+5 −0 modified@@ -1655,6 +1655,11 @@ def data_open(self, req): scheme, data = url.split(":",1) mediatype, data = data.split(",",1) + # Disallow control characters within mediatype. + if re.search(r"[\x00-\x1F\x7F]", mediatype): + raise ValueError( + "Control characters not allowed in data: mediatype") + # even base64 encoded data URLs might be quoted so unquote in any case: data = unquote_to_bytes(data) if mediatype.endswith(";base64"):
Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst+1 −0 added@@ -0,0 +1 @@ +Reject control characters in ``data:`` URL media types.
3f396ca9d7bb[3.11] gh-143925: Reject control characters in data: URL mediatypes (#144114)
3 files changed · +14 −0
Lib/test/test_urllib.py+8 −0 modified@@ -12,6 +12,7 @@ from test.support import os_helper from test.support import socket_helper from test.support import warnings_helper +from test.support import control_characters_c0 import os try: import ssl @@ -683,6 +684,13 @@ def test_invalid_base64_data(self): # missing padding character self.assertRaises(ValueError,urllib.request.urlopen,'data:;base64,Cg=') + def test_invalid_mediatype(self): + for c0 in control_characters_c0(): + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html;{c0},data') + for c0 in control_characters_c0(): + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html{c0};base64,ZGF0YQ==') class urlretrieve_FileTests(unittest.TestCase): """Test urllib.urlretrieve() on local files"""
Lib/urllib/request.py+5 −0 modified@@ -1654,6 +1654,11 @@ def data_open(self, req): scheme, data = url.split(":",1) mediatype, data = data.split(",",1) + # Disallow control characters within mediatype. + if re.search(r"[\x00-\x1F\x7F]", mediatype): + raise ValueError( + "Control characters not allowed in data: mediatype") + # even base64 encoded data URLs might be quoted so unquote in any case: data = unquote_to_bytes(data) if mediatype.endswith(";base64"):
Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst+1 −0 added@@ -0,0 +1 @@ +Reject control characters in ``data:`` URL media types.
34d76b00dabd[3.10] gh-143925: Reject control characters in data: URL mediatypes (#144115)
3 files changed · +14 −0
Lib/test/test_urllib.py+8 −0 modified@@ -11,6 +11,7 @@ from test import support from test.support import os_helper from test.support import warnings_helper +from test.support import control_characters_c0 import os try: import ssl @@ -683,6 +684,13 @@ def test_invalid_base64_data(self): # missing padding character self.assertRaises(ValueError,urllib.request.urlopen,'data:;base64,Cg=') + def test_invalid_mediatype(self): + for c0 in control_characters_c0(): + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html;{c0},data') + for c0 in control_characters_c0(): + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html{c0};base64,ZGF0YQ==') class urlretrieve_FileTests(unittest.TestCase): """Test urllib.urlretrieve() on local files"""
Lib/urllib/request.py+5 −0 modified@@ -1654,6 +1654,11 @@ def data_open(self, req): scheme, data = url.split(":",1) mediatype, data = data.split(",",1) + # Disallow control characters within mediatype. + if re.search(r"[\x00-\x1F\x7F]", mediatype): + raise ValueError( + "Control characters not allowed in data: mediatype") + # even base64 encoded data URLs might be quoted so unquote in any case: data = unquote_to_bytes(data) if mediatype.endswith(";base64"):
Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst+1 −0 added@@ -0,0 +1 @@ +Reject control characters in ``data:`` URL media types.
05356b1cc153[3.14] gh-143925: Reject control characters in data: URL mediatypes (#144084)
3 files changed · +14 −0
Lib/test/test_urllib.py+8 −0 modified@@ -10,6 +10,7 @@ from test import support from test.support import os_helper from test.support import socket_helper +from test.support import control_characters_c0 import os import socket try: @@ -590,6 +591,13 @@ def test_invalid_base64_data(self): # missing padding character self.assertRaises(ValueError,urllib.request.urlopen,'data:;base64,Cg=') + def test_invalid_mediatype(self): + for c0 in control_characters_c0(): + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html;{c0},data') + for c0 in control_characters_c0(): + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html{c0};base64,ZGF0YQ==') class urlretrieve_FileTests(unittest.TestCase): """Test urllib.urlretrieve() on local files"""
Lib/urllib/request.py+5 −0 modified@@ -1634,6 +1634,11 @@ def data_open(self, req): scheme, data = url.split(":",1) mediatype, data = data.split(",",1) + # Disallow control characters within mediatype. + if re.search(r"[\x00-\x1F\x7F]", mediatype): + raise ValueError( + "Control characters not allowed in data: mediatype") + # even base64 encoded data URLs might be quoted so unquote in any case: data = unquote_to_bytes(data) if mediatype.endswith(";base64"):
Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst+1 −0 added@@ -0,0 +1 @@ +Reject control characters in ``data:`` URL media types.
f25509e78e8bgh-143925: Reject control characters in data: URL mediatypes
3 files changed · +14 −0
Lib/test/test_urllib.py+8 −0 modified@@ -10,6 +10,7 @@ from test import support from test.support import os_helper from test.support import socket_helper +from test.support import control_characters_c0 import os import socket try: @@ -590,6 +591,13 @@ def test_invalid_base64_data(self): # missing padding character self.assertRaises(ValueError,urllib.request.urlopen,'data:;base64,Cg=') + def test_invalid_mediatype(self): + for c0 in control_characters_c0(): + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html;{c0},data') + for c0 in control_characters_c0(): + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html{c0};base64,ZGF0YQ==') class urlretrieve_FileTests(unittest.TestCase): """Test urllib.urlretrieve() on local files"""
Lib/urllib/request.py+5 −0 modified@@ -1636,6 +1636,11 @@ def data_open(self, req): scheme, data = url.split(":",1) mediatype, data = data.split(",",1) + # Disallow control characters within mediatype. + if re.search(r"[\x00-\x1F\x7F]", mediatype): + raise ValueError( + "Control characters not allowed in data: mediatype") + # even base64 encoded data URLs might be quoted so unquote in any case: data = unquote_to_bytes(data) if mediatype.endswith(";base64"):
Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst+1 −0 added@@ -0,0 +1 @@ +Reject control characters in ``data:`` URL media types.
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
9- github.com/python/cpython/commit/05356b1cc153108aaf27f3b72ce438af4aa218c0nvd
- github.com/python/cpython/commit/34d76b00dabde81a793bd06dd8ecb057838c4b38nvd
- github.com/python/cpython/commit/3f396ca9d7bbe2a50ea6b8c9b27c0082884d9f80nvd
- github.com/python/cpython/commit/4ed11d3cd288e6b90196a15c5a825a45d318fe47nvd
- github.com/python/cpython/commit/a35ca3be5842505dab74dc0b90b89cde0405017anvd
- github.com/python/cpython/commit/f25509e78e8be6ea73c811ac2b8c928c28841b9fnvd
- github.com/python/cpython/issues/143925nvd
- github.com/python/cpython/pull/143926nvd
- mail.python.org/archives/list/security-announce@python.org/thread/X66HL7SISGJT33J53OHXMZT4DFLMHVKF/nvd
News mentions
0No linked articles in our index yet.