]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-oauth2: oauth-jwt - Ensure / and . are escaped in kid
authorAki Tuomi <aki.tuomi@open-xchange.com>
Thu, 4 Jun 2020 10:15:11 +0000 (13:15 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 5 Jun 2020 06:12:09 +0000 (09:12 +0300)
src/lib-oauth2/oauth2-jwt.c
src/lib-oauth2/test-oauth2-jwt.c

index faf37317f10461fc09899fe3fe6d34fa4c5cb9f8..a68875e57fc341869e345f96603ab3486b81c0da 100644 (file)
@@ -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 =
index bd46f571603b232b892e645b4a7624f48bd3a9be..71f1f1399041bbfb0aa18fe1d88fb51376b1d154 100644 (file)
@@ -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,