From patchwork Wed Oct 22 23:26:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 72866 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8BEF0CCD1AB for ; Wed, 22 Oct 2025 23:27:17 +0000 (UTC) Received: from mail-pf1-f180.google.com (mail-pf1-f180.google.com [209.85.210.180]) by mx.groups.io with SMTP id smtpd.web11.8324.1761175632588983064 for ; Wed, 22 Oct 2025 16:27:12 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20230601 header.b=PYG7D5E5; spf=pass (domain: gmail.com, ip: 209.85.210.180, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pf1-f180.google.com with SMTP id d2e1a72fcca58-7a1603a098eso124836b3a.1 for ; Wed, 22 Oct 2025 16:27:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761175632; x=1761780432; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=mdO42SslM9g0kLFrj28C3Rj40IWCy/JfvwZG5jRoJao=; b=PYG7D5E5JD8ln0MN8KEb7AhDXFigf/723DVubgi8KVeqmGWB+pW6YtdoT+pppMP9/Q pUITUvwBQJ8a4ytx6GPdeIDu8YYp8GYeYxz08yP3DpIRdSsbtlo61Y1NDZePZvgb4/Q3 rXFWXbme5OfpOYzmpyXXtDKbdXqAbNT+bRM2p6SCiLnUfPygHYy9Da+JV2dJLJkDcUp1 CjE/WXuuQUkJaLAFnCaFaLulw6kWMNFeUIF+rR3ENv/OQqjFcIRhR71GHM7x/LTB+xXs XBhaMPMilP54B5DbrtoP5+8q2TxU2bnnMaS3VNRmBNI7l5lTOjFYncAv6zX5fGxK5OBG NfNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761175632; x=1761780432; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mdO42SslM9g0kLFrj28C3Rj40IWCy/JfvwZG5jRoJao=; b=j5SgYmGF8PLyKiau8sFCwFm8jbBNhd5DvjtBjR0w92ICZRiJ7Xck8t7qRrTvdL8ppJ +1RPCcVQFHV7l1rErLa7oWbeLcG6LeJ3ASzoxe1i1uZDusTlBYXVVBtD7DRp39Hr507H TYifAPRrx13/4diOF08g34vrfkt56h/bXzPKfkHZMiqliwJ2YA+aQMU33XSlu4jG6BTk 3Lna/tL0DNtVSOiDI0vPSSa6jFAM7XK6137OikegwbbJDSxR9Wf8u6g99MVP06mz1Ewa UbtA0Cc0fr9Cin/r4e51tg8ygRtAIxkxG+gPMg/rQXAVab+QqMPs+UcqIclxCq7Ub5K9 Xi3Q== X-Gm-Message-State: AOJu0YyF9cigqU6NDR7WMAqghpkS8P+cnobrfATky3+/FaadTO9V3qne of2YM4mVWpMuA2P2SfddUcIz6aXq148xJTx0yV1Fmxp/LS/cSFQSbMyhxHKMqg== X-Gm-Gg: ASbGncsxiQwoZ1SfD154kxcpUKxqvpu19jmCaIWbFXLbwXMp6GbboQDJtsGRY4/40FA dW92CLOZGF9NoBKllcBhXJhMKxmiT/mfSNMmhb33W4m+tqE4QBxEeG9FtylUgcLKfQF513QR8eP WtmJmiQ89WxzWPrXr7gJ0bvj2ZHYJC57l1VB0iWqoi/kQkpREtm17iH2g2L/5K5ojYIdpsYnzNQ kWrLcHietT2GCKEcZtO7T6CIlFYeQfLrq3APKZ7ZvUfIbSMNRUXsWA+32R3PU6CyJ+7uCyNcOL+ 6uqPJZirp0KY1AENVj1gnjZ+fvZ8dR05mhh6mGU3sUOJM/CRPcbRq6CRY4gYlKxTrX6p+e/2+ct q2yLnBF7OPAUOv76sIQTGxNdFg9IE2oL1bbvJZtnAshjhpraagXNvghMXrPhPYOdhHNbJVDUAPO BtiPAjjims91jaLBF7HNsF+koM X-Google-Smtp-Source: AGHT+IHigKGl8PD1XQGwAVyl9Vrj2TETpHRTPf6fYm4U7P7/I87S9ev4awqYJmjfXXPFCCpWR7k/Kw== X-Received: by 2002:a05:6a20:9144:b0:334:a23b:50bc with SMTP id adf61e73a8af0-334a8610fddmr27758775637.37.1761175631720; Wed, 22 Oct 2025 16:27:11 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([147.161.216.252]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-33fb01919aasm331129a91.17.2025.10.22.16.27.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Oct 2025 16:27:11 -0700 (PDT) From: Ankur Tyagi To: openembedded-devel@lists.openembedded.org Cc: Soumya Sambu , Khem Raj , Ankur Tyagi Subject: [oe][meta-python][scarthgap][PATCH v2 1/8] python3-django: upgrade 4.2.18 -> 4.2.20 Date: Thu, 23 Oct 2025 12:26:24 +1300 Message-ID: <20251022232633.1703690-2-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> References: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 22 Oct 2025 23:27:17 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/120902 From: Soumya Sambu Includes fix for CVE-2025-26699 Release Notes: https://docs.djangoproject.com/en/dev/releases/4.2.19/ https://docs.djangoproject.com/en/dev/releases/4.2.20/ Signed-off-by: Soumya Sambu Signed-off-by: Khem Raj (cherry picked from commit 54f5df8907cbf1212d0733ffddc049c7b8b8aaf0) Signed-off-by: Ankur Tyagi --- .../{python3-django_4.2.18.bb => python3-django_4.2.20.bb} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename meta-python/recipes-devtools/python/{python3-django_4.2.18.bb => python3-django_4.2.20.bb} (63%) diff --git a/meta-python/recipes-devtools/python/python3-django_4.2.18.bb b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb similarity index 63% rename from meta-python/recipes-devtools/python/python3-django_4.2.18.bb rename to meta-python/recipes-devtools/python/python3-django_4.2.20.bb index c9be3c0462..3fb8b03224 100644 --- a/meta-python/recipes-devtools/python/python3-django_4.2.18.bb +++ b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb @@ -1,7 +1,7 @@ require python-django.inc inherit setuptools3 -SRC_URI[sha256sum] = "52ae8eacf635617c0f13b44f749e5ea13dc34262819b2cc8c8636abb08d82c4b" +SRC_URI[sha256sum] = "92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789" RDEPENDS:${PN} += "\ python3-sqlparse \ @@ -10,5 +10,5 @@ RDEPENDS:${PN} += "\ # Set DEFAULT_PREFERENCE so that the LTS version of django is built by # default. To build the 4.x branch, -# PREFERRED_VERSION_python3-django = "4.2.18" can be added to local.conf +# PREFERRED_VERSION_python3-django = "4.2.20" can be added to local.conf DEFAULT_PREFERENCE = "-1" From patchwork Wed Oct 22 23:26:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 72865 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8EB0BCCD1BF for ; Wed, 22 Oct 2025 23:27:17 +0000 (UTC) Received: from mail-pj1-f50.google.com (mail-pj1-f50.google.com [209.85.216.50]) by mx.groups.io with SMTP id smtpd.web11.8325.1761175634965805253 for ; Wed, 22 Oct 2025 16:27:15 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20230601 header.b=MPgmH65N; spf=pass (domain: gmail.com, ip: 209.85.216.50, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f50.google.com with SMTP id 98e67ed59e1d1-3327f8ed081so235676a91.1 for ; Wed, 22 Oct 2025 16:27:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761175634; x=1761780434; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=saZA9fcNAi2rikXcd/HjdxfFH5D6caLJo6CQbjzWY3s=; b=MPgmH65NfZHitwCGWBZJFnerOHHJPzgbBjWBOwFIUOFMgRzSh/2f28hbXBwthM08AZ 415tdYpCWErkmUJrczvm6BO9jTiRN6ggv9is0djVhkoMOdtt6IhfgLovp2xbivgYUV2z fXcl34mDEZuerSl+pVdiQzQJXt4wghjB2ONK+pdGa0fuqSsyXXiMDIcjM6eEShYV02x3 UsuU+LBEGNwBy14z04WVtBc8dtu936f8eXEVHcNcwSYb6gqhZmgfm6la+oKQQgfEPjGs VJXFfpQ4BxKkV1ca1oXXrbG+ztF4dM6BZn012lQ70IQX4sJcIhAaf/A5lcpvkmI8owQK ct+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761175634; x=1761780434; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=saZA9fcNAi2rikXcd/HjdxfFH5D6caLJo6CQbjzWY3s=; b=LDxV68a36LMXANvXTJ9pkxYtLtb7UxgBcVmmvaiseXwA7GQcOIQAb6yKpNvnRrUeut nQqYZW4s23lOPnQAgCglfQTB4Q6aK2wNggxOTbMlXmbd/2fIUKVmVAbGu+6HHU/9uWS+ yAxgHQ8qguZeHDSSzobLdyq/g9LXIfUMumJCs1vJqhALRMylK5Xqnnv3UeiNbKYhl4tl FgaaKSNb/6IYptX2prmDvOtnImCg8dLsV61Os/2QeIY1OlC580uIZzNbUyQL1OQURhRz Jp8KBFkrBMvie1LBMEqnfM4T0tJ4SA5S0MNzPR641Y9AunmH61Ue+Uxo5++HKJKHSz/x vqHQ== X-Gm-Message-State: AOJu0YzXkRiBMrX92K47bfDePTjmk1gcY7L6XIXKiFwfEbm0KOHhAjhr CwSOLrKoza+/FxH6tFAlqKcNAciOI7gPKZfEZi53kcuM48XD517tUt+PKGRZ1A== X-Gm-Gg: ASbGnctqRR4mE0rcXtS1mJu6pLSErvnt+dy4MCa2R/9Sn41TDXcCVFmGIo4/CRRj3Ct K7DsIkmxW74oOtvyhcDaJY2s8jIXBrRLndBe+PvyftOcSIKWOs7gKFqlTofMLRG4YNm1UDgdFnC dhaVwhscTbolJicYHd/5Fs3QCgXAK7mZC4A0ib3qhAL6SeRs/tqh1v7+VKEgcVkoyiEegaymRP4 Gt3wRCkehHiVoMU7KEM18iPANuGjMAnvdCP+on7Lx1d2gPJsngNP8yajgk8PLmbpxhfzybaXUqQ vsV5nop5tEfZh2tXtrJvWC5TBLD1EmqsXclqJc/R6GTaKeXvoRwHrQyqbyY+jqrTkmzImtBYhs/ bHGXmPLRQFv0i8wyWsmo5HUOQZk2a0XodDi8Zvw0T1k8dfmira4slT+M0Kgg3nqSRX+Fyebafev dAeBpyjMIGZna+s52GsOUnyIQ4 X-Google-Smtp-Source: AGHT+IGKRknTdlaBo/Rjo3/jHOwl+dw7QMN+LVwiIkRs7eysJW5txbYFG6S03vkMBO+BwgY3Iae9UA== X-Received: by 2002:a17:90b:3fc6:b0:329:e9da:35e9 with SMTP id 98e67ed59e1d1-33bcf84e3e2mr25288878a91.2.1761175633870; Wed, 22 Oct 2025 16:27:13 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([147.161.216.252]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-33fb01919aasm331129a91.17.2025.10.22.16.27.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Oct 2025 16:27:13 -0700 (PDT) From: Ankur Tyagi To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-python][scarthgap][PATCH v2 2/8] python-django: fix 4.2.20 regression Date: Thu, 23 Oct 2025 12:26:25 +1300 Message-ID: <20251022232633.1703690-3-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> References: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 22 Oct 2025 23:27:17 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/120903 This fixes a regression in Django 4.2.20, introduced when fixing CVE-2025-26699 Details https://code.djangoproject.com/ticket/36341 Signed-off-by: Ankur Tyagi --- ...ntroduced-when-fixing-CVE-2025-26699.patch | 102 ++++++++++++++++++ .../python/python3-django_4.2.20.bb | 4 + 2 files changed, 106 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/fix-regression-introduced-when-fixing-CVE-2025-26699.patch diff --git a/meta-python/recipes-devtools/python/python3-django-4.2.20/fix-regression-introduced-when-fixing-CVE-2025-26699.patch b/meta-python/recipes-devtools/python/python3-django-4.2.20/fix-regression-introduced-when-fixing-CVE-2025-26699.patch new file mode 100644 index 0000000000..0b4dd69f2c --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/fix-regression-introduced-when-fixing-CVE-2025-26699.patch @@ -0,0 +1,102 @@ +From 9e8a009a7360349d5adb96e896a0a17f53dc9826 Mon Sep 17 00:00:00 2001 +From: Matti Pohjanvirta +Date: Sun, 20 Apr 2025 18:22:51 +0300 +Subject: [PATCH] Fix regression introduced when fixing CVE-2025-26699 + +[4.2.x] Fixed #36341 -- Preserved whitespaces in wordwrap template filter. + +Regression in 55d89e25f4115c5674cdd9b9bcba2bb2bb6d820b. + +This work improves the django.utils.text.wrap() function to ensure that +empty lines and lines with whitespace only are kept instead of being +dropped. + +Thanks Matti Pohjanvirta for the report and fix. + +Co-authored-by: Natalia <124304+nessita@users.noreply.github.com> + +Backport of 1e9db35836d42a3c72f3d1015c2f302eb6fee046 from main. + +Upstream-Status: Backport [https://github.com/django/django/commit/e61e3daaf037507211028494d61f24382be31e5a] +(cherry picked from commit e61e3daaf037507211028494d61f24382be31e5a) +Signed-off-by: Ankur Tyagi +--- + django/utils/text.py | 13 +++++- + .../filter_tests/test_wordwrap.py | 41 +++++++++++++++++++ + 2 files changed, 52 insertions(+), 2 deletions(-) + +diff --git a/django/utils/text.py b/django/utils/text.py +index 81ae88dc76..b018f2601f 100644 +--- a/django/utils/text.py ++++ b/django/utils/text.py +@@ -102,10 +102,19 @@ def wrap(text, width): + width=width, + break_long_words=False, + break_on_hyphens=False, ++ replace_whitespace=False, + ) + result = [] +- for line in text.splitlines(True): +- result.extend(wrapper.wrap(line)) ++ for line in text.splitlines(): ++ wrapped = wrapper.wrap(line) ++ if not wrapped: ++ # If `line` contains only whitespaces that are dropped, restore it. ++ result.append(line) ++ else: ++ result.extend(wrapped) ++ if text.endswith("\n"): ++ # If `text` ends with a newline, preserve it. ++ result.append("") + return "\n".join(result) + + +diff --git a/tests/template_tests/filter_tests/test_wordwrap.py b/tests/template_tests/filter_tests/test_wordwrap.py +index 4afa1dd234..1692332e1e 100644 +--- a/tests/template_tests/filter_tests/test_wordwrap.py ++++ b/tests/template_tests/filter_tests/test_wordwrap.py +@@ -89,3 +89,44 @@ class FunctionTests(SimpleTestCase): + "I'm afraid", + wordwrap(long_text, 10), + ) ++ ++ def test_wrap_preserve_newlines(self): ++ cases = [ ++ ( ++ "this is a long paragraph of text that really needs to be wrapped\n\n" ++ "that is followed by another paragraph separated by an empty line\n", ++ "this is a long paragraph of\ntext that really needs to be\nwrapped\n\n" ++ "that is followed by another\nparagraph separated by an\nempty line\n", ++ 30, ++ ), ++ ("\n\n\n", "\n\n\n", 5), ++ ("\n\n\n\n\n\n", "\n\n\n\n\n\n", 5), ++ ] ++ for text, expected, width in cases: ++ with self.subTest(text=text): ++ self.assertEqual(wordwrap(text, width), expected) ++ ++ def test_wrap_preserve_whitespace(self): ++ width = 5 ++ width_spaces = " " * width ++ cases = [ ++ ( ++ f"first line\n{width_spaces}\nsecond line", ++ f"first\nline\n{width_spaces}\nsecond\nline", ++ ), ++ ( ++ "first line\n \t\t\t \nsecond line", ++ "first\nline\n \t\t\t \nsecond\nline", ++ ), ++ ( ++ f"first line\n{width_spaces}\nsecond line\n\nthird{width_spaces}\n", ++ f"first\nline\n{width_spaces}\nsecond\nline\n\nthird\n", ++ ), ++ ( ++ f"first line\n{width_spaces}{width_spaces}\nsecond line", ++ f"first\nline\n{width_spaces}{width_spaces}\nsecond\nline", ++ ), ++ ] ++ for text, expected in cases: ++ with self.subTest(text=text): ++ self.assertEqual(wordwrap(text, width), expected) 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 3fb8b03224..1bb14aeb71 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 @@ -1,6 +1,10 @@ require python-django.inc inherit setuptools3 +SRC_URI += " \ + file://fix-regression-introduced-when-fixing-CVE-2025-26699.patch \ +" + SRC_URI[sha256sum] = "92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789" RDEPENDS:${PN} += "\ From patchwork Wed Oct 22 23:26:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 72867 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94834CCD1BE for ; Wed, 22 Oct 2025 23:27:17 +0000 (UTC) Received: from mail-pg1-f173.google.com (mail-pg1-f173.google.com [209.85.215.173]) by mx.groups.io with SMTP id smtpd.web10.8321.1761175636828911251 for ; Wed, 22 Oct 2025 16:27:16 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20230601 header.b=SzGqaXDI; spf=pass (domain: gmail.com, ip: 209.85.215.173, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f173.google.com with SMTP id 41be03b00d2f7-b6ce696c18bso115143a12.1 for ; Wed, 22 Oct 2025 16:27:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761175636; x=1761780436; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=f5vU6Yq39HmNeo1b0ZZY0rUj7ENO7+WY0pON3c/LQY4=; b=SzGqaXDI3KRxM5m9wv5dR8hul+jDgTkaGorhXRQmtlgCJo58SIjTljtGPWbw/qdnam Nm9Myjru9w26lus5NRroNNO1CJCGuETjiMf3CveYc4xw5bQKwAKzj2UfZLDz07Ehk1fO UTqmiUcAejYuh6rD7W1yxqqpoJwjNvlg/Mx5/hYACouBUn9ngtN2w89qLLYDcGGclDcM BfmF4zc5HjaZnEZLuv5UC7tO1x6SSSCMlGR6qIAZnXdHPP4xfCc+vMI1PmIRSDA5AUjc v7L9x/znEHEykV7sYm/TFZrrn8m/gzQ1sJkl1wkXWQ2z1/cLn/cOvogbBDWV88PvbEr8 ooVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761175636; x=1761780436; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=f5vU6Yq39HmNeo1b0ZZY0rUj7ENO7+WY0pON3c/LQY4=; b=DI1ncbz0lBRPBGFfMwyyagJAlCoi9lK2upDvUNARkrKWT5koqVoOslewD0ggz4+qM+ 7oBI6V0EKiFba6z8A6Nrh9C5B9RuU0y+ZE5epUnhZOHJbYPqX+KzbXSyNKeL07CXzMsi WK+n6NiF55vdian2ON3ChI+2ebcg5ydv0xNVZTImwy/RJSeMRPIj5V3f89zdCwo4JXcM RGnDN5PWhaE+DEmj13HzQ958cMRfYM5qbht9irIsGGET66SmROGFxegjIEkM+XT8kmL2 dJaz7nEemsza1AMfAYpoqX1Z2XnK++jVKtY2T8SAAakLbeWI+2DwyvI7prsz4V11Yk7z Pqmw== X-Gm-Message-State: AOJu0YyVDuILmRHbHpd0f90wQ5MWwKnfkepEwEV1mjGjcYvs8Zxyx5uF 5SCx74x09SsTDmqYeFCTM2JPJJ6kioJGiNvOmY2IwEMhl4p9woLATkbK3FgLlA== X-Gm-Gg: ASbGncuIH7y/LChMQ3Lrh0vBopvy83iPyrUD3KWRiPetj3A0UfRHPxjr+akFpAcmxwT F+6fhNrrjAxzXuvB13m4eoALhYTUi0dMjNsOQu/VUJdukvJR3Spwv/yjrbnWktIubfPuwfanxtU 6LZOh7QYB+zs6fzWfgc/XiRY0I++Pole8NUqFZfbgT38H9inMC0mmjSYmIlh3YWx1pBdaSL+DqK +pjRJfMxPO1IiSjhka2LKRznpgj7GAV8hSK/Dt+OOuggPhDS1c3Q9nI1nmzchIA34L6brFVxRib 66E20xZWksHpPeup5NGIrx6Sopx77wkAV7Xn/JilcyMymiCE/JISlYEkhD4W0xshPbeBJdzVgog PR52py+DYRQ8YI264L3Poo1BlPLpRMTSF+8gThEIexIl9wtputlRh1maFKzkAQ6M9pUU7/cfah0 csk1FwM/OXWl83pyS8rjzN6hIW X-Google-Smtp-Source: AGHT+IE4aQOnEkZGfl2F2IwHXBe4ujkzHY55Wxu2B1uV12U5PIVP+p6paY0T+K7bHCxIIMpixcph3w== X-Received: by 2002:a17:902:f691:b0:278:bfae:3244 with SMTP id d9443c01a7336-290cba4382amr286191535ad.54.1761175635931; Wed, 22 Oct 2025 16:27:15 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([147.161.216.252]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-33fb01919aasm331129a91.17.2025.10.22.16.27.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Oct 2025 16:27:15 -0700 (PDT) From: Ankur Tyagi To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-python][scarthgap][PATCH v2 3/8] python3-django: patch CVE-2025-32873 Date: Thu, 23 Oct 2025 12:26:26 +1300 Message-ID: <20251022232633.1703690-4-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> References: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 22 Oct 2025 23:27:17 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/120904 Details https://nvd.nist.gov/vuln/detail/CVE-2025-32873 Signed-off-by: Ankur Tyagi --- .../CVE-2025-32873.patch | 86 +++++++++++++++++++ .../python/python3-django_4.2.20.bb | 1 + 2 files changed, 87 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-32873.patch diff --git a/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-32873.patch b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-32873.patch new file mode 100644 index 0000000000..cb1e32846a --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-32873.patch @@ -0,0 +1,86 @@ +From 3571c537ae0b504cf1326807908682f28aff9613 Mon Sep 17 00:00:00 2001 +From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> +Date: Tue, 8 Apr 2025 16:30:17 +0200 +Subject: [PATCH] CVE-2025-32873 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[4.2.x] Fixed CVE-2025-32873 -- Mitigated potential DoS in strip_tags(). + +Thanks to Elias Myllymäki for the report, and Shai Berger and Jake +Howard for the reviews. + +Co-authored-by: Natalia <124304+nessita@users.noreply.github.com> + +Backport of 9f3419b519799d69f2aba70b9d25abe2e70d03e0 from main. + +CVE: CVE-2025-32873 +Upstream-Status: Backport [https://github.com/django/django/commit/9cd8028f3e38dca8e51c1388f474eecbe7d6ca3c] +(cherry picked from commit 9cd8028f3e38dca8e51c1388f474eecbe7d6ca3c) +Signed-off-by: Ankur Tyagi +--- + django/utils/html.py | 6 ++++++ + tests/utils_tests/test_html.py | 15 ++++++++++++++- + 2 files changed, 20 insertions(+), 1 deletion(-) + +diff --git a/django/utils/html.py b/django/utils/html.py +index a3a7238cba..84c37d1186 100644 +--- a/django/utils/html.py ++++ b/django/utils/html.py +@@ -17,6 +17,9 @@ from django.utils.text import normalize_newlines + MAX_URL_LENGTH = 2048 + MAX_STRIP_TAGS_DEPTH = 50 + ++# HTML tag that opens but has no closing ">" after 1k+ chars. ++long_open_tag_without_closing_re = _lazy_re_compile(r"<[a-zA-Z][^>]{1000,}") ++ + + @keep_lazy(SafeString) + def escape(text): +@@ -175,6 +178,9 @@ def _strip_once(value): + def strip_tags(value): + """Return the given HTML with all tags stripped.""" + value = str(value) ++ for long_open_tag in long_open_tag_without_closing_re.finditer(value): ++ if long_open_tag.group().count("<") >= MAX_STRIP_TAGS_DEPTH: ++ raise SuspiciousOperation + # Note: in typical case this loop executes _strip_once twice (the second + # execution does not remove any more tags). + strip_tags_depth = 0 +diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py +index 579bb2a1e3..25168e2348 100644 +--- a/tests/utils_tests/test_html.py ++++ b/tests/utils_tests/test_html.py +@@ -115,17 +115,30 @@ class TestUtilsHtml(SimpleTestCase): + (">br>br>br>X", "XX"), + ("<" * 50 + "a>" * 50, ""), ++ (">" + "" + "" * 51, "" + with self.assertRaises(SuspiciousOperation): + strip_tags(value) + ++ def test_strip_tags_suspicious_operation_large_open_tags(self): ++ items = [ ++ ">" + " X-Patchwork-Id: 72870 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8F098CCD1BE for ; Wed, 22 Oct 2025 23:27:27 +0000 (UTC) Received: from mail-pg1-f173.google.com (mail-pg1-f173.google.com [209.85.215.173]) by mx.groups.io with SMTP id smtpd.web10.8325.1761175640038029723 for ; Wed, 22 Oct 2025 16:27:20 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20230601 header.b=E0FZpkse; spf=pass (domain: gmail.com, ip: 209.85.215.173, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f173.google.com with SMTP id 41be03b00d2f7-b67ae7e76abso71501a12.3 for ; Wed, 22 Oct 2025 16:27:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761175639; x=1761780439; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=j0Ef9LyEqdvsrtN5iG8KCnNN2K2eTiET77lXwT7yEhU=; b=E0FZpksenOQbak1XygKj+Z7fATs/U1q2yUO8iyXu2wdZSBwx+FtVikBZpjKM5H62Tg wl0n9panLYWnvKMIzZI01fBD0T8/3qlESfBfJdKBA/ZXmIZGwHWoTqsfu9y6aqSxCrNl DLJou55E7/qwA5OzXCrfulla89to8k3rQLHJK43u7/mticZpWDF0ndUj0ecG0tldLlLg QTRN0fI/h0cVF45GVaUJ+/uzwvZvgu/Adf2mMNLueCdt4Z3UovQk4bCz1i0ffavf+0tv enaDRRixTE5bmOe1fgTAhOpZeDg0w75LkjK4p5CVLbTSxV+wZfsducvqscXU80e5OK5F UWpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761175639; x=1761780439; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=j0Ef9LyEqdvsrtN5iG8KCnNN2K2eTiET77lXwT7yEhU=; b=Z6Ure04D8wpoTe8hD4ueqej+ODXIrJqqTuzbPclL6akU2zkwMQ152Gl0GaIHGeciVn RFGHvsGMc0V3sJMElpLmCbRzemF5ZxYonoVbINuyO0QGRkCwXTo1GHVOScKb7jacVR9A MOSSSTUO5rkzhxyVzQgoYwAJwu6EG/O1p2EViKVhxMEzFiDmPCYSBW3Otl2M502sJO/k /HrcubNRA2Wsl/2Rv+addaDwWCd0T3Hci/TisahGEclmqmDcC7WdoGOuPzLKFTRY3Mtv 7FmyHw262C6VeD3qp10JOUBz+Kg0T8vmjQVzkj4n5Jf2RygjprooDcC8xQbHH9v4ynnu xuvg== X-Gm-Message-State: AOJu0YxN3L6UbJoQW8Ao8i5ZN5WmhpLovTZCzJ5jjyK+g2UbpaSxF7dX cE8T0IFpAwWH3BR6FhMGKJOEZpBl0tb4bFdehKX4UUJeOFbpLVHqZzs1xgLFfw== X-Gm-Gg: ASbGnctHv3fV12ppKNLAoRHYEG5cVHhnffbXuxpxh8cZxfyNrfI/N8ZyNKe+NmLfr0w 6uefqw3uFij0FlSVgEIFARwv2ueB9Wpv0stvaBeJzloe1v+T827LJWbZbJFp4/IeP7Dj2/blkq+ NjEWhDoogGjBmN5a7mMF7CvN8t5sqNb502HBFZZflcDnxu84CpdrUl3G5z5Sdzq2e1oFUqruMNe jbHsQxNedRWUqlicpMWclm1mvxDNPh4VTwOd03NQbNCFceVaRTIuoJoBVrNzMMgjXu+qjyz3Zwe 424B7twiMP7p+O9S1yJNdpADms+VwOL0PdEDrM+1POErgpIhWL1fOQ4/97MWtkVxrBlqrqqkHmc EdqwdfsujMIBrCr6yeKNkYedKTWB8e8UW8UMrgvHvjTWXKYOgNrbdcdgKWZIqWiyAfWGEB9ZBqN V/6fAAk/jQBQrEbA== X-Google-Smtp-Source: AGHT+IEya9K1RzvKspxhlzbdpbTn8STGGIqE9fId+wL/W/kguhDFfoN5KrdK2V09g/d8qBdLT6HBLQ== X-Received: by 2002:a17:903:8c6:b0:28d:18fb:bb93 with SMTP id d9443c01a7336-290c9c8968cmr308770925ad.7.1761175638850; Wed, 22 Oct 2025 16:27:18 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([147.161.216.252]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-33fb01919aasm331129a91.17.2025.10.22.16.27.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Oct 2025 16:27:18 -0700 (PDT) From: Ankur Tyagi To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-python][scarthgap][PATCH v2 4/8] python3-django: patch CVE-2025-48432 Date: Thu, 23 Oct 2025 12:26:27 +1300 Message-ID: <20251022232633.1703690-5-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> References: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 22 Oct 2025 23:27:27 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/120905 Details https://nvd.nist.gov/vuln/detail/CVE-2025-48432 Following patches are needed to avoid cherry-pick conflicts - CVE-2025-48432-1.patch - CVE-2025-48432-2.patch - CVE-2025-48432-4.patch Signed-off-by: Ankur Tyagi --- .../CVE-2025-48432-1.patch | 166 +++++++++++++ .../CVE-2025-48432-2.patch | 225 ++++++++++++++++++ .../CVE-2025-48432-3.patch | 165 +++++++++++++ .../CVE-2025-48432-4.patch | 193 +++++++++++++++ .../CVE-2025-48432-5.patch | 76 ++++++ .../CVE-2025-48432-6.patch | 167 +++++++++++++ .../python/python3-django_4.2.20.bb | 6 + 7 files changed, 998 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-1.patch create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-2.patch create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-3.patch create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-4.patch create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-5.patch create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-6.patch diff --git a/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-1.patch b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-1.patch new file mode 100644 index 0000000000..b7a6379660 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-1.patch @@ -0,0 +1,166 @@ +From be9a242fadb72bbb678095b958605d74543f112c Mon Sep 17 00:00:00 2001 +From: Natalia <124304+nessita@users.noreply.github.com> +Date: Mon, 19 May 2025 22:45:38 -0300 +Subject: [PATCH] [4.2.x] Refs #26688 -- Added tests for `log_response()` + internal helper. + +Backport of 897046815944cc9a2da7ed9e8082f45ffe8110e3 from main. + +CVE: CVE-2025-48432 +Upstream-Status: Backport [https://github.com/django/django/commit/acbe655a0fa1200d2de31c6020f310ba9aa2f636] +(cherry picked from commit acbe655a0fa1200d2de31c6020f310ba9aa2f636) +Signed-off-by: Ankur Tyagi +--- + tests/logging_tests/tests.py | 121 +++++++++++++++++++++++++++++++++++ + 1 file changed, 121 insertions(+) + +diff --git a/tests/logging_tests/tests.py b/tests/logging_tests/tests.py +index c73a3acd6d..2138a7fe50 100644 +--- a/tests/logging_tests/tests.py ++++ b/tests/logging_tests/tests.py +@@ -1,6 +1,7 @@ + import logging + from contextlib import contextmanager + from io import StringIO ++from unittest import TestCase + + from admin_scripts.tests import AdminScriptTestCase + +@@ -9,6 +10,7 @@ from django.core import mail + from django.core.exceptions import DisallowedHost, PermissionDenied, SuspiciousOperation + from django.core.files.temp import NamedTemporaryFile + from django.core.management import color ++from django.http import HttpResponse + from django.http.multipartparser import MultiPartParserError + from django.test import RequestFactory, SimpleTestCase, override_settings + from django.test.utils import LoggingCaptureMixin +@@ -19,6 +21,7 @@ from django.utils.log import ( + RequireDebugFalse, + RequireDebugTrue, + ServerFormatter, ++ log_response, + ) + from django.views.debug import ExceptionReporter + +@@ -646,3 +649,121 @@ class LogFormattersTests(SimpleTestCase): + self.assertRegex( + logger_output.getvalue(), r"^\[[/:,\w\s\d]+\] %s\n" % log_msg + ) ++ ++ ++class LogResponseRealLoggerTests(TestCase): ++ request = RequestFactory().get("/test-path/") ++ ++ def assertResponseLogged(self, logger_cm, msg, levelno, status_code, request): ++ self.assertEqual( ++ records_len := len(logger_cm.records), ++ 1, ++ f"Unexpected number of records for {logger_cm=} in {levelno=} (expected 1, " ++ f"got {records_len}).", ++ ) ++ record = logger_cm.records[0] ++ self.assertEqual(record.getMessage(), msg) ++ self.assertEqual(record.levelno, levelno) ++ self.assertEqual(record.status_code, status_code) ++ self.assertEqual(record.request, request) ++ ++ def test_missing_response_raises_attribute_error(self): ++ with self.assertRaises(AttributeError): ++ log_response("No response provided", response=None, request=self.request) ++ ++ def test_missing_request_logs_with_none(self): ++ response = HttpResponse(status=403) ++ with self.assertLogs("django.request", level="INFO") as cm: ++ log_response(msg := "Missing request", response=response, request=None) ++ self.assertResponseLogged(cm, msg, logging.WARNING, 403, request=None) ++ ++ def test_logs_5xx_as_error(self): ++ response = HttpResponse(status=508) ++ with self.assertLogs("django.request", level="ERROR") as cm: ++ log_response( ++ msg := "Server error occurred", response=response, request=self.request ++ ) ++ self.assertResponseLogged(cm, msg, logging.ERROR, 508, self.request) ++ ++ def test_logs_4xx_as_warning(self): ++ response = HttpResponse(status=418) ++ with self.assertLogs("django.request", level="WARNING") as cm: ++ log_response( ++ msg := "This is a teapot!", response=response, request=self.request ++ ) ++ self.assertResponseLogged(cm, msg, logging.WARNING, 418, self.request) ++ ++ def test_logs_2xx_as_info(self): ++ response = HttpResponse(status=201) ++ with self.assertLogs("django.request", level="INFO") as cm: ++ log_response(msg := "OK response", response=response, request=self.request) ++ self.assertResponseLogged(cm, msg, logging.INFO, 201, self.request) ++ ++ def test_custom_log_level(self): ++ response = HttpResponse(status=403) ++ with self.assertLogs("django.request", level="DEBUG") as cm: ++ log_response( ++ msg := "Debug level log", ++ response=response, ++ request=self.request, ++ level="debug", ++ ) ++ self.assertResponseLogged(cm, msg, logging.DEBUG, 403, self.request) ++ ++ def test_logs_only_once_per_response(self): ++ response = HttpResponse(status=500) ++ with self.assertLogs("django.request", level="ERROR") as cm: ++ log_response("First log", response=response, request=self.request) ++ log_response("Second log", response=response, request=self.request) ++ self.assertResponseLogged(cm, "First log", logging.ERROR, 500, self.request) ++ ++ def test_exc_info_output(self): ++ response = HttpResponse(status=500) ++ try: ++ raise ValueError("Simulated failure") ++ except ValueError as exc: ++ with self.assertLogs("django.request", level="ERROR") as cm: ++ log_response( ++ "With exception", ++ response=response, ++ request=self.request, ++ exception=exc, ++ ) ++ self.assertResponseLogged( ++ cm, "With exception", logging.ERROR, 500, self.request ++ ) ++ self.assertIn("ValueError", "\n".join(cm.output)) # Stack trace included ++ ++ def test_format_args_are_applied(self): ++ response = HttpResponse(status=500) ++ with self.assertLogs("django.request", level="ERROR") as cm: ++ log_response( ++ "Something went wrong: %s (%d)", ++ "DB error", ++ 42, ++ response=response, ++ request=self.request, ++ ) ++ msg = "Something went wrong: DB error (42)" ++ self.assertResponseLogged(cm, msg, logging.ERROR, 500, self.request) ++ ++ def test_logs_with_custom_logger(self): ++ handler = logging.StreamHandler(log_stream := StringIO()) ++ handler.setFormatter(logging.Formatter("%(levelname)s:%(name)s:%(message)s")) ++ ++ custom_logger = logging.getLogger("my.custom.logger") ++ custom_logger.setLevel(logging.DEBUG) ++ custom_logger.addHandler(handler) ++ self.addCleanup(custom_logger.removeHandler, handler) ++ ++ response = HttpResponse(status=404) ++ log_response( ++ msg := "Handled by custom logger", ++ response=response, ++ request=self.request, ++ logger=custom_logger, ++ ) ++ ++ self.assertEqual( ++ f"WARNING:my.custom.logger:{msg}", log_stream.getvalue().strip() ++ ) diff --git a/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-2.patch b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-2.patch new file mode 100644 index 0000000000..853d57c3ed --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-2.patch @@ -0,0 +1,225 @@ +From b0b78910bf659fd33d101d99fee02b19f8dc346c Mon Sep 17 00:00:00 2001 +From: Natalia <124304+nessita@users.noreply.github.com> +Date: Mon, 19 May 2025 22:46:00 -0300 +Subject: [PATCH] [4.2.x] Added helpers in csrf_tests and logging_tests to + assert logs from `log_response()`. + +Backport of ad6f99889838ccc2c30b3c02ed3868c9b565e81b from main. + +CVE: CVE-2025-48432 +Upstream-Status: Backport [https://github.com/django/django/commit/32fd8dec5618bd09eccdeb9dbf512043193d68ef] +(cherry picked from commit 32fd8dec5618bd09eccdeb9dbf512043193d68ef) +Signed-off-by: Ankur Tyagi +--- + tests/csrf_tests/tests.py | 53 ++++++++++++++++++------------------ + tests/logging_tests/tests.py | 42 ++++++++++++++++++++-------- + 2 files changed, 57 insertions(+), 38 deletions(-) + +diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py +index ba8f87d6ac..b8d928151e 100644 +--- a/tests/csrf_tests/tests.py ++++ b/tests/csrf_tests/tests.py +@@ -1,3 +1,4 @@ ++import logging + import re + + from django.conf import settings +@@ -57,6 +58,21 @@ class CsrfFunctionTestMixin: + actual = _unmask_cipher_token(masked_secret) + self.assertEqual(actual, secret) + ++ def assertForbiddenReason( ++ self, response, logger_cm, reason, levelno=logging.WARNING ++ ): ++ self.assertEqual( ++ records_len := len(logger_cm.records), ++ 1, ++ f"Unexpected number of records for {logger_cm=} in {levelno=} (expected 1, " ++ f"got {records_len}).", ++ ) ++ record = logger_cm.records[0] ++ self.assertEqual(record.getMessage(), "Forbidden (%s): " % reason) ++ self.assertEqual(record.levelno, levelno) ++ self.assertEqual(record.status_code, 403) ++ self.assertEqual(response.status_code, 403) ++ + + class CsrfFunctionTests(CsrfFunctionTestMixin, SimpleTestCase): + def test_unmask_cipher_token(self): +@@ -347,8 +363,7 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin): + mw.process_request(req) + with self.assertLogs("django.security.csrf", "WARNING") as cm: + resp = mw.process_view(req, post_form_view, (), {}) +- self.assertEqual(403, resp.status_code) +- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % expected) ++ self.assertForbiddenReason(resp, cm, expected) + + def test_no_csrf_cookie(self): + """ +@@ -373,9 +388,8 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin): + mw.process_request(req) + with self.assertLogs("django.security.csrf", "WARNING") as cm: + resp = mw.process_view(req, post_form_view, (), {}) +- self.assertEqual(403, resp.status_code) + self.assertEqual(resp["Content-Type"], "text/html; charset=utf-8") +- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % expected) ++ self.assertForbiddenReason(resp, cm, expected) + + def test_csrf_cookie_bad_or_missing_token(self): + """ +@@ -480,18 +494,12 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin): + mw = CsrfViewMiddleware(post_form_view) + with self.assertLogs("django.security.csrf", "WARNING") as cm: + resp = mw.process_view(req, post_form_view, (), {}) +- self.assertEqual(403, resp.status_code) +- self.assertEqual( +- cm.records[0].getMessage(), "Forbidden (%s): " % REASON_NO_CSRF_COOKIE +- ) ++ self.assertForbiddenReason(resp, cm, REASON_NO_CSRF_COOKIE) + + req = self._get_request(method="DELETE") + with self.assertLogs("django.security.csrf", "WARNING") as cm: + resp = mw.process_view(req, post_form_view, (), {}) +- self.assertEqual(403, resp.status_code) +- self.assertEqual( +- cm.records[0].getMessage(), "Forbidden (%s): " % REASON_NO_CSRF_COOKIE +- ) ++ self.assertForbiddenReason(resp, cm, REASON_NO_CSRF_COOKIE) + + def test_put_and_delete_allowed(self): + """ +@@ -879,11 +887,7 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin): + mw.process_request(req) + with self.assertLogs("django.security.csrf", "WARNING") as cm: + resp = mw.process_view(req, post_form_view, (), {}) +- self.assertEqual(resp.status_code, 403) +- self.assertEqual( +- cm.records[0].getMessage(), +- "Forbidden (%s): " % REASON_CSRF_TOKEN_MISSING, +- ) ++ self.assertForbiddenReason(resp, cm, REASON_CSRF_TOKEN_MISSING) + + def test_reading_post_data_raises_os_error(self): + """ +@@ -908,9 +912,8 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin): + self.assertIs(mw._origin_verified(req), False) + with self.assertLogs("django.security.csrf", "WARNING") as cm: + response = mw.process_view(req, post_form_view, (), {}) +- self.assertEqual(response.status_code, 403) + msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"] +- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg) ++ self.assertForbiddenReason(response, cm, msg) + + @override_settings(ALLOWED_HOSTS=["www.example.com"]) + def test_bad_origin_null_origin(self): +@@ -923,9 +926,8 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin): + self.assertIs(mw._origin_verified(req), False) + with self.assertLogs("django.security.csrf", "WARNING") as cm: + response = mw.process_view(req, post_form_view, (), {}) +- self.assertEqual(response.status_code, 403) + msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"] +- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg) ++ self.assertForbiddenReason(response, cm, msg) + + @override_settings(ALLOWED_HOSTS=["www.example.com"]) + def test_bad_origin_bad_protocol(self): +@@ -939,9 +941,8 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin): + self.assertIs(mw._origin_verified(req), False) + with self.assertLogs("django.security.csrf", "WARNING") as cm: + response = mw.process_view(req, post_form_view, (), {}) +- self.assertEqual(response.status_code, 403) + msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"] +- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg) ++ self.assertForbiddenReason(response, cm, msg) + + @override_settings( + ALLOWED_HOSTS=["www.example.com"], +@@ -966,9 +967,8 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin): + self.assertIs(mw._origin_verified(req), False) + with self.assertLogs("django.security.csrf", "WARNING") as cm: + response = mw.process_view(req, post_form_view, (), {}) +- self.assertEqual(response.status_code, 403) + msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"] +- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg) ++ self.assertForbiddenReason(response, cm, msg) + self.assertEqual(mw.allowed_origins_exact, {"http://no-match.com"}) + self.assertEqual( + mw.allowed_origin_subdomains, +@@ -992,9 +992,8 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin): + self.assertIs(mw._origin_verified(req), False) + with self.assertLogs("django.security.csrf", "WARNING") as cm: + response = mw.process_view(req, post_form_view, (), {}) +- self.assertEqual(response.status_code, 403) + msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"] +- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg) ++ self.assertForbiddenReason(response, cm, msg) + + @override_settings(ALLOWED_HOSTS=["www.example.com"]) + def test_good_origin_insecure(self): +diff --git a/tests/logging_tests/tests.py b/tests/logging_tests/tests.py +index 2138a7fe50..4ffa49a1b8 100644 +--- a/tests/logging_tests/tests.py ++++ b/tests/logging_tests/tests.py +@@ -94,6 +94,28 @@ class DefaultLoggingTests( + + + class LoggingAssertionMixin: ++ ++ def assertLogRecord( ++ self, ++ logger_cm, ++ level, ++ msg, ++ status_code, ++ exc_class=None, ++ ): ++ self.assertEqual( ++ records_len := len(logger_cm.records), ++ 1, ++ f"Wrong number of calls for {logger_cm=} in {level=} (expected 1, got " ++ f"{records_len}).", ++ ) ++ record = logger_cm.records[0] ++ self.assertEqual(record.getMessage(), msg) ++ self.assertEqual(record.status_code, status_code) ++ if exc_class: ++ self.assertIsNotNone(record.exc_info) ++ self.assertEqual(record.exc_info[0], exc_class) ++ + def assertLogsRequest( + self, url, level, msg, status_code, logger="django.request", exc_class=None + ): +@@ -102,17 +124,7 @@ class LoggingAssertionMixin: + self.client.get(url) + except views.UncaughtException: + pass +- self.assertEqual( +- len(cm.records), +- 1, +- "Wrong number of calls for logger %r in %r level." % (logger, level), +- ) +- record = cm.records[0] +- self.assertEqual(record.getMessage(), msg) +- self.assertEqual(record.status_code, status_code) +- if exc_class: +- self.assertIsNotNone(record.exc_info) +- self.assertEqual(record.exc_info[0], exc_class) ++ self.assertLogRecord(cm, level, msg, status_code, exc_class) + + + @override_settings(DEBUG=True, ROOT_URLCONF="logging_tests.urls") +@@ -135,6 +147,14 @@ class HandlerLoggingTests( + msg="Not Found: /does_not_exist/", + ) + ++ async def test_async_page_not_found_warning(self): ++ logger = "django.request" ++ level = "WARNING" ++ with self.assertLogs(logger, level) as cm: ++ await self.async_client.get("/does_not_exist/") ++ ++ self.assertLogRecord(cm, level, "Not Found: /does_not_exist/", 404) ++ + def test_page_not_found_raised(self): + self.assertLogsRequest( + url="/does_not_exist_raised/", diff --git a/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-3.patch b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-3.patch new file mode 100644 index 0000000000..0517662d50 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-48432-3.patch @@ -0,0 +1,165 @@ +From 4ac54529e08371c3c20511167258ed18e0a3a7d6 Mon Sep 17 00:00:00 2001 +From: Natalia <124304+nessita@users.noreply.github.com> +Date: Tue, 20 May 2025 15:29:52 -0300 +Subject: [PATCH] [4.2.x] Fixed CVE-2025-48432 -- Escaped formatting arguments + in `log_response()`. + +Suitably crafted requests containing a CRLF sequence in the request +path may have allowed log injection, potentially corrupting log files, +obscuring other attacks, misleading log post-processing tools, or +forging log entries. + +To mitigate this, all positional formatting arguments passed to the +logger are now escaped using "unicode_escape" encoding. + +Thanks to Seokchan Yoon (https://ch4n3.kr/) for the report. + +Co-authored-by: Carlton Gibson +Co-authored-by: Jake Howard + +Backport of a07ebec5591e233d8bbb38b7d63f35c5479eef0e from main. + +CVE: CVE-2025-48432 +Upstream-Status: Backport [https://github.com/django/django/commit/ac03c5e7df8680c61cdb0d3bdb8be9095dba841e] +(cherry picked from commit ac03c5e7df8680c61cdb0d3bdb8be9095dba841e) +Signed-off-by: Ankur Tyagi +--- + django/utils/log.py | 7 +++- + tests/logging_tests/tests.py | 79 +++++++++++++++++++++++++++++++++++- + 2 files changed, 84 insertions(+), 2 deletions(-) + +diff --git a/django/utils/log.py b/django/utils/log.py +index fd0cc1bdc1..d7465f73d7 100644 +--- a/django/utils/log.py ++++ b/django/utils/log.py +@@ -238,9 +238,14 @@ def log_response( + else: + level = "info" + ++ escaped_args = tuple( ++ a.encode("unicode_escape").decode("ascii") if isinstance(a, str) else a ++ for a in args ++ ) ++ + getattr(logger, level)( + message, +- *args, ++ *escaped_args, + extra={ + "status_code": response.status_code, + "request": request, +diff --git a/tests/logging_tests/tests.py b/tests/logging_tests/tests.py +index 4ffa49a1b8..cda0a62f2c 100644 +--- a/tests/logging_tests/tests.py ++++ b/tests/logging_tests/tests.py +@@ -94,7 +94,6 @@ class DefaultLoggingTests( + + + class LoggingAssertionMixin: +- + def assertLogRecord( + self, + logger_cm, +@@ -147,6 +146,14 @@ class HandlerLoggingTests( + msg="Not Found: /does_not_exist/", + ) + ++ def test_control_chars_escaped(self): ++ self.assertLogsRequest( ++ url="/%1B[1;31mNOW IN RED!!!1B[0m/", ++ level="WARNING", ++ status_code=404, ++ msg=r"Not Found: /\x1b[1;31mNOW IN RED!!!1B[0m/", ++ ) ++ + async def test_async_page_not_found_warning(self): + logger = "django.request" + level = "WARNING" +@@ -155,6 +162,16 @@ class HandlerLoggingTests( + + self.assertLogRecord(cm, level, "Not Found: /does_not_exist/", 404) + ++ async def test_async_control_chars_escaped(self): ++ logger = "django.request" ++ level = "WARNING" ++ with self.assertLogs(logger, level) as cm: ++ await self.async_client.get(r"/%1B[1;31mNOW IN RED!!!1B[0m/") ++ ++ self.assertLogRecord( ++ cm, level, r"Not Found: /\x1b[1;31mNOW IN RED!!!1B[0m/", 404 ++ ) ++ + def test_page_not_found_raised(self): + self.assertLogsRequest( + url="/does_not_exist_raised/", +@@ -686,6 +703,7 @@ class LogResponseRealLoggerTests(TestCase): + self.assertEqual(record.levelno, levelno) + self.assertEqual(record.status_code, status_code) + self.assertEqual(record.request, request) ++ return record + + def test_missing_response_raises_attribute_error(self): + with self.assertRaises(AttributeError): +@@ -787,3 +805,62 @@ class LogResponseRealLoggerTests(TestCase): + self.assertEqual( + f"WARNING:my.custom.logger:{msg}", log_stream.getvalue().strip() + ) ++ ++ def test_unicode_escape_escaping(self): ++ test_cases = [ ++ # Control characters. ++ ("line\nbreak", "line\\nbreak"), ++ ("carriage\rreturn", "carriage\\rreturn"), ++ ("tab\tseparated", "tab\\tseparated"), ++ ("formfeed\f", "formfeed\\x0c"), ++ ("bell\a", "bell\\x07"), ++ ("multi\nline\ntext", "multi\\nline\\ntext"), ++ # Slashes. ++ ("slash\\test", "slash\\\\test"), ++ ("back\\slash", "back\\\\slash"), ++ # Quotes. ++ ('quote"test"', 'quote"test"'), ++ ("quote'test'", "quote'test'"), ++ # Accented, composed characters, emojis and symbols. ++ ("café", "caf\\xe9"), ++ ("e\u0301", "e\\u0301"), # e + combining acute ++ ("smile From patchwork Wed Oct 22 23:26:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 72868 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 890B0CCD1AB for ; Wed, 22 Oct 2025 23:27:27 +0000 (UTC) Received: from mail-pg1-f174.google.com (mail-pg1-f174.google.com [209.85.215.174]) by mx.groups.io with SMTP id smtpd.web10.8326.1761175641912408270 for ; Wed, 22 Oct 2025 16:27:21 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20230601 header.b=Iq9K5OGC; spf=pass (domain: gmail.com, ip: 209.85.215.174, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f174.google.com with SMTP id 41be03b00d2f7-b67684e2904so89480a12.2 for ; Wed, 22 Oct 2025 16:27:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761175641; x=1761780441; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=h8H0hptqct0wZayQZNSWDST1n6Tgg1mMVL78YDJKVTg=; b=Iq9K5OGCqlWIqvi/WBrT0EzfIX/aijxyz7+fc09ZqxLmTL5BHSTX6eimAHilbwccDE GRrQvHWVZgDanrRc/Kcrqx08MDPnkgjoPrQoU8iiqS3Ueh/kvECSob91ja8GWhDT9FWu FGkACxSlduhSkUKjoZ3jTK+B0D+XnCfj1NCnV+4dRFCRB1/+KOrS0mxYYYpgkRSeVQ3b R+mJyVEsbPaVksP11Y5sJJLeiJAVjDuO6GTA0Zt9eA/AbPEiEFrMbdvx+P9kDo7dDNOV BVytetGShOw8CvnawWt7xf/vcnoH/Ag89vqnwgdFrj1Uerp1JSINDW2A6WzoartECdWu EDrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761175641; x=1761780441; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=h8H0hptqct0wZayQZNSWDST1n6Tgg1mMVL78YDJKVTg=; b=VwnuvQdYVkfIi8VFESSdbMahLTyBCzq6pzlUm3cXZwaLUxwp9rhpkfVHcQQnV56Bv1 4xO40ZddejgH4lgze6MWVIIwIZyZi6dsOhpHBLtkdkNj0GANRiO95MZGk1HnY1yvA9xn DvNxonbUqxBK6LOP4Sd4E2/9GCnxr3x9J8+fxFNPUgqpMsIQbQTcd1a6Yjhl46XwZe+K 8Sw+srC2Hexu0MzfDwrEt6k8vWHcNXCpGZFJfUk6LH1eIz5SmPWq+RqTb/hga7fQQxYb CzDmHuXHDSAXpKhn3ifsTNdZF13HQMGg+3izjemuY9ekXqRAtGVTA7+n9yFgbIWXOaLa tgLw== X-Gm-Message-State: AOJu0YySJjHIvfJKECXWNHHXzXI1CnQGmxXNrqx8wofiJQXB/RVvj9Va cbhI+Q6LBRKR8G4Av4B6LX+WAIR6VIBnU2SyLP1t6KTlfPVnGa+ADzdJTPmhLg== X-Gm-Gg: ASbGnctPvC9Q6uQNIHniaOqdTd8ZuBnsCRPJPzDjcXPRCJw3vNky58XFs1IlUbM50uE 51ToqAtz7FGQXDsjYhjgGcy6POq4n0tIh5Y9IjJA6caQVpakGoSuMl7/bVWc28sdAGoSlbSvGcf SXISvWEAYIwtDSTLlWXsqkxjhJWKFPyJz7cGJqaxaBpowlLOL5qAJfqxPoTHzmYNN4+ZnZw0kG/ o7M+miN/dIyzcpE5rB4/Hr8fQW/w2XpjTe8XlPAbpGXTQxNJByODgIwjT1FdlVPTLk5Itl5Hasf Lig6SeMfEfbC9EoyfUEE+qFSyvlF7ybVDHL+1gEb/dlKG1pQ4DXK7zkLwl/XsSQZUkBJBSv/RNT N+52eUsuAK0j+XdjXNjgb5cwHYjOCY6rXkTCRTz56h5memTy4fTJOAPxib/3O5KCavSLX/G2rfH r+uV6B1+ARTS7p+ADJ6Aqg//Bm X-Google-Smtp-Source: AGHT+IFODNBydVrgYsHLJLBH2xnD34bhREwo59kcZGU0MTAVrc5+DpAft7B4JQ75DKBvtKPV/2RSeg== X-Received: by 2002:a17:902:cf0a:b0:291:2b6f:cf64 with SMTP id d9443c01a7336-2912b6fd015mr250031965ad.55.1761175641004; Wed, 22 Oct 2025 16:27:21 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([147.161.216.252]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-33fb01919aasm331129a91.17.2025.10.22.16.27.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Oct 2025 16:27:20 -0700 (PDT) From: Ankur Tyagi To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-python][scarthgap][PATCH v2 5/8] python3-django: patch CVE-2025-57833 Date: Thu, 23 Oct 2025 12:26:28 +1300 Message-ID: <20251022232633.1703690-6-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> References: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 22 Oct 2025 23:27:27 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/120906 Details https://nvd.nist.gov/vuln/detail/CVE-2025-57833 Signed-off-by: Ankur Tyagi --- .../CVE-2025-57833.patch | 83 +++++++++++++++++++ .../python/python3-django_4.2.20.bb | 1 + 2 files changed, 84 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-57833.patch diff --git a/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-57833.patch b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-57833.patch new file mode 100644 index 0000000000..d04589a149 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-57833.patch @@ -0,0 +1,83 @@ +From 5826d1b59363e0208ebbd4a59d3b3ef39cfe14d5 Mon Sep 17 00:00:00 2001 +From: Jake Howard +Date: Wed, 13 Aug 2025 14:13:42 +0200 +Subject: [PATCH] [4.2.x] Fixed CVE-2025-57833 -- Protected FilteredRelation + against SQL injection in column aliases. + +Thanks Eyal Gabay (EyalSec) for the report. + +Backport of 51711717098d3f469f795dfa6bc3758b24f69ef7 from main. +CVE: CVE-2025-57833 +Upstream-Status: Backport [https://github.com/django/django/commit/31334e6965ad136a5e369993b01721499c5d1a92] +(cherry picked from commit 31334e6965ad136a5e369993b01721499c5d1a92) +Signed-off-by: Ankur Tyagi +--- + django/db/models/sql/query.py | 1 + + tests/annotations/tests.py | 24 ++++++++++++++++++++++++ + 2 files changed, 25 insertions(+) + +diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py +index e68fd9efb7..5a1b68507b 100644 +--- a/django/db/models/sql/query.py ++++ b/django/db/models/sql/query.py +@@ -1620,6 +1620,7 @@ class Query(BaseExpression): + return target_clause + + def add_filtered_relation(self, filtered_relation, alias): ++ self.check_alias(alias) + filtered_relation.alias = alias + lookups = dict(get_children_from_q(filtered_relation.condition)) + relation_lookup_parts, relation_field_parts, _ = self.solve_lookup_type( +diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py +index e0cdbf1e0b..a8474abc77 100644 +--- a/tests/annotations/tests.py ++++ b/tests/annotations/tests.py +@@ -12,6 +12,7 @@ from django.db.models import ( + Exists, + ExpressionWrapper, + F, ++ FilteredRelation, + FloatField, + Func, + IntegerField, +@@ -1121,6 +1122,15 @@ class NonAggregateAnnotationTestCase(TestCase): + with self.assertRaisesMessage(ValueError, msg): + Book.objects.annotate(**{crafted_alias: Value(1)}) + ++ def test_alias_filtered_relation_sql_injection(self): ++ crafted_alias = """injected_name" from "annotations_book"; --""" ++ msg = ( ++ "Column aliases cannot contain whitespace characters, quotation marks, " ++ "semicolons, or SQL comments." ++ ) ++ with self.assertRaisesMessage(ValueError, msg): ++ Book.objects.annotate(**{crafted_alias: FilteredRelation("author")}) ++ + def test_alias_forbidden_chars(self): + tests = [ + 'al"ias', +@@ -1146,6 +1156,11 @@ class NonAggregateAnnotationTestCase(TestCase): + with self.assertRaisesMessage(ValueError, msg): + Book.objects.annotate(**{crafted_alias: Value(1)}) + ++ with self.assertRaisesMessage(ValueError, msg): ++ Book.objects.annotate( ++ **{crafted_alias: FilteredRelation("authors")} ++ ) ++ + + class AliasTests(TestCase): + @classmethod +@@ -1418,3 +1433,12 @@ class AliasTests(TestCase): + ) + with self.assertRaisesMessage(ValueError, msg): + Book.objects.alias(**{crafted_alias: Value(1)}) ++ ++ def test_alias_filtered_relation_sql_injection(self): ++ crafted_alias = """injected_name" from "annotations_book"; --""" ++ msg = ( ++ "Column aliases cannot contain whitespace characters, quotation marks, " ++ "semicolons, or SQL comments." ++ ) ++ with self.assertRaisesMessage(ValueError, msg): ++ Book.objects.alias(**{crafted_alias: FilteredRelation("authors")}) 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 ae99758543..caebfe0e46 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 @@ -10,6 +10,7 @@ SRC_URI += " \ file://CVE-2025-48432-4.patch \ file://CVE-2025-48432-5.patch \ file://CVE-2025-48432-6.patch \ + file://CVE-2025-57833.patch \ " SRC_URI[sha256sum] = "92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789" From patchwork Wed Oct 22 23:26:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 72871 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94445CCD1BF for ; Wed, 22 Oct 2025 23:27:27 +0000 (UTC) Received: from mail-pf1-f178.google.com (mail-pf1-f178.google.com [209.85.210.178]) by mx.groups.io with SMTP id smtpd.web10.8327.1761175644284793830 for ; Wed, 22 Oct 2025 16:27:24 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20230601 header.b=C8+hyKBh; spf=pass (domain: gmail.com, ip: 209.85.210.178, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pf1-f178.google.com with SMTP id d2e1a72fcca58-78af3fe5b17so135458b3a.2 for ; Wed, 22 Oct 2025 16:27:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761175643; x=1761780443; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QvLLiM3ZbMLZLyiZkK9eXTKfGGJTzfqR7w4KCAG0xUg=; b=C8+hyKBh/TepZEdCP4ULgFFl6JXj7IVFtOCu7sND2hDcdWE+U8PmBlLlaRcSxjr/NE xPOh4PVKVV6zq7E4/tl+1L94TN4M2xkuCP0BK0tjfHLSE6o0QXJI/JMcC0z5hMNsSVyJ KGMNWOZnKE7R6lbWCIYIU8SL8McLMOQD3THaS4zSexS6LbkAW5WUJkB8IDNnRbHL2fTG E1QfSaY7UE4iZz5g7f4JBrNaldYUfZ1MgYfN0Qg0oDEbixdW/TmAgrAZrVJPZO0GED1W Ve6SlH7GOrSvdoy+rjcxutOonaBEeDtjK3eTqmUqGkx/16rpAeUI2sbkcAYRuCgbgmVe 5vQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761175643; x=1761780443; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QvLLiM3ZbMLZLyiZkK9eXTKfGGJTzfqR7w4KCAG0xUg=; b=vXbfLrqTbcmlB4eg4POT2XtQYq7L+//MOa9ZGVpsTOLlZPMAmWtRgkL4/wKLhzZMte uXll8YrN+E04F2TT6pLdMGYdrTlitzjuaL60J8nqIzXXMf5KvOcY7Q4hfCs42+Q/A6Xa orYPJ4khzfvglYD2NToypLApNnr717478EKD8jWrQrkx81tPeNHkYy2kGTfOTuyLK7ku 2TBPo3tMBcHUxYedMbzs3opQLmFtKQTnM5ljZ/LGBuZDDpuRZ2Oz2OTrUE9iF7DdZZ8w ircELAoz+kbgpgpvq0+VMMQyspzyOEYdSl+/lrCeWdNZkbr2nFkaDSLMa+pNw/bM/tgD P6eA== X-Gm-Message-State: AOJu0Yxb4i1hQkKKOLQYF37qZ9Jt5cx/BqH7jnoGQ+H9BMgPvDvuNhWB iSWcZldztnz5hex52dZi4fXzfLx6AnNmeJ9th/IBe0oEe5Z4qYjXSnbO/IZVOA== X-Gm-Gg: ASbGncvJndRRfyCpjepVDv4mW54ztrX/8W7ltak25QxnCREaRcIYkVtZejO727hh9ex 6eNVNm9pcHXr/hnpVTzPp6jQhZ7SLHCU/tYKewPbs0cZFriNOZXXW/YeSH/ffsFIeYWaaAXKAJl 4d8zQG0qU15FUj38yBwfzQbuqkPYiVOg7b4dCLY49uPmqpYh4kDtNV8uvQSsvUcaLKnXVZPxh4e LHufKPEJBTrxAgS0Hv+MCs0WFhPQgpHJYbMcJGRiieWp+EHRtxDCe1Nklbk/iPDRFK9eiakzEbm 0pGQabD+Awss7MI+vs6LhUKMUur9tgf06kHMqvglZNDw5WavVUl3JeLZNPIiDY2mjiiVXIk2JQR ohb2GGSBUPcJiSqx3KhS80aaym4DeICMlzqEjlLIf5j9E6Yr4eAk9AF5ybng1GL2t/KJTz0FpMg nX73cNzBVvWW3WstA09Jkdp9vc X-Google-Smtp-Source: AGHT+IF/3iknX40fBhEqMnBw6T/TcGB8HAxJ1vOCOP0esyTkaV0x80Y//p7RyNgq83KNNf/1aLzNpQ== X-Received: by 2002:a05:6a21:6daa:b0:306:2a14:d0d4 with SMTP id adf61e73a8af0-334a8625728mr28568478637.43.1761175643339; Wed, 22 Oct 2025 16:27:23 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([147.161.216.252]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-33fb01919aasm331129a91.17.2025.10.22.16.27.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Oct 2025 16:27:22 -0700 (PDT) From: Ankur Tyagi To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-python][scarthgap][PATCH v2 6/8] python3-django: patch CVE-2025-59681 Date: Thu, 23 Oct 2025 12:26:29 +1300 Message-ID: <20251022232633.1703690-7-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> References: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 22 Oct 2025 23:27:27 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/120907 Details https://nvd.nist.gov/vuln/detail/CVE-2025-59681 Signed-off-by: Ankur Tyagi --- .../CVE-2025-59681.patch | 174 ++++++++++++++++++ .../python/python3-django_4.2.20.bb | 1 + 2 files changed, 175 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-59681.patch diff --git a/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-59681.patch b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-59681.patch new file mode 100644 index 0000000000..681638ac4f --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-59681.patch @@ -0,0 +1,174 @@ +From af61d1752df85a1ba1c320282128f2fccdad0107 Mon Sep 17 00:00:00 2001 +From: Mariusz Felisiak +Date: Wed, 10 Sep 2025 09:53:52 +0200 +Subject: [PATCH] [4.2.x] Fixed CVE-2025-59681 -- Protected + QuerySet.annotate(), alias(), aggregate(), and extra() against SQL injection + in column aliases on MySQL/MariaDB. + +Thanks sw0rd1ight for the report. + +Follow up to 93cae5cb2f9a4ef1514cf1a41f714fef08005200. + +Backport of 41b43c74bda19753c757036673ea9db74acf494a from main. + +CVE: CVE-2025-59681 +Upstream-Status: Backport [https://github.com/django/django/commit/38d9ef8c7b5cb6ef51b933e51a20e0e0063f33d5] +(cherry picked from commit 38d9ef8c7b5cb6ef51b933e51a20e0e0063f33d5) +Signed-off-by: Ankur Tyagi +--- + django/db/models/sql/query.py | 8 ++++---- + tests/aggregation/tests.py | 4 ++-- + tests/annotations/tests.py | 23 ++++++++++++----------- + tests/expressions/test_queryset_values.py | 8 ++++---- + tests/queries/tests.py | 4 ++-- + 5 files changed, 24 insertions(+), 23 deletions(-) + +diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py +index 5a1b68507b..3b8071eab4 100644 +--- a/django/db/models/sql/query.py ++++ b/django/db/models/sql/query.py +@@ -46,9 +46,9 @@ from django.utils.tree import Node + + __all__ = ["Query", "RawQuery"] + +-# Quotation marks ('"`[]), whitespace characters, semicolons, or inline ++# Quotation marks ('"`[]), whitespace characters, semicolons, hashes, or inline + # SQL comments are forbidden in column aliases. +-FORBIDDEN_ALIAS_PATTERN = _lazy_re_compile(r"['`\"\]\[;\s]|--|/\*|\*/") ++FORBIDDEN_ALIAS_PATTERN = _lazy_re_compile(r"['`\"\]\[;\s]|#|--|/\*|\*/") + + # Inspired from + # https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS +@@ -1123,8 +1123,8 @@ class Query(BaseExpression): + def check_alias(self, alias): + if FORBIDDEN_ALIAS_PATTERN.search(alias): + raise ValueError( +- "Column aliases cannot contain whitespace characters, quotation marks, " +- "semicolons, or SQL comments." ++ "Column aliases cannot contain whitespace characters, hashes, " ++ "quotation marks, semicolons, or SQL comments." + ) + + def add_annotation(self, annotation, alias, select=True): +diff --git a/tests/aggregation/tests.py b/tests/aggregation/tests.py +index 48266d9774..277c0507f7 100644 +--- a/tests/aggregation/tests.py ++++ b/tests/aggregation/tests.py +@@ -2090,8 +2090,8 @@ class AggregateTestCase(TestCase): + def test_alias_sql_injection(self): + crafted_alias = """injected_name" from "aggregation_author"; --""" + msg = ( +- "Column aliases cannot contain whitespace characters, quotation marks, " +- "semicolons, or SQL comments." ++ "Column aliases cannot contain whitespace characters, hashes, quotation " ++ "marks, semicolons, or SQL comments." + ) + with self.assertRaisesMessage(ValueError, msg): + Author.objects.aggregate(**{crafted_alias: Avg("age")}) +diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py +index a8474abc77..4879f19a78 100644 +--- a/tests/annotations/tests.py ++++ b/tests/annotations/tests.py +@@ -1116,8 +1116,8 @@ class NonAggregateAnnotationTestCase(TestCase): + def test_alias_sql_injection(self): + crafted_alias = """injected_name" from "annotations_book"; --""" + msg = ( +- "Column aliases cannot contain whitespace characters, quotation marks, " +- "semicolons, or SQL comments." ++ "Column aliases cannot contain whitespace characters, hashes, quotation " ++ "marks, semicolons, or SQL comments." + ) + with self.assertRaisesMessage(ValueError, msg): + Book.objects.annotate(**{crafted_alias: Value(1)}) +@@ -1125,8 +1125,8 @@ class NonAggregateAnnotationTestCase(TestCase): + def test_alias_filtered_relation_sql_injection(self): + crafted_alias = """injected_name" from "annotations_book"; --""" + msg = ( +- "Column aliases cannot contain whitespace characters, quotation marks, " +- "semicolons, or SQL comments." ++ "Column aliases cannot contain whitespace characters, hashes, quotation " ++ "marks, semicolons, or SQL comments." + ) + with self.assertRaisesMessage(ValueError, msg): + Book.objects.annotate(**{crafted_alias: FilteredRelation("author")}) +@@ -1143,13 +1143,14 @@ class NonAggregateAnnotationTestCase(TestCase): + "ali/*as", + "alias*/", + "alias;", +- # [] are used by MSSQL. ++ # [] and # are used by MSSQL. + "alias[", + "alias]", ++ "ali#as", + ] + msg = ( +- "Column aliases cannot contain whitespace characters, quotation marks, " +- "semicolons, or SQL comments." ++ "Column aliases cannot contain whitespace characters, hashes, quotation " ++ "marks, semicolons, or SQL comments." + ) + for crafted_alias in tests: + with self.subTest(crafted_alias): +@@ -1428,8 +1429,8 @@ class AliasTests(TestCase): + def test_alias_sql_injection(self): + crafted_alias = """injected_name" from "annotations_book"; --""" + msg = ( +- "Column aliases cannot contain whitespace characters, quotation marks, " +- "semicolons, or SQL comments." ++ "Column aliases cannot contain whitespace characters, hashes, quotation " ++ "marks, semicolons, or SQL comments." + ) + with self.assertRaisesMessage(ValueError, msg): + Book.objects.alias(**{crafted_alias: Value(1)}) +@@ -1437,8 +1438,8 @@ class AliasTests(TestCase): + def test_alias_filtered_relation_sql_injection(self): + crafted_alias = """injected_name" from "annotations_book"; --""" + msg = ( +- "Column aliases cannot contain whitespace characters, quotation marks, " +- "semicolons, or SQL comments." ++ "Column aliases cannot contain whitespace characters, hashes, quotation " ++ "marks, semicolons, or SQL comments." + ) + with self.assertRaisesMessage(ValueError, msg): + Book.objects.alias(**{crafted_alias: FilteredRelation("authors")}) +diff --git a/tests/expressions/test_queryset_values.py b/tests/expressions/test_queryset_values.py +index 47bd1358de..080ee06183 100644 +--- a/tests/expressions/test_queryset_values.py ++++ b/tests/expressions/test_queryset_values.py +@@ -37,8 +37,8 @@ class ValuesExpressionsTests(TestCase): + def test_values_expression_alias_sql_injection(self): + crafted_alias = """injected_name" from "expressions_company"; --""" + msg = ( +- "Column aliases cannot contain whitespace characters, quotation marks, " +- "semicolons, or SQL comments." ++ "Column aliases cannot contain whitespace characters, hashes, quotation " ++ "marks, semicolons, or SQL comments." + ) + with self.assertRaisesMessage(ValueError, msg): + Company.objects.values(**{crafted_alias: F("ceo__salary")}) +@@ -47,8 +47,8 @@ class ValuesExpressionsTests(TestCase): + def test_values_expression_alias_sql_injection_json_field(self): + crafted_alias = """injected_name" from "expressions_company"; --""" + msg = ( +- "Column aliases cannot contain whitespace characters, quotation marks, " +- "semicolons, or SQL comments." ++ "Column aliases cannot contain whitespace characters, hashes, quotation " ++ "marks, semicolons, or SQL comments." + ) + with self.assertRaisesMessage(ValueError, msg): + JSONFieldModel.objects.values(f"data__{crafted_alias}") +diff --git a/tests/queries/tests.py b/tests/queries/tests.py +index a6a2b252eb..b8488fef75 100644 +--- a/tests/queries/tests.py ++++ b/tests/queries/tests.py +@@ -1943,8 +1943,8 @@ class Queries5Tests(TestCase): + def test_extra_select_alias_sql_injection(self): + crafted_alias = """injected_name" from "queries_note"; --""" + msg = ( +- "Column aliases cannot contain whitespace characters, quotation marks, " +- "semicolons, or SQL comments." ++ "Column aliases cannot contain whitespace characters, hashes, quotation " ++ "marks, semicolons, or SQL comments." + ) + with self.assertRaisesMessage(ValueError, msg): + Note.objects.extra(select={crafted_alias: "1"}) 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 caebfe0e46..443b4dbbfc 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 @@ -11,6 +11,7 @@ SRC_URI += " \ file://CVE-2025-48432-5.patch \ file://CVE-2025-48432-6.patch \ file://CVE-2025-57833.patch \ + file://CVE-2025-59681.patch \ " SRC_URI[sha256sum] = "92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789" From patchwork Wed Oct 22 23:26:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 72869 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9CFC8CCF9E4 for ; Wed, 22 Oct 2025 23:27:27 +0000 (UTC) Received: from mail-pj1-f54.google.com (mail-pj1-f54.google.com [209.85.216.54]) by mx.groups.io with SMTP id smtpd.web11.8329.1761175646287303413 for ; Wed, 22 Oct 2025 16:27:26 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20230601 header.b=HOnMXIz2; spf=pass (domain: gmail.com, ip: 209.85.216.54, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj1-f54.google.com with SMTP id 98e67ed59e1d1-339d53f4960so208567a91.3 for ; Wed, 22 Oct 2025 16:27:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761175645; x=1761780445; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5+F0TJGPYV4zpXwU3bfCeAqJ9AtMqfu9WqyZC/oWZOE=; b=HOnMXIz21zgJ+HpGtbtez+Az9fyPfTyrWd3lYzCS+gVFV8V/Jo7Bq9reG78zgWT9d5 OW+dPsUwGdVR1r+OlEr2IHkP8Bi8aIgXI3HlnmnacnbT2azwm+VbhziZkZzhjPSeVplP Q9GGjq9K/oXchtUdcv1bW8NL5OC8Miio9pQkxOjaXTUG26orF8F5RIWR2hnUkWHrmPzB l8+lYt0vZGt/MjC2BfqqXxKN/HcAlVnm9uVZhHtTa+/wJMYUhwDuyhEb9c6PVh6DuzOt UdTza/gyRC2CYoQLhy1H+XAKERsOHjMp7SvPD9EcTmHufmL8IshOEH0dMMatuxrWXxid AoLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761175645; x=1761780445; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5+F0TJGPYV4zpXwU3bfCeAqJ9AtMqfu9WqyZC/oWZOE=; b=UXTrdgJFjlCkDExlonLchg2vS2YgUmcOaX1kCUp20LxieBA1Z0dSXluelufOMe7udE eGMqifZucJ/ppM8hB/ZpwDm9anEoxF1JzDW/Y8KK/KrSF+GwnuokCHkhWGpRhkF3HCQd tVrIdgXAKjoyBeRZcyAqvTiIN0WW+W6ky9HbAHUzveU7LV4n2PyEX93gwcSwXob8ljyR +UNIGKcnQkb2XZcgRKqkusNIO+7My0GvXb7uuxw2CGe+QPQ+vxGcFZqzH51Y13z9FR2R 1m3Fn7hC2mPkLNxVbAPaadzGZ8Hc+dfdCtCYlwVflRR53Rlj5XS3Wkq9b9XDHnslhNGp LdYw== X-Gm-Message-State: AOJu0YxyeOU1adBCdNs//vko2VuAgQyPeXxoBsl9B7O9AVn8af9kVVTX ZJOAGBTHotJ9ivk0eJF2pOEi0jCkVpi6zq6Aj22emVA2yWL6cgixBbebKOipUA== X-Gm-Gg: ASbGncteVftMsW/lcGRx34K6qD3dzRaWrpBNcqPB4/ua2Mxl0bLRRZvlwAD6t2yJ/Hy PCLlX5EKx5L/w8ak0sjXMZ99kZMR7AhWSz9XUgAleVNQRtLXwBfIRAG81NE2Z7b/IM5pEsIRqhI NW2w8nh3KGv+33M8WapLBWdu5u0KpTwwtcCw9reaOBqYzn2BHVxFV/+cFNbRwFcvGS3rCrVZlOV E3RvMX0Vs1it55Ga5DzvaT6NjJgRYCYjFABv/4LgtbB15r9WRtFZNrW1mn9b0jR6ghIFiMZgOgR pfe6GkGUX0UGAOZNsKgDKtNdyWseEItCDK9LxRzAtxJhTigDaEuTnk9izOWpzYLAsa23JMQFY0D nTTBFHvSr+1DCt1h8lLDZ0h8lMQA3FJorWIdAgvi6srxKM493XddvsXJK1Nyd8KdtztNnsEZcSG mRGHua30CJzLGdLb+Kq/B5PiI8 X-Google-Smtp-Source: AGHT+IHj5/+to5JgA0dZRybJ8aPc0ShEQydvfwZUjbJxs3be2YdFd8vl2HBN0O9n5evC9a1aJC6PJQ== X-Received: by 2002:a17:90b:3d8a:b0:330:6f16:c4e0 with SMTP id 98e67ed59e1d1-33bcf87f43dmr33021156a91.12.1761175645485; Wed, 22 Oct 2025 16:27:25 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([147.161.216.252]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-33fb01919aasm331129a91.17.2025.10.22.16.27.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Oct 2025 16:27:25 -0700 (PDT) From: Ankur Tyagi To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-python][scarthgap][PATCH v2 7/8] python3-django: patch CVE-2025-59682 Date: Thu, 23 Oct 2025 12:26:30 +1300 Message-ID: <20251022232633.1703690-8-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> References: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 22 Oct 2025 23:27:27 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/120908 Details https://nvd.nist.gov/vuln/detail/CVE-2025-59682 Signed-off-by: Ankur Tyagi --- .../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/9504bbaa392c9fe37eee9291f5b4c29eb6037619] +(cherry picked from commit 9504bbaa392c9fe37eee9291f5b4c29eb6037619) +Signed-off-by: Ankur Tyagi +--- + 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" From patchwork Wed Oct 22 23:26:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 72872 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 97CC7CCD1BE for ; Wed, 22 Oct 2025 23:27:37 +0000 (UTC) Received: from mail-pg1-f181.google.com (mail-pg1-f181.google.com [209.85.215.181]) by mx.groups.io with SMTP id smtpd.web10.8329.1761175648384396785 for ; Wed, 22 Oct 2025 16:27:28 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20230601 header.b=c2cyEYZO; spf=pass (domain: gmail.com, ip: 209.85.215.181, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pg1-f181.google.com with SMTP id 41be03b00d2f7-b6cf07258e8so84993a12.1 for ; Wed, 22 Oct 2025 16:27:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761175647; x=1761780447; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=e7nR8i4MvkzGLG77qjep7fYozZhlMHyCSJzu+IsiXnM=; b=c2cyEYZOJrxg11X9J1P4rQjBleycMFI1e/+Jf2f0VNRAZCyLhwld/zHWPaB9VJWgru 9QL1MP2VQ/iWn4PDGrFIILsCnfUVpk47843n9sj1kEXIVHYDj0Ivh3VyjUcnOqRJo+qd cBSmguk9cVe3ezOE8eeNxGbe6otCl1d7kcgOzPE9Ep7L2nH3wxD7j5t0qvAW/zshykxt 5eTfXVYR+UHuUJNZtmiRWeYkVDqmrkdBehTu64G5hNSQm/6iZG8GP/kOJTJy+czwa96P qg2Wf4lyPxKkdQTyyLklvzRxoXCdq68mWjtl7GJIhiNQuNikzczuLrFFeOpbrc04phx/ zFiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761175647; x=1761780447; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=e7nR8i4MvkzGLG77qjep7fYozZhlMHyCSJzu+IsiXnM=; b=XlfxCSOnPtqMSvMWNIzZFgAUme2BeQVAYtSjb03nqU37MqGEz6ViIXuZO9ouQmclWh E12LiFUOwAEFN9Jt89OXvuaRfG7p471He86QTW47HCxef9pn4nuQHuBR9BPixc9rLGOR LhwsfXVkqFuX40CSrYTtZr+zCE/Y65nRX/PkBbskTa8igvEgnyM6rQ+8qUTAI3vnNFZ1 10I9c1dgAQ6aVq765b95rCifQJkFhvUbN+oW4dZMNASCX/gHRbyY0B+pszrGmTVqxV5H T98iK/2V4wFxgieCZBzbrXR5oShY0dePghyNY5KdhY+3ux6Py6hVFzU/ko5qNxFLTYu2 BIzg== X-Gm-Message-State: AOJu0YzxsGfGKDAiRlhrv0vxNLoqJbgu1Wd7N0+gzklzwyq9ZAnmswW3 K8m9jFQ93dqBjIRns+WfRn0VX0ahoJ6WtUHcB/ob5ZxHN//RD2yhb+6NJrvRAQ== X-Gm-Gg: ASbGncsw97OCHl+RIw06JUZr1V63Lhrrk/UD63eGp2FpxryUrvhDJmICtYd2bYXkp17 011ClgXsVKFgH5zhtmWk8bJ7uYWTkQl+d7pDtqQX6KFFXPBgRzJRlTPY2V/ox7/O/YLqfAdSF0I AvHgB4qWGfnvq0kGIfbJHtcFu1gq/E4jg3gS+jzk8ggj9RLskLwsqNBi6WaVq+j2oRk4n8wZipX Dx0jZRN9SP0b2EM0Xp43gsAybsLWB89d/JVudghcsjTHw16VUsnz8X58ypcsUfDPMPkCvxPSrMN p4g91i6n9HUtQqLZxBEr3+Fm1kXMt7YyVaxMPMnX/M5ocEISvXHUtQ1QNIkvbC6uPP9S2UjARWR zl1QymF84pLCuV3QbA45KzuXBj4u+jClKTXN/qU8wcJU4n05F5inhqoyTsBoWBgQ5gj+/FZ62jG /IYkIM4SMuKak3Fw== X-Google-Smtp-Source: AGHT+IELeYPB+Dv7GhLDP5V4RdVQhxwrJZQGtd6U274J3Z1yzrqJEthF7lFmOzBYaZSyO6UGPQEgUg== X-Received: by 2002:a17:902:f64a:b0:269:9e4d:4c8b with SMTP id d9443c01a7336-290ca403110mr277385325ad.21.1761175647556; Wed, 22 Oct 2025 16:27:27 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([147.161.216.252]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-33fb01919aasm331129a91.17.2025.10.22.16.27.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Oct 2025 16:27:27 -0700 (PDT) From: Ankur Tyagi To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-python][scarthgap][PATCH v2 8/8] python3-django: upgrade 5.0.11 -> 5.0.14 Date: Thu, 23 Oct 2025 12:26:31 +1300 Message-ID: <20251022232633.1703690-9-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> References: <20251022232633.1703690-1-ankur.tyagi85@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 22 Oct 2025 23:27:37 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/120909 Includes fix for CVE-2025-26699 and CVE-2025-27556 Release notes: https://docs.djangoproject.com/en/dev/releases/5.0.12/ https://docs.djangoproject.com/en/dev/releases/5.0.13/ https://docs.djangoproject.com/en/dev/releases/5.0.14/ Signed-off-by: Ankur Tyagi --- .../{python3-django_5.0.11.bb => python3-django_5.0.14.bb} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename meta-python/recipes-devtools/python/{python3-django_5.0.11.bb => python3-django_5.0.14.bb} (56%) diff --git a/meta-python/recipes-devtools/python/python3-django_5.0.11.bb b/meta-python/recipes-devtools/python/python3-django_5.0.14.bb similarity index 56% rename from meta-python/recipes-devtools/python/python3-django_5.0.11.bb rename to meta-python/recipes-devtools/python/python3-django_5.0.14.bb index 5060f3c9ad..b95a5067fb 100644 --- a/meta-python/recipes-devtools/python/python3-django_5.0.11.bb +++ b/meta-python/recipes-devtools/python/python3-django_5.0.14.bb @@ -1,7 +1,7 @@ require python-django.inc inherit setuptools3 -SRC_URI[sha256sum] = "e7d98fa05ce09cb3e8d5ad6472fb602322acd1740bfdadc29c8404182d664f65" +SRC_URI[sha256sum] = "29019a5763dbd48da1720d687c3522ef40d1c61be6fb2fad27ed79e9f655bc11" RDEPENDS:${PN} += "\ python3-sqlparse \