diff mbox series

[meta-python,scarthgap,v2,7/8] python3-django: patch CVE-2025-59682

Message ID 20251022232633.1703690-8-ankur.tyagi85@gmail.com
State New
Headers show
Series python3-django CVE fixes | expand

Commit Message

Ankur Tyagi Oct. 22, 2025, 11:26 p.m. UTC
Details https://nvd.nist.gov/vuln/detail/CVE-2025-59682

Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
---
 .../CVE-2025-59682.patch                      | 72 +++++++++++++++++++
 .../python/python3-django_4.2.20.bb           |  1 +
 2 files changed, 73 insertions(+)
 create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-59682.patch

Comments

Anuj Mittal Oct. 30, 2025, 7:16 a.m. UTC | #1
Can we update straight to 4.2.25 instead that only has all these CVE
fixes and a few bug fixes?

On Thu, 2025-10-23 at 12:26 +1300, Ankur Tyagi via
lists.openembedded.org wrote:
> Details https://nvd.nist.gov/vuln/detail/CVE-2025-59682
> 
> Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
> ---
>  .../CVE-2025-59682.patch                      | 72
> +++++++++++++++++++
>  .../python/python3-django_4.2.20.bb           |  1 +
>  2 files changed, 73 insertions(+)
>  create mode 100644 meta-python/recipes-devtools/python/python3-
> django-4.2.20/CVE-2025-59682.patch
> 
> diff --git a/meta-python/recipes-devtools/python/python3-django-
> 4.2.20/CVE-2025-59682.patch b/meta-python/recipes-
> devtools/python/python3-django-4.2.20/CVE-2025-59682.patch
> new file mode 100644
> index 0000000000..72f566a0e1
> --- /dev/null
> +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-
> 2025-59682.patch
> @@ -0,0 +1,72 @@
> +From c757b620cd8099d17e202c0f5582bbab5564056c Mon Sep 17 00:00:00
> 2001
> +From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
> +Date: Tue, 16 Sep 2025 17:13:36 +0200
> +Subject: [PATCH] [4.2.x] Fixed CVE-2025-59682 -- Fixed potential
> partial
> + directory-traversal via archive.extract().
> +
> +Thanks stackered for the report.
> +
> +Follow up to 05413afa8c18cdb978fcdf470e09f7a12b234a23.
> +
> +Backport of 924a0c092e65fa2d0953fd1855d2dc8786d94de2 from main.
> +
> +CVE: CVE-2025-59682
> +Upstream-Status: Backport
> [https://github.com/django/django/commit/9504bbaa392c9fe37eee9291f5b4
> c29eb6037619]
> +(cherry picked from commit 9504bbaa392c9fe37eee9291f5b4c29eb6037619)
> +Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
> +---
> + django/utils/archive.py           |  6 +++++-
> + tests/utils_tests/test_archive.py | 19 +++++++++++++++++++
> + 2 files changed, 24 insertions(+), 1 deletion(-)
> +
> +diff --git a/django/utils/archive.py b/django/utils/archive.py
> +index 71ec2d0015..e8af690e27 100644
> +--- a/django/utils/archive.py
> ++++ b/django/utils/archive.py
> +@@ -144,7 +144,11 @@ class BaseArchive:
> +     def target_filename(self, to_path, name):
> +         target_path = os.path.abspath(to_path)
> +         filename = os.path.abspath(os.path.join(target_path, name))
> +-        if not filename.startswith(target_path):
> ++        try:
> ++            if os.path.commonpath([target_path, filename]) !=
> target_path:
> ++                raise SuspiciousOperation("Archive contains invalid
> path: '%s'" % name)
> ++        except ValueError:
> ++            # Different drives on Windows raises ValueError.
> +             raise SuspiciousOperation("Archive contains invalid
> path: '%s'" % name)
> +         return filename
> + 
> +diff --git a/tests/utils_tests/test_archive.py
> b/tests/utils_tests/test_archive.py
> +index 8cd107063f..8063dafb65 100644
> +--- a/tests/utils_tests/test_archive.py
> ++++ b/tests/utils_tests/test_archive.py
> +@@ -3,6 +3,7 @@ import stat
> + import sys
> + import tempfile
> + import unittest
> ++import zipfile
> + 
> + from django.core.exceptions import SuspiciousOperation
> + from django.test import SimpleTestCase
> +@@ -96,3 +97,21 @@ class TestArchiveInvalid(SimpleTestCase):
> +             with self.subTest(entry), tempfile.TemporaryDirectory()
> as tmpdir:
> +                 with self.assertRaisesMessage(SuspiciousOperation,
> msg % invalid_path):
> +                     archive.extract(os.path.join(archives_dir,
> entry), tmpdir)
> ++
> ++    def test_extract_function_traversal_startswith(self):
> ++        with tempfile.TemporaryDirectory() as tmpdir:
> ++            base = os.path.abspath(tmpdir)
> ++            tarfile_handle =
> tempfile.NamedTemporaryFile(suffix=".zip", delete=False)
> ++            tar_path = tarfile_handle.name
> ++            tarfile_handle.close()
> ++            self.addCleanup(os.remove, tar_path)
> ++
> ++            malicious_member = os.path.join(base + "abc",
> "evil.txt")
> ++            with zipfile.ZipFile(tar_path, "w") as zf:
> ++                zf.writestr(malicious_member, "evil\n")
> ++                zf.writestr("test.txt", "data\n")
> ++
> ++            with self.assertRaisesMessage(
> ++                SuspiciousOperation, "Archive contains invalid
> path"
> ++            ):
> ++                archive.extract(tar_path, base)
> diff --git a/meta-python/recipes-devtools/python/python3-
> django_4.2.20.bb b/meta-python/recipes-devtools/python/python3-
> django_4.2.20.bb
> index 443b4dbbfc..964b982fda 100644
> --- a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb
> +++ b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb
> @@ -12,6 +12,7 @@ SRC_URI += " \
>      file://CVE-2025-48432-6.patch \
>      file://CVE-2025-57833.patch \
>      file://CVE-2025-59681.patch \
> +    file://CVE-2025-59682.patch \
>  "
>  
>  SRC_URI[sha256sum] =
> "92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789"
> 
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#120908):
> https://lists.openembedded.org/g/openembedded-devel/message/120908
> Mute This Topic: https://lists.openembedded.org/mt/115902367/3616702
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe:
> https://lists.openembedded.org/g/openembedded-devel/unsub [
> anuj.mittal@intel.com]
> -=-=-=-=-=-=-=-=-=-=-=-
Ankur Tyagi Oct. 30, 2025, 10:15 a.m. UTC | #2
On Thu, Oct 30, 2025 at 8:16 PM Anuj Mittal via lists.openembedded.org
<anuj.mittal=intel.com@lists.openembedded.org> wrote:
>
> Can we update straight to 4.2.25 instead that only has all these CVE
> fixes and a few bug fixes?

Agree, please drop following patches for v4.x and I'll submit upgrade
to 4.2.25 separately
https://lists.openembedded.org/g/openembedded-devel/message/120902
https://lists.openembedded.org/g/openembedded-devel/message/120903
https://lists.openembedded.org/g/openembedded-devel/message/120904
https://lists.openembedded.org/g/openembedded-devel/message/120905
https://lists.openembedded.org/g/openembedded-devel/message/120906
https://lists.openembedded.org/g/openembedded-devel/message/120907
https://lists.openembedded.org/g/openembedded-devel/message/120908

>
> On Thu, 2025-10-23 at 12:26 +1300, Ankur Tyagi via
> lists.openembedded.org wrote:
> > Details https://nvd.nist.gov/vuln/detail/CVE-2025-59682
> >
> > Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
> > ---
> >  .../CVE-2025-59682.patch                      | 72
> > +++++++++++++++++++
> >  .../python/python3-django_4.2.20.bb           |  1 +
> >  2 files changed, 73 insertions(+)
> >  create mode 100644 meta-python/recipes-devtools/python/python3-
> > django-4.2.20/CVE-2025-59682.patch
> >
> > diff --git a/meta-python/recipes-devtools/python/python3-django-
> > 4.2.20/CVE-2025-59682.patch b/meta-python/recipes-
> > devtools/python/python3-django-4.2.20/CVE-2025-59682.patch
> > new file mode 100644
> > index 0000000000..72f566a0e1
> > --- /dev/null
> > +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-
> > 2025-59682.patch
> > @@ -0,0 +1,72 @@
> > +From c757b620cd8099d17e202c0f5582bbab5564056c Mon Sep 17 00:00:00
> > 2001
> > +From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
> > +Date: Tue, 16 Sep 2025 17:13:36 +0200
> > +Subject: [PATCH] [4.2.x] Fixed CVE-2025-59682 -- Fixed potential
> > partial
> > + directory-traversal via archive.extract().
> > +
> > +Thanks stackered for the report.
> > +
> > +Follow up to 05413afa8c18cdb978fcdf470e09f7a12b234a23.
> > +
> > +Backport of 924a0c092e65fa2d0953fd1855d2dc8786d94de2 from main.
> > +
> > +CVE: CVE-2025-59682
> > +Upstream-Status: Backport
> > [https://github.com/django/django/commit/9504bbaa392c9fe37eee9291f5b4
> > c29eb6037619]
> > +(cherry picked from commit 9504bbaa392c9fe37eee9291f5b4c29eb6037619)
> > +Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
> > +---
> > + django/utils/archive.py           |  6 +++++-
> > + tests/utils_tests/test_archive.py | 19 +++++++++++++++++++
> > + 2 files changed, 24 insertions(+), 1 deletion(-)
> > +
> > +diff --git a/django/utils/archive.py b/django/utils/archive.py
> > +index 71ec2d0015..e8af690e27 100644
> > +--- a/django/utils/archive.py
> > ++++ b/django/utils/archive.py
> > +@@ -144,7 +144,11 @@ class BaseArchive:
> > +     def target_filename(self, to_path, name):
> > +         target_path = os.path.abspath(to_path)
> > +         filename = os.path.abspath(os.path.join(target_path, name))
> > +-        if not filename.startswith(target_path):
> > ++        try:
> > ++            if os.path.commonpath([target_path, filename]) !=
> > target_path:
> > ++                raise SuspiciousOperation("Archive contains invalid
> > path: '%s'" % name)
> > ++        except ValueError:
> > ++            # Different drives on Windows raises ValueError.
> > +             raise SuspiciousOperation("Archive contains invalid
> > path: '%s'" % name)
> > +         return filename
> > +
> > +diff --git a/tests/utils_tests/test_archive.py
> > b/tests/utils_tests/test_archive.py
> > +index 8cd107063f..8063dafb65 100644
> > +--- a/tests/utils_tests/test_archive.py
> > ++++ b/tests/utils_tests/test_archive.py
> > +@@ -3,6 +3,7 @@ import stat
> > + import sys
> > + import tempfile
> > + import unittest
> > ++import zipfile
> > +
> > + from django.core.exceptions import SuspiciousOperation
> > + from django.test import SimpleTestCase
> > +@@ -96,3 +97,21 @@ class TestArchiveInvalid(SimpleTestCase):
> > +             with self.subTest(entry), tempfile.TemporaryDirectory()
> > as tmpdir:
> > +                 with self.assertRaisesMessage(SuspiciousOperation,
> > msg % invalid_path):
> > +                     archive.extract(os.path.join(archives_dir,
> > entry), tmpdir)
> > ++
> > ++    def test_extract_function_traversal_startswith(self):
> > ++        with tempfile.TemporaryDirectory() as tmpdir:
> > ++            base = os.path.abspath(tmpdir)
> > ++            tarfile_handle =
> > tempfile.NamedTemporaryFile(suffix=".zip", delete=False)
> > ++            tar_path = tarfile_handle.name
> > ++            tarfile_handle.close()
> > ++            self.addCleanup(os.remove, tar_path)
> > ++
> > ++            malicious_member = os.path.join(base + "abc",
> > "evil.txt")
> > ++            with zipfile.ZipFile(tar_path, "w") as zf:
> > ++                zf.writestr(malicious_member, "evil\n")
> > ++                zf.writestr("test.txt", "data\n")
> > ++
> > ++            with self.assertRaisesMessage(
> > ++                SuspiciousOperation, "Archive contains invalid
> > path"
> > ++            ):
> > ++                archive.extract(tar_path, base)
> > diff --git a/meta-python/recipes-devtools/python/python3-
> > django_4.2.20.bb b/meta-python/recipes-devtools/python/python3-
> > django_4.2.20.bb
> > index 443b4dbbfc..964b982fda 100644
> > --- a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb
> > +++ b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb
> > @@ -12,6 +12,7 @@ SRC_URI += " \
> >      file://CVE-2025-48432-6.patch \
> >      file://CVE-2025-57833.patch \
> >      file://CVE-2025-59681.patch \
> > +    file://CVE-2025-59682.patch \
> >  "
> >
> >  SRC_URI[sha256sum] =
> > "92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789"
> >
> >
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#121198): https://lists.openembedded.org/g/openembedded-devel/message/121198
> Mute This Topic: https://lists.openembedded.org/mt/115902367/3619737
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [ankur.tyagi85@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
Ankur Tyagi Oct. 30, 2025, 10:31 a.m. UTC | #3
On Thu, Oct 30, 2025 at 11:15 PM Ankur Tyagi via
lists.openembedded.org
<ankur.tyagi85=gmail.com@lists.openembedded.org> wrote:
>
> On Thu, Oct 30, 2025 at 8:16 PM Anuj Mittal via lists.openembedded.org
> <anuj.mittal=intel.com@lists.openembedded.org> wrote:
> >
> > Can we update straight to 4.2.25 instead that only has all these CVE
> > fixes and a few bug fixes?
>
> Agree, please drop following patches for v4.x and I'll submit upgrade
> to 4.2.25 separately
> https://lists.openembedded.org/g/openembedded-devel/message/120902
> https://lists.openembedded.org/g/openembedded-devel/message/120903
> https://lists.openembedded.org/g/openembedded-devel/message/120904
> https://lists.openembedded.org/g/openembedded-devel/message/120905
> https://lists.openembedded.org/g/openembedded-devel/message/120906
> https://lists.openembedded.org/g/openembedded-devel/message/120907
> https://lists.openembedded.org/g/openembedded-devel/message/120908
>

Starting with v4.2.21 [1], setuptools configuration migrated from
setup.py/setup.cfg to pyproject.toml
And [2] updated setuptools version causing following build error:

ERROR Missing dependencies:
    setuptools>=75.8.1; python_version >= "3.9"

[1] https://github.com/django/django/commit/afe52d89c4f42870622a4bb161ab5f4d4913aac5
[2] https://github.com/django/django/commit/3456eee4a3a00dc14e72d4f7d6eecc15ed9571e7

Any ideas to try?

> >
> > On Thu, 2025-10-23 at 12:26 +1300, Ankur Tyagi via
> > lists.openembedded.org wrote:
> > > Details https://nvd.nist.gov/vuln/detail/CVE-2025-59682
> > >
> > > Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
> > > ---
> > >  .../CVE-2025-59682.patch                      | 72
> > > +++++++++++++++++++
> > >  .../python/python3-django_4.2.20.bb           |  1 +
> > >  2 files changed, 73 insertions(+)
> > >  create mode 100644 meta-python/recipes-devtools/python/python3-
> > > django-4.2.20/CVE-2025-59682.patch
> > >
> > > diff --git a/meta-python/recipes-devtools/python/python3-django-
> > > 4.2.20/CVE-2025-59682.patch b/meta-python/recipes-
> > > devtools/python/python3-django-4.2.20/CVE-2025-59682.patch
> > > new file mode 100644
> > > index 0000000000..72f566a0e1
> > > --- /dev/null
> > > +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-
> > > 2025-59682.patch
> > > @@ -0,0 +1,72 @@
> > > +From c757b620cd8099d17e202c0f5582bbab5564056c Mon Sep 17 00:00:00
> > > 2001
> > > +From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
> > > +Date: Tue, 16 Sep 2025 17:13:36 +0200
> > > +Subject: [PATCH] [4.2.x] Fixed CVE-2025-59682 -- Fixed potential
> > > partial
> > > + directory-traversal via archive.extract().
> > > +
> > > +Thanks stackered for the report.
> > > +
> > > +Follow up to 05413afa8c18cdb978fcdf470e09f7a12b234a23.
> > > +
> > > +Backport of 924a0c092e65fa2d0953fd1855d2dc8786d94de2 from main.
> > > +
> > > +CVE: CVE-2025-59682
> > > +Upstream-Status: Backport
> > > [https://github.com/django/django/commit/9504bbaa392c9fe37eee9291f5b4
> > > c29eb6037619]
> > > +(cherry picked from commit 9504bbaa392c9fe37eee9291f5b4c29eb6037619)
> > > +Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
> > > +---
> > > + django/utils/archive.py           |  6 +++++-
> > > + tests/utils_tests/test_archive.py | 19 +++++++++++++++++++
> > > + 2 files changed, 24 insertions(+), 1 deletion(-)
> > > +
> > > +diff --git a/django/utils/archive.py b/django/utils/archive.py
> > > +index 71ec2d0015..e8af690e27 100644
> > > +--- a/django/utils/archive.py
> > > ++++ b/django/utils/archive.py
> > > +@@ -144,7 +144,11 @@ class BaseArchive:
> > > +     def target_filename(self, to_path, name):
> > > +         target_path = os.path.abspath(to_path)
> > > +         filename = os.path.abspath(os.path.join(target_path, name))
> > > +-        if not filename.startswith(target_path):
> > > ++        try:
> > > ++            if os.path.commonpath([target_path, filename]) !=
> > > target_path:
> > > ++                raise SuspiciousOperation("Archive contains invalid
> > > path: '%s'" % name)
> > > ++        except ValueError:
> > > ++            # Different drives on Windows raises ValueError.
> > > +             raise SuspiciousOperation("Archive contains invalid
> > > path: '%s'" % name)
> > > +         return filename
> > > +
> > > +diff --git a/tests/utils_tests/test_archive.py
> > > b/tests/utils_tests/test_archive.py
> > > +index 8cd107063f..8063dafb65 100644
> > > +--- a/tests/utils_tests/test_archive.py
> > > ++++ b/tests/utils_tests/test_archive.py
> > > +@@ -3,6 +3,7 @@ import stat
> > > + import sys
> > > + import tempfile
> > > + import unittest
> > > ++import zipfile
> > > +
> > > + from django.core.exceptions import SuspiciousOperation
> > > + from django.test import SimpleTestCase
> > > +@@ -96,3 +97,21 @@ class TestArchiveInvalid(SimpleTestCase):
> > > +             with self.subTest(entry), tempfile.TemporaryDirectory()
> > > as tmpdir:
> > > +                 with self.assertRaisesMessage(SuspiciousOperation,
> > > msg % invalid_path):
> > > +                     archive.extract(os.path.join(archives_dir,
> > > entry), tmpdir)
> > > ++
> > > ++    def test_extract_function_traversal_startswith(self):
> > > ++        with tempfile.TemporaryDirectory() as tmpdir:
> > > ++            base = os.path.abspath(tmpdir)
> > > ++            tarfile_handle =
> > > tempfile.NamedTemporaryFile(suffix=".zip", delete=False)
> > > ++            tar_path = tarfile_handle.name
> > > ++            tarfile_handle.close()
> > > ++            self.addCleanup(os.remove, tar_path)
> > > ++
> > > ++            malicious_member = os.path.join(base + "abc",
> > > "evil.txt")
> > > ++            with zipfile.ZipFile(tar_path, "w") as zf:
> > > ++                zf.writestr(malicious_member, "evil\n")
> > > ++                zf.writestr("test.txt", "data\n")
> > > ++
> > > ++            with self.assertRaisesMessage(
> > > ++                SuspiciousOperation, "Archive contains invalid
> > > path"
> > > ++            ):
> > > ++                archive.extract(tar_path, base)
> > > diff --git a/meta-python/recipes-devtools/python/python3-
> > > django_4.2.20.bb b/meta-python/recipes-devtools/python/python3-
> > > django_4.2.20.bb
> > > index 443b4dbbfc..964b982fda 100644
> > > --- a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb
> > > +++ b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb
> > > @@ -12,6 +12,7 @@ SRC_URI += " \
> > >      file://CVE-2025-48432-6.patch \
> > >      file://CVE-2025-57833.patch \
> > >      file://CVE-2025-59681.patch \
> > > +    file://CVE-2025-59682.patch \
> > >  "
> > >
> > >  SRC_URI[sha256sum] =
> > > "92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789"
> > >
> > >
> >
> >
> >
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#121203): https://lists.openembedded.org/g/openembedded-devel/message/121203
> Mute This Topic: https://lists.openembedded.org/mt/115902367/3619737
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [ankur.tyagi85@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
diff mbox series

Patch

diff --git a/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-59682.patch b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-59682.patch
new file mode 100644
index 0000000000..72f566a0e1
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-59682.patch
@@ -0,0 +1,72 @@ 
+From c757b620cd8099d17e202c0f5582bbab5564056c Mon Sep 17 00:00:00 2001
+From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
+Date: Tue, 16 Sep 2025 17:13:36 +0200
+Subject: [PATCH] [4.2.x] Fixed CVE-2025-59682 -- Fixed potential partial
+ directory-traversal via archive.extract().
+
+Thanks stackered for the report.
+
+Follow up to 05413afa8c18cdb978fcdf470e09f7a12b234a23.
+
+Backport of 924a0c092e65fa2d0953fd1855d2dc8786d94de2 from main.
+
+CVE: CVE-2025-59682
+Upstream-Status: Backport [https://github.com/django/django/commit/9504bbaa392c9fe37eee9291f5b4c29eb6037619]
+(cherry picked from commit 9504bbaa392c9fe37eee9291f5b4c29eb6037619)
+Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
+---
+ django/utils/archive.py           |  6 +++++-
+ tests/utils_tests/test_archive.py | 19 +++++++++++++++++++
+ 2 files changed, 24 insertions(+), 1 deletion(-)
+
+diff --git a/django/utils/archive.py b/django/utils/archive.py
+index 71ec2d0015..e8af690e27 100644
+--- a/django/utils/archive.py
++++ b/django/utils/archive.py
+@@ -144,7 +144,11 @@ class BaseArchive:
+     def target_filename(self, to_path, name):
+         target_path = os.path.abspath(to_path)
+         filename = os.path.abspath(os.path.join(target_path, name))
+-        if not filename.startswith(target_path):
++        try:
++            if os.path.commonpath([target_path, filename]) != target_path:
++                raise SuspiciousOperation("Archive contains invalid path: '%s'" % name)
++        except ValueError:
++            # Different drives on Windows raises ValueError.
+             raise SuspiciousOperation("Archive contains invalid path: '%s'" % name)
+         return filename
+ 
+diff --git a/tests/utils_tests/test_archive.py b/tests/utils_tests/test_archive.py
+index 8cd107063f..8063dafb65 100644
+--- a/tests/utils_tests/test_archive.py
++++ b/tests/utils_tests/test_archive.py
+@@ -3,6 +3,7 @@ import stat
+ import sys
+ import tempfile
+ import unittest
++import zipfile
+ 
+ from django.core.exceptions import SuspiciousOperation
+ from django.test import SimpleTestCase
+@@ -96,3 +97,21 @@ class TestArchiveInvalid(SimpleTestCase):
+             with self.subTest(entry), tempfile.TemporaryDirectory() as tmpdir:
+                 with self.assertRaisesMessage(SuspiciousOperation, msg % invalid_path):
+                     archive.extract(os.path.join(archives_dir, entry), tmpdir)
++
++    def test_extract_function_traversal_startswith(self):
++        with tempfile.TemporaryDirectory() as tmpdir:
++            base = os.path.abspath(tmpdir)
++            tarfile_handle = tempfile.NamedTemporaryFile(suffix=".zip", delete=False)
++            tar_path = tarfile_handle.name
++            tarfile_handle.close()
++            self.addCleanup(os.remove, tar_path)
++
++            malicious_member = os.path.join(base + "abc", "evil.txt")
++            with zipfile.ZipFile(tar_path, "w") as zf:
++                zf.writestr(malicious_member, "evil\n")
++                zf.writestr("test.txt", "data\n")
++
++            with self.assertRaisesMessage(
++                SuspiciousOperation, "Archive contains invalid path"
++            ):
++                archive.extract(tar_path, base)
diff --git a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb
index 443b4dbbfc..964b982fda 100644
--- a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb
+++ b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb
@@ -12,6 +12,7 @@  SRC_URI += " \
     file://CVE-2025-48432-6.patch \
     file://CVE-2025-57833.patch \
     file://CVE-2025-59681.patch \
+    file://CVE-2025-59682.patch \
 "
 
 SRC_URI[sha256sum] = "92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789"