@@ -283,7 +283,7 @@ static int oauth2_jwt_base64url_decode(const char *segment,
283283
284284 /* First, count non-whitespace characters */
285285 for (i = 0 ; i < segment_len ; i ++ ) {
286- if (!isspace ((unsigned char )segment [i ])) {
286+ if (!isspace ((unsigned char ) segment [i ])) {
287287 clean_len ++ ;
288288 }
289289 }
@@ -303,7 +303,7 @@ static int oauth2_jwt_base64url_decode(const char *segment,
303303
304304 /* Copy and convert base64url to base64, skipping whitespace */
305305 for (i = 0 ; i < segment_len && j < clean_len ; i ++ ) {
306- c = (unsigned char )segment [i ];
306+ c = (unsigned char ) segment [i ];
307307
308308 if (isspace (c )) {
309309 continue ; /* Skip whitespace */
@@ -340,8 +340,8 @@ static int oauth2_jwt_base64url_decode(const char *segment,
340340 padded [padded_len ] = '\0' ;
341341
342342 /* First pass: get required buffer size */
343- ret = flb_base64_decode (NULL , 0 , decoded_len ,
344- ( unsigned char * ) padded , padded_len );
343+ ret = flb_base64_decode (NULL , 0 , decoded_len , ( unsigned char * ) padded , padded_len );
344+
345345 /* Note: ret will be FLB_BASE64_ERR_BUFFER_TOO_SMALL (-42) on first pass, this is expected */
346346 if (ret != 0 && ret != FLB_BASE64_ERR_BUFFER_TOO_SMALL ) {
347347 flb_free (padded );
@@ -360,8 +360,7 @@ static int oauth2_jwt_base64url_decode(const char *segment,
360360 return FLB_OAUTH2_JWT_ERR_INVALID_ARGUMENT ;
361361 }
362362
363- ret = flb_base64_decode (* decoded , * decoded_len , decoded_len ,
364- (unsigned char * ) padded , padded_len );
363+ ret = flb_base64_decode (* decoded , * decoded_len , decoded_len , (unsigned char * ) padded , padded_len );
365364 flb_free (padded );
366365
367366 if (ret != 0 ) {
@@ -431,8 +430,8 @@ static int oauth2_jwt_parse_header(const char *json, size_t json_len,
431430 if (v -> type == MSGPACK_OBJECT_STR ) {
432431 key_len = k -> via .str .size ;
433432 val_len = v -> via .str .size ;
434- key_str = (const char * )k -> via .str .ptr ;
435- val_str = (const char * )v -> via .str .ptr ;
433+ key_str = (const char * ) k -> via .str .ptr ;
434+ val_str = (const char * ) v -> via .str .ptr ;
436435
437436 if (key_len == 3 && strncmp (key_str , "kid" , 3 ) == 0 ) {
438437 claims -> kid = flb_sds_create_len (val_str , val_len );
@@ -511,7 +510,7 @@ static int oauth2_jwt_parse_payload(const char *json, size_t json_len,
511510 }
512511
513512 key_len = k -> via .str .size ;
514- key_str = (const char * )k -> via .str .ptr ;
513+ key_str = (const char * ) k -> via .str .ptr ;
515514
516515 if (key_len == 3 && strncmp (key_str , "exp" , 3 ) == 0 ) {
517516 if (v -> type == MSGPACK_OBJECT_POSITIVE_INTEGER ) {
@@ -924,14 +923,14 @@ static int oauth2_jwt_verify_signature_rsa(const char *signing_input,
924923
925924 /* Decode base64url modulus and exponent */
926925 ret = oauth2_jwt_base64url_decode (modulus_b64 , flb_sds_len (modulus_b64 ),
927- (unsigned char * * )& modulus_bytes , & modulus_len ,
926+ (unsigned char * * ) & modulus_bytes , & modulus_len ,
928927 FLB_OAUTH2_JWT_ERR_INVALID_ARGUMENT );
929928 if (ret != FLB_OAUTH2_JWT_OK ) {
930929 goto cleanup ;
931930 }
932931
933932 ret = oauth2_jwt_base64url_decode (exponent_b64 , flb_sds_len (exponent_b64 ),
934- (unsigned char * * )& exponent_bytes , & exponent_len ,
933+ (unsigned char * * ) & exponent_bytes , & exponent_len ,
935934 FLB_OAUTH2_JWT_ERR_INVALID_ARGUMENT );
936935 if (ret != FLB_OAUTH2_JWT_OK ) {
937936 goto cleanup ;
@@ -1184,13 +1183,13 @@ static int oauth2_jwt_check_audience(const char *json, size_t json_len,
11841183 }
11851184
11861185 key_len = k -> via .str .size ;
1187- key_str = (const char * )k -> via .str .ptr ;
1186+ key_str = (const char * ) k -> via .str .ptr ;
11881187
11891188 if (key_len == 3 && strncmp (key_str , "aud" , 3 ) == 0 ) {
11901189 if (v -> type == MSGPACK_OBJECT_STR ) {
11911190 /* Single string audience */
11921191 if (v -> via .str .size == strlen (allowed_audience ) &&
1193- strncmp ((const char * )v -> via .str .ptr , allowed_audience ,
1192+ strncmp ((const char * ) v -> via .str .ptr , allowed_audience ,
11941193 v -> via .str .size ) == 0 ) {
11951194 found_match = 1 ;
11961195 }
@@ -1201,7 +1200,7 @@ static int oauth2_jwt_check_audience(const char *json, size_t json_len,
12011200 msgpack_object * elem = & v -> via .array .ptr [j ];
12021201 if (elem -> type == MSGPACK_OBJECT_STR ) {
12031202 if (elem -> via .str .size == strlen (allowed_audience ) &&
1204- strncmp ((const char * )elem -> via .str .ptr , allowed_audience ,
1203+ strncmp ((const char * ) elem -> via .str .ptr , allowed_audience ,
12051204 elem -> via .str .size ) == 0 ) {
12061205 found_match = 1 ;
12071206 break ;
@@ -1221,7 +1220,8 @@ static int oauth2_jwt_check_audience(const char *json, size_t json_len,
12211220
12221221static void oauth2_jwt_free_cfg (struct flb_oauth2_jwt_cfg * cfg )
12231222{
1224- /* Note: cfg->issuer, cfg->jwks_url, and cfg->allowed_audience are pointers
1223+ /*
1224+ * Note: cfg->issuer, cfg->jwks_url, and cfg->allowed_audience are pointers
12251225 * to strings owned by the Fluent Bit configuration system (flb_kv).
12261226 * They will be freed automatically when the input instance properties are
12271227 * destroyed, so we should NOT free them here to avoid double-free errors.
@@ -1257,9 +1257,6 @@ struct flb_oauth2_jwt_ctx *flb_oauth2_jwt_context_create(struct flb_config *conf
12571257 return NULL ;
12581258 }
12591259
1260- /* Don't download JWKS during initialization - do it lazily on first validation */
1261- /* This avoids blocking the initialization thread */
1262-
12631260 return ctx ;
12641261}
12651262
@@ -1374,33 +1371,24 @@ int flb_oauth2_jwt_validate(struct flb_oauth2_jwt_ctx *ctx,
13741371 }
13751372
13761373 /* Lookup key by kid */
1377- jwks_key = (struct flb_oauth2_jwks_key * )flb_hash_table_get_ptr (ctx -> jwks_cache .entries ,
1378- jwt .claims .kid ,
1379- flb_sds_len (jwt .claims .kid ));
1380- if (!jwks_key ) {
1381- /* Try to refresh JWKS and lookup again */
1382- ret = oauth2_jwks_fetch_keys (ctx );
1383- if (ret != 0 ) {
1384- flb_debug ("[oauth2_jwt] Failed to refresh JWKS: %d" , ret );
1385- status = FLB_OAUTH2_JWT_ERR_INVALID_ARGUMENT ;
1386- goto jwt_end ;
1387- }
1388- jwks_key = (struct flb_oauth2_jwks_key * )flb_hash_table_get_ptr (ctx -> jwks_cache .entries ,
1389- jwt .claims .kid ,
1390- flb_sds_len (jwt .claims .kid ));
1391- }
1392-
1374+ jwks_key = (struct flb_oauth2_jwks_key * ) flb_hash_table_get_ptr (ctx -> jwks_cache .entries ,
1375+ jwt .claims .kid ,
1376+ flb_sds_len (jwt .claims .kid ));
13931377 if (!jwks_key ) {
1378+ /*
1379+ * Key not found in cache - reject the token.
1380+ * JWKS refresh is time-based only to prevent DoS attacks from malicious tokens with
1381+ * random kid values. If key rotation requires faster refresh, configure a shorter
1382+ * jwks_refresh_interval. */
13941383 flb_debug ("[oauth2_jwt] Key with kid '%s' not found in JWKS" , jwt .claims .kid );
13951384 status = FLB_OAUTH2_JWT_ERR_INVALID_ARGUMENT ;
13961385 goto jwt_end ;
13971386 }
13981387
13991388 /* Verify RSA signature */
1400- verify_ret = oauth2_jwt_verify_signature_rsa (
1401- jwt .signing_input , flb_sds_len (jwt .signing_input ),
1402- jwt .signature , jwt .signature_len ,
1403- jwks_key -> modulus , jwks_key -> exponent );
1389+ verify_ret = oauth2_jwt_verify_signature_rsa (jwt .signing_input , flb_sds_len (jwt .signing_input ),
1390+ jwt .signature , jwt .signature_len ,
1391+ jwks_key -> modulus , jwks_key -> exponent );
14041392 if (verify_ret != 0 ) {
14051393 flb_debug ("[oauth2_jwt] Signature verification failed: ret=%d" , verify_ret );
14061394 status = FLB_OAUTH2_JWT_ERR_INVALID_ARGUMENT ;
@@ -1526,5 +1514,3 @@ struct mk_list *flb_oauth2_jwt_get_config_map(struct flb_config *config)
15261514
15271515 return config_map ;
15281516}
1529-
1530-
0 commit comments