Your message dated Sat, 11 Jul 2026 10:32:48 +0000
with message-id <[email protected]>
and subject line Released in 13.6
has caused the Debian Bug report #1140850,
regarding trixie-pu: package python-jwcrypto/1.5.6-1.1~deb13u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
1140850: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1140850
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected], [email protected]
Control: affects -1 + src:python-jwcrypto
User: [email protected]
Usertags: pu

  * CVE-2026-39373: JWT bomb Attack in deserialize (Closes: #1133006)
diffstat for python-jwcrypto-1.5.6 python-jwcrypto-1.5.6

 changelog                                                         |   14 
 patches/0001-Limit-max-plaintext-size-for-JWE-decompression.patch |  156 
++++++++++
 patches/series                                                    |    1 
 3 files changed, 171 insertions(+)

diff -Nru python-jwcrypto-1.5.6/debian/changelog 
python-jwcrypto-1.5.6/debian/changelog
--- python-jwcrypto-1.5.6/debian/changelog      2024-05-02 09:03:21.000000000 
+0300
+++ python-jwcrypto-1.5.6/debian/changelog      2026-06-27 21:49:49.000000000 
+0300
@@ -1,3 +1,17 @@
+python-jwcrypto (1.5.6-1.1~deb13u1) trixie; urgency=medium
+
+  * Non-maintainer upload.
+  * Rebuild for trixie.
+
+ -- Adrian Bunk <[email protected]>  Sat, 27 Jun 2026 21:49:49 +0300
+
+python-jwcrypto (1.5.6-1.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * CVE-2026-39373: JWT bomb Attack in deserialize (Closes: #1133006)
+
+ -- Adrian Bunk <[email protected]>  Tue, 23 Jun 2026 17:17:46 +0300
+
 python-jwcrypto (1.5.6-1) unstable; urgency=medium
 
   * New upstream release.
diff -Nru 
python-jwcrypto-1.5.6/debian/patches/0001-Limit-max-plaintext-size-for-JWE-decompression.patch
 
python-jwcrypto-1.5.6/debian/patches/0001-Limit-max-plaintext-size-for-JWE-decompression.patch
--- 
python-jwcrypto-1.5.6/debian/patches/0001-Limit-max-plaintext-size-for-JWE-decompression.patch
      1970-01-01 02:00:00.000000000 +0200
+++ 
python-jwcrypto-1.5.6/debian/patches/0001-Limit-max-plaintext-size-for-JWE-decompression.patch
      2026-06-23 17:17:46.000000000 +0300
@@ -0,0 +1,156 @@
+From 4c4740f2c8f94793f27c0bfc5689dc28d131da45 Mon Sep 17 00:00:00 2001
+From: Simo Sorce <[email protected]>
+Date: Mon, 6 Apr 2026 10:37:20 -0400
+Subject: Limit max plaintext size for JWE decompression
+
+This change introduces a maximum plaintext size limit (defaulting to 100MB)
+during JWE decryption and updates the decompression logic to enforce it safely
+using zlib.decompressobj. The decrypt method now accepts a max_plaintext
+parameter to allow overriding the default limit.
+
+This mitigates memory exhaustion and decompression bomb attacks when
+processing highly compressed malicious JWE payloads.
+
+Fixes CVE-2026-39373
+
+Signed-off-by: Simo Sorce <[email protected]>
+---
+ jwcrypto/jwe.py   | 27 +++++++++++++++++++++------
+ jwcrypto/tests.py | 34 ++++++++++++++++++++++++++--------
+ 2 files changed, 47 insertions(+), 14 deletions(-)
+
+diff --git a/jwcrypto/jwe.py b/jwcrypto/jwe.py
+index 5df500b..613699e 100644
+--- a/jwcrypto/jwe.py
++++ b/jwcrypto/jwe.py
+@@ -12,7 +12,8 @@ from jwcrypto.jwk import JWKSet
+ 
+ # Limit the amount of data we are willing to decompress by default.
+ default_max_compressed_size = 256 * 1024
+-
++# Limit the maximum plaintext size to 100MB by default.
++default_max_plaintext_size = 100 * 1024 * 1024
+ 
+ # RFC 7516 - 4.1
+ # name: (description, supported?)
+@@ -371,7 +372,7 @@ class JWE:
+         return data
+ 
+     # FIXME: allow to specify which algorithms to accept as valid
+-    def _decrypt(self, key, ppe):
++    def _decrypt(self, key, ppe, max_plaintext=default_max_plaintext_size):
+ 
+         jh = self._get_jose_header(ppe.get('header', None))
+ 
+@@ -429,19 +430,29 @@ class JWE:
+                 raise InvalidJWEData(
+                     'Compressed data exceeds maximum allowed'
+                     'size' + f' ({default_max_compressed_size})')
+-            self.plaintext = zlib.decompress(data, -zlib.MAX_WBITS)
++            do = zlib.decompressobj(wbits=-zlib.MAX_WBITS)
++            self.plaintext = do.decompress(data, max_plaintext)
++            if do.unconsumed_tail or not do.eof:
++                self.plaintext = None
++                raise InvalidJWEData(
++                    'Compressed data exceeds maximum allowed'
++                    'output size' + f' ({max_plaintext})')
+         elif compress is None:
+             self.plaintext = data
+         else:
+             raise ValueError('Unknown compression')
+ 
+-    def decrypt(self, key):
++    def decrypt(self, key, max_plaintext=0):
+         """Decrypt a JWE token.
+ 
+         :param key: The (:class:`jwcrypto.jwk.JWK`) decryption key.
+         :param key: A (:class:`jwcrypto.jwk.JWK`) decryption key,
+          or a (:class:`jwcrypto.jwk.JWKSet`) that contains a key indexed
+          by the 'kid' header or (deprecated) a string containing a password.
++        :param max_plaintext: Maximum plaintext size allowed, 0 means
++         the library default applies. Application writers are recommended
++         to set a limit here if they know what is the max plaintext size
++         for their application.
+ 
+         :raises InvalidJWEOperation: if the key is not a JWK object.
+         :raises InvalidJWEData: if the ciphertext can't be decrypted or
+@@ -449,6 +460,10 @@ class JWE:
+         :raises JWKeyNotFound: if key is a JWKSet and the key is not found.
+         """
+ 
++        self.plaintext = None
++        if max_plaintext == 0:
++            max_plaintext = default_max_plaintext_size
++
+         if 'ciphertext' not in self.objects:
+             raise InvalidJWEOperation("No available ciphertext")
+         self.decryptlog = []
+@@ -457,14 +472,14 @@ class JWE:
+         if 'recipients' in self.objects:
+             for rec in self.objects['recipients']:
+                 try:
+-                    self._decrypt(key, rec)
++                    self._decrypt(key, rec, max_plaintext=max_plaintext)
+                 except Exception as e:  # pylint: disable=broad-except
+                     if isinstance(e, JWKeyNotFound):
+                         missingkey = True
+                     self.decryptlog.append('Failed: [%s]' % repr(e))
+         else:
+             try:
+-                self._decrypt(key, self.objects)
++                self._decrypt(key, self.objects, max_plaintext=max_plaintext)
+             except Exception as e:  # pylint: disable=broad-except
+                 if isinstance(e, JWKeyNotFound):
+                     missingkey = True
+diff --git a/jwcrypto/tests.py b/jwcrypto/tests.py
+index 59049f8..d75761a 100644
+--- a/jwcrypto/tests.py
++++ b/jwcrypto/tests.py
+@@ -2124,18 +2124,36 @@ class ConformanceTests(unittest.TestCase):
+         enc = jwe.JWE(payload.encode('utf-8'),
+                       recipient=key,
+                       protected=protected_header).serialize(compact=True)
++        check = jwe.JWE()
++        check.deserialize(enc)
+         with self.assertRaises(jwe.InvalidJWEData):
+-            check = jwe.JWE()
+-            check.deserialize(enc)
+             check.decrypt(key)
+ 
+-        defmax = jwe.default_max_compressed_size
+-        jwe.default_max_compressed_size = 1000000000
+-        # ensure we can eraise the limit and decrypt
+-        check = jwe.JWE()
+-        check.deserialize(enc)
++        # raise the limit on compressed token size so we can decrypt
++        defcmax = jwe.default_max_compressed_size
++        jwe.default_max_compressed_size = 10 * 1024 * 1024
++
++        # this passes if we explicitly allow larger plaintext via API
++        check.decrypt(key, max_plaintext=1000000000)
++
++        # this will still fail because the max plaintext length clamps this
++        with self.assertRaises(jwe.InvalidJWEData):
++            check.decrypt(key)
++
++        # ensure that now this can work with changed defaults
++        defpmax = jwe.default_max_plaintext_size
++        jwe.default_max_plaintext_size = 1000000000
+         check.decrypt(key)
+-        jwe.default_max_compressed_size = defmax
++
++        # restore limits
++        jwe.default_max_compressed_size = defcmax
++
++        # check that this fails the max compressed header limits
++        with self.assertRaises(jwe.InvalidJWEData):
++            check.decrypt(key)
++
++        # restore plaintext limits
++        jwe.default_max_plaintext_size = defpmax
+ 
+ 
+ class JWATests(unittest.TestCase):
+-- 
+2.47.3
+
diff -Nru python-jwcrypto-1.5.6/debian/patches/series 
python-jwcrypto-1.5.6/debian/patches/series
--- python-jwcrypto-1.5.6/debian/patches/series 1970-01-01 02:00:00.000000000 
+0200
+++ python-jwcrypto-1.5.6/debian/patches/series 2026-06-23 17:17:46.000000000 
+0300
@@ -0,0 +1 @@
+0001-Limit-max-plaintext-size-for-JWE-decompression.patch

--- End Message ---
--- Begin Message ---
Version: 13.6

This update was released as part of 13.6.

--- End Message ---

Reply via email to