From 6655ee7efeeab665b0ac76316c61fe22b8406ee7 Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Thu, 9 May 2024 17:20:05 +0200 Subject: [PATCH] WIP: Avoid potential DoS with high compression Signed-off-by: Sergio Arroutbi --- lib/jwe.c | 7 +++++++ lib/zlib/deflate.c | 6 ++++++ tests/alg_comp.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++ tests/api_jwe.c | 17 ++++++++++++++++ 4 files changed, 81 insertions(+) diff --git a/lib/jwe.c b/lib/jwe.c index 516245bd..399526d5 100644 --- a/lib/jwe.c +++ b/lib/jwe.c @@ -28,6 +28,8 @@ #include +#define MAX_COMPRESSED_SIZE (256*1024) + static bool jwe_hdr_set_new(json_t *jwe, const char *name, json_t *value) { @@ -357,6 +359,11 @@ jose_jwe_dec(jose_cfg_t *cfg, const json_t *jwe, const json_t *rcp, { json_auto_t *cek = NULL; + if (ptl && *ptl > MAX_COMPRESSED_SIZE) { + jose_cfg_err(cfg, JOSE_CFG_ERR_JWK_DENIED, "Maximum decompression size reached"); + return NULL; + } + cek = jose_jwe_dec_jwk(cfg, jwe, rcp, jwk); if (!cek) return NULL; diff --git a/lib/zlib/deflate.c b/lib/zlib/deflate.c index 07eca0c9..9dfbbf3b 100644 --- a/lib/zlib/deflate.c +++ b/lib/zlib/deflate.c @@ -23,8 +23,11 @@ #define containerof(ptr, type, member) \ ((type *)((char *) ptr - offsetof(type, member))) +static size_t MAX_COMPRESSED_SIZE = (256*1024); + static size_t SIZE = 4096; + typedef struct { jose_io_t io; jose_io_t *next; @@ -34,6 +37,9 @@ typedef struct { static bool feed(jose_io_t *io, const void *in, size_t len, typeof(deflate) *func) { + if (len > MAX_COMPRESSED_SIZE) { + return false; + } io_t *i = containerof(io, io_t, io); i->strm.next_in = (void *) in; diff --git a/tests/alg_comp.c b/tests/alg_comp.c index fcd305c1..a05f2eae 100644 --- a/tests/alg_comp.c +++ b/tests/alg_comp.c @@ -19,6 +19,7 @@ #include #include #include +#include const struct { const char *alg; @@ -41,6 +42,53 @@ const struct { {} }; +static uint8_t* get_random_string(uint32_t length) +{ + assert(length); + uint8_t* c = (uint8_t*)malloc(length*sizeof(uint8_t)); + for (uint32_t i=0; icomp.def(a, NULL, b); + assert(z); + + assert(z->feed(z, str, inputlen)); + assert(z->done(z)); + + /* Test decompression now. */ + c = jose_io_malloc(NULL, &buf2, &clen); + assert(b); + z = a->comp.inf(a, NULL, c); + assert(z); + assert(z->feed(z, buf1, blen)); + assert(z->done(z)); + + /* Compare the final output with the original input. */ + assert(clen == inputlen); + assert(memcmp(buf2, str, inputlen) == 0); + + free(str); +} + static void test(const jose_hook_alg_t *a, bool iter, const uint8_t *i, size_t il) @@ -119,5 +167,8 @@ main(int argc, char *argv[]) tst_inf, sizeof(tst_inf)); } + test_long_string(200000); // inside limits + // test_long_string(300000); // outside limits + return EXIT_SUCCESS; } diff --git a/tests/api_jwe.c b/tests/api_jwe.c index f1d7a481..677c7b88 100644 --- a/tests/api_jwe.c +++ b/tests/api_jwe.c @@ -43,6 +43,15 @@ dec(json_t *jwe, json_t *jwk) return ret; } +static char* get_string(uint32_t length, char fill) { + assert(length); + char* c = (char*)malloc(length*sizeof(char)); + for (uint32_t i=0; i