Compare commits

...

No commits in common. "c8s-stream-DL1" and "stream-idm-DL1-rhel-8.10.0" have entirely different histories.

8 changed files with 165 additions and 2 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
SOURCES/jwcrypto-0.5.0.tar.gz
/jwcrypto-0.5.0.tar.gz

View File

@ -1 +1 @@
8eccc6fbeeee2fedc602998a7c7a97b8bd550e59 SOURCES/jwcrypto-0.5.0.tar.gz
8eccc6fbeeee2fedc602998a7c7a97b8bd550e59 jwcrypto-0.5.0.tar.gz

View File

@ -0,0 +1,74 @@
From 90477a3b6e73da69740e00b8161f53fea19b831f Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 5 Mar 2024 16:57:17 -0500
Subject: [PATCH] Address potential DoS with high compression ratio
Fixes CVE-2024-28102
Signed-off-by: Simo Sorce <simo@redhat.com>
---
jwcrypto/jwe.py | 7 +++++++
jwcrypto/tests.py | 26 ++++++++++++++++++++++++++
2 files changed, 33 insertions(+)
diff --git a/jwcrypto/jwe.py b/jwcrypto/jwe.py
index 9412881..5df500b 100644
--- a/jwcrypto/jwe.py
+++ b/jwcrypto/jwe.py
@@ -9,5 +10,8 @@
from jwcrypto.jwa import JWA
+# Limit the amount of data we are willing to decompress by default.
+default_max_compressed_size = 256 * 1024
+
# RFC 7516 - 4.1
# name: (description, supported?)
@@ -374,6 +374,10 @@ def _decrypt(self, key, ppe):
compress = jh.get('zip', None)
if compress == 'DEF':
+ if len(data) > default_max_compressed_size:
+ raise InvalidJWEData(
+ 'Compressed data exceeds maximum allowed'
+ 'size' + f' ({default_max_compressed_size})')
self.plaintext = zlib.decompress(data, -zlib.MAX_WBITS)
elif compress is None:
self.plaintext = data
diff --git a/jwcrypto/tests.py b/jwcrypto/tests.py
index bb2ff10..59049f8 100644
--- a/jwcrypto/tests.py
+++ b/jwcrypto/tests.py
@@ -1196,6 +1196,32 @@ def test_pbes2_hs256_aeskw_custom_params(self):
check.deserialize(enc, key)
self.assertEqual(b'plain', check.payload)
+ def test_jwe_decompression_max(self):
+ key = jwk.JWK(kty='oct', k=base64url_encode(b'A' * (128 // 8)))
+ payload = '{"u": "' + "u" * 400000000 + '", "uu":"' \
+ + "u" * 400000000 + '"}'
+ protected_header = {
+ "alg": "A128KW",
+ "enc": "A128GCM",
+ "typ": "JWE",
+ "zip": "DEF",
+ }
+ enc = jwe.JWE(payload.encode('utf-8'),
+ recipient=key,
+ protected=protected_header).serialize(compact=True)
+ 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)
+ check.decrypt(key)
+ jwe.default_max_compressed_size = defmax
+
class JWATests(unittest.TestCase):
def test_jwa_create(self):

View File

@ -0,0 +1,44 @@
From d2655d370586cb830e49acfb450f87598da60be8 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Thu, 7 Dec 2023 12:49:07 -0500
Subject: [PATCH] Fix potential DoS issue with p2c header
Unbounded p2c headers may be used to cause an application that accept
PBES algorithms to spend alot of resources running PBKDF2 with a very
high number of iterations.
Clamp the default maximum to 16384 (double the default of 8192).
An application that wants to use more iterations will have to chenge the
jwa default max.
Fixes CVE-2023-6681
Signed-off-by: Simo Sorce <simo@redhat.com>
---
jwcrypto/jwa.py | 5 +++++
jwcrypto/tests.py | 12 ++++++++++++
2 files changed, 17 insertions(+)
diff --git a/jwcrypto/jwa.py b/jwcrypto/jwa.py
index de7a79f..ca4568e 100644
--- a/jwcrypto/jwa.py
+++ b/jwcrypto/jwa.py
@@ -29,6 +29,8 @@
# Implements RFC 7518 - JSON Web Algorithms (JWA)
+default_max_pbkdf2_iterations = 16384
+
@six.add_metaclass(abc.ABCMeta)
class JWAAlgorithm(object):
@@ -588,6 +590,9 @@ def __init__(self):
self.aeskwmap = {128: _A128KW, 192: _A192KW, 256: _A256KW}
def _get_key(self, alg, key, p2s, p2c):
+ if p2c > default_max_pbkdf2_iterations:
+ raise ValueError('Invalid p2c value, too large')
+
if isinstance(key, bytes):
plain = key
else:

7
gating.yaml Normal file
View File

@ -0,0 +1,7 @@
# recipients: abokovoy, frenaud, kaleem, ftrivino, cheimes
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

View File

@ -16,13 +16,16 @@
Name: python-%{srcname}
Version: 0.5.0
Release: 1.1%{?dist}
Release: 2%{?dist}
Summary: Implements JWK, JWS, JWE specifications using python-cryptography
License: LGPLv3+
URL: https://github.com/latchset/%{srcname}
Source0: https://github.com/latchset/%{srcname}/releases/download/v%{version}/%{srcname}-%{version}.tar.gz
Patch1: 0001-Address-potential-DoS-with-high-compression-ratio_rhel#28697.patch
Patch2: 0002-Limit-number-of-iterations-for-PBES_rhel#23038.patch
BuildArch: noarch
%if %{with python2}
BuildRequires: python2-devel
@ -64,6 +67,7 @@ Implements JWK, JWS, JWE specifications using python-cryptography
%prep
%setup -q -n %{srcname}-%{version}
%autopatch -p 1
%build
%if %{with python2}
@ -114,6 +118,12 @@ rm -rf %{buildroot}/usr/share/doc/jwcrypto
%changelog
* Mon Apr 15 2024 Rafael Jeffman <rjeffman@redhat.com> - 0.5.0-2
- Address potential DoS with high compression ratio
Resolves: RHEL-28697
- Limit number of iterations for PBES
Resolves: RHEL-23036 RHEL-23037
* Fri Jun 17 2022 Christian Heimes <cheimes@redhat.com> - 0.5.0-1.1
- Bump dist to solve version sorting issue, fixes RHBZ#2097800

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (jwcrypto-0.5.0.tar.gz) = 78a670a0a24c772ed8fd04f8786f34a9cfd1c74cb0943897f9e09bfd73344a7836c6930e0c22e123db5a02d129cec2a9133081166f97b5c76d05ada7b1831089

26
tests/tests.yml Normal file
View File

@ -0,0 +1,26 @@
---
- hosts: localhost
tags:
- classic
pre_tasks:
- name: Enable CRB for python3-pytest on 1minutetip
ini_file:
path: /etc/yum.repos.d/rhel.repo
section: rhel-CRB
option: enabled
value: "1"
create: no
ignore_errors: yes
roles:
- role: standard-test-source
- role: standard-test-basic
required_packages:
- python3-jwcrypto
- python3-pytest
tests:
- unittests:
dir: "source"
# remove jwcrypto Python files to run tests with packages code
run: >-
rm -rf jwcrypto/j*.py jwcrypto/__init__.py jwcrypto/__pycache__ &&
python3 -m pytest jwcrypto/test*.py