From 87f109d404f61fc9ef1ea6d6111da2dee1fe2870 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Thu, 4 Jun 2020 13:15:11 +0300 Subject: [PATCH] lib-oauth2: oauth-jwt - Ensure / and . are escaped in kid --- src/lib-oauth2/oauth2-jwt.c | 25 +++++++++++++++++++++++++ src/lib-oauth2/test-oauth2-jwt.c | 18 ++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/lib-oauth2/oauth2-jwt.c b/src/lib-oauth2/oauth2-jwt.c index faf37317f1..a68875e57f 100644 --- a/src/lib-oauth2/oauth2-jwt.c +++ b/src/lib-oauth2/oauth2-jwt.c @@ -403,6 +403,31 @@ int oauth2_try_parse_jwt(const struct oauth2_settings *set, return -1; } + size_t pos = strcspn(kid, "./%"); + if (pos < strlen(kid)) { + /* sanitize kid, cannot allow dots or / in it, so we encode them */ + string_t *new_kid = t_str_new(strlen(kid)); + /* put initial data */ + str_append_data(new_kid, kid, pos); + for (const char *c = kid+pos; *c != '\0'; c++) { + switch (*c) { + case '.': + str_append(new_kid, "%2e"); + break; + case '/': + str_append(new_kid, "%2f"); + break; + case '%': + str_append(new_kid, "%25"); + break; + default: + str_append_c(new_kid, *c); + break; + } + } + kid = str_c(new_kid); + } + /* parse body */ struct json_tree *body_tree; buffer_t *body = diff --git a/src/lib-oauth2/test-oauth2-jwt.c b/src/lib-oauth2/test-oauth2-jwt.c index bd46f57160..71f1f13990 100644 --- a/src/lib-oauth2/test-oauth2-jwt.c +++ b/src/lib-oauth2/test-oauth2-jwt.c @@ -500,6 +500,23 @@ static void test_jwt_key_files(void) test_end(); } +static void test_jwt_kid_escape(void) +{ + test_begin("JWT kid escape"); + /* save a token */ + buffer_t *secret = t_buffer_create(32); + void *ptr = buffer_append_space_unsafe(secret, 32); + random_fill(ptr, 32); + buffer_t *b64_key = t_base64_encode(0, (size_t)-1, secret->data, secret->used); + save_key_to("HS256", "hello%2eworld%2f%25", str_c(b64_key)); + /* make a token */ + buffer_t *tokenbuf = create_jwt_token_kid("HS256", "hello.world/%"); + /* sign it */ + sign_jwt_token_hs256(tokenbuf, secret); + test_jwt_token(str_c(tokenbuf)); + test_end(); +} + static void test_jwt_rs_token(void) { const char *error; @@ -657,6 +674,7 @@ int main(void) test_jwt_broken_token, test_jwt_dates, test_jwt_key_files, + test_jwt_kid_escape, test_jwt_rs_token, test_jwt_ps_token, test_jwt_ec_token, -- 2.47.3