Skip to content

Commit 6655ee7

Browse files
committed
WIP: Avoid potential DoS with high compression
Signed-off-by: Sergio Arroutbi <[email protected]>
1 parent 76ec70b commit 6655ee7

File tree

4 files changed

+81
-0
lines changed

4 files changed

+81
-0
lines changed

lib/jwe.c

+7
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
#include <unistd.h>
3030

31+
#define MAX_COMPRESSED_SIZE (256*1024)
32+
3133
static bool
3234
jwe_hdr_set_new(json_t *jwe, const char *name, json_t *value)
3335
{
@@ -357,6 +359,11 @@ jose_jwe_dec(jose_cfg_t *cfg, const json_t *jwe, const json_t *rcp,
357359
{
358360
json_auto_t *cek = NULL;
359361

362+
if (ptl && *ptl > MAX_COMPRESSED_SIZE) {
363+
jose_cfg_err(cfg, JOSE_CFG_ERR_JWK_DENIED, "Maximum decompression size reached");
364+
return NULL;
365+
}
366+
360367
cek = jose_jwe_dec_jwk(cfg, jwe, rcp, jwk);
361368
if (!cek)
362369
return NULL;

lib/zlib/deflate.c

+6
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@
2323
#define containerof(ptr, type, member) \
2424
((type *)((char *) ptr - offsetof(type, member)))
2525

26+
static size_t MAX_COMPRESSED_SIZE = (256*1024);
27+
2628
static size_t SIZE = 4096;
2729

30+
2831
typedef struct {
2932
jose_io_t io;
3033
jose_io_t *next;
@@ -34,6 +37,9 @@ typedef struct {
3437
static bool
3538
feed(jose_io_t *io, const void *in, size_t len, typeof(deflate) *func)
3639
{
40+
if (len > MAX_COMPRESSED_SIZE) {
41+
return false;
42+
}
3743
io_t *i = containerof(io, io_t, io);
3844

3945
i->strm.next_in = (void *) in;

tests/alg_comp.c

+51
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <jose/jose.h>
2020
#include <assert.h>
2121
#include <string.h>
22+
#include <stdlib.h>
2223

2324
const struct {
2425
const char *alg;
@@ -41,6 +42,53 @@ const struct {
4142
{}
4243
};
4344

45+
static uint8_t* get_random_string(uint32_t length)
46+
{
47+
assert(length);
48+
uint8_t* c = (uint8_t*)malloc(length*sizeof(uint8_t));
49+
for (uint32_t i=0; i<length; i++) {
50+
c[i] = 'A' + (random() % 26);
51+
}
52+
return c;
53+
}
54+
55+
static void
56+
test_long_string(size_t inputlen) {
57+
jose_io_auto_t *b = NULL;
58+
jose_io_auto_t *c = NULL;
59+
jose_io_auto_t *z = NULL;
60+
void *buf1 = NULL;
61+
void *buf2 = NULL;
62+
size_t blen = 0;
63+
size_t clen = 0;
64+
const jose_hook_alg_t *a = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_COMP, "DEF");
65+
uint8_t* str = get_random_string(inputlen);
66+
67+
68+
/* Test compression first. */
69+
b = jose_io_malloc(NULL, &buf1, &blen);
70+
assert(b);
71+
z = a->comp.def(a, NULL, b);
72+
assert(z);
73+
74+
assert(z->feed(z, str, inputlen));
75+
assert(z->done(z));
76+
77+
/* Test decompression now. */
78+
c = jose_io_malloc(NULL, &buf2, &clen);
79+
assert(b);
80+
z = a->comp.inf(a, NULL, c);
81+
assert(z);
82+
assert(z->feed(z, buf1, blen));
83+
assert(z->done(z));
84+
85+
/* Compare the final output with the original input. */
86+
assert(clen == inputlen);
87+
assert(memcmp(buf2, str, inputlen) == 0);
88+
89+
free(str);
90+
}
91+
4492
static void
4593
test(const jose_hook_alg_t *a, bool iter,
4694
const uint8_t *i, size_t il)
@@ -119,5 +167,8 @@ main(int argc, char *argv[])
119167
tst_inf, sizeof(tst_inf));
120168
}
121169

170+
test_long_string(200000); // inside limits
171+
// test_long_string(300000); // outside limits
172+
122173
return EXIT_SUCCESS;
123174
}

tests/api_jwe.c

+17
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ dec(json_t *jwe, json_t *jwk)
4343
return ret;
4444
}
4545

46+
static char* get_string(uint32_t length, char fill) {
47+
assert(length);
48+
char* c = (char*)malloc(length*sizeof(char));
49+
for (uint32_t i=0; i<length; i++) {
50+
c[i] = fill;
51+
}
52+
return c;
53+
}
54+
4655
int
4756
main(int argc, char *argv[])
4857
{
@@ -98,5 +107,13 @@ main(int argc, char *argv[])
98107
assert(dec(jwe, set1));
99108
assert(dec(jwe, set2));
100109

110+
char* long_str_300k = get_string(300000, 'a');
111+
json_decref(jwe);
112+
assert((jwe = json_object()));
113+
assert(jose_jwe_enc(NULL, jwe, NULL, jwke, long_str_300k, 300000));
114+
assert(!dec(jwe, jwke));
115+
free(long_str_300k);
116+
json_decref(jwe);
117+
101118
return EXIT_SUCCESS;
102119
}

0 commit comments

Comments
 (0)