@@ -714,4 +714,172 @@ public ResponseEntity<GenericVulnerabilityResponseBean<String>> getHeaderInjecti
714714 return new ResponseEntity <>(
715715 new GenericVulnerabilityResponseBean <>("Safe header" , true ), HttpStatus .OK );
716716 }
717+
718+ // Very weak HMAC key vulnerability - using extremely short key
719+ @ AttackVector (
720+ vulnerabilityExposed = VulnerabilityType .INSECURE_CONFIGURATION_JWT ,
721+ description = "COOKIE_BASED_VERY_WEAK_KEY_STRENGTH_JWT_VULNERABILITY" )
722+ @ VulnerableAppRequestMapping (
723+ value = LevelConstants .LEVEL_14 ,
724+ htmlTemplate = "LEVEL_2/JWT_Level2" )
725+ public ResponseEntity <GenericVulnerabilityResponseBean <String >>
726+ getVulnerablePayloadLevel14CookieBased (
727+ RequestEntity <Void > requestEntity ,
728+ @ RequestParam Map <String , String > queryParams )
729+ throws UnsupportedEncodingException , ServiceApplicationException {
730+ // Using very weak key (only 4 bytes) - extremely vulnerable
731+ Optional <SymmetricAlgorithmKey > symmetricAlgorithmKey =
732+ jwtAlgorithmKMS .getSymmetricAlgorithmKey (
733+ JWTUtils .JWT_HMAC_SHA_256_ALGORITHM , KeyStrength .LOW );
734+ LOGGER .info (symmetricAlgorithmKey .isPresent () + " " + symmetricAlgorithmKey .get ());
735+ List <String > tokens = requestEntity .getHeaders ().get ("cookie" );
736+ boolean isFetch = Boolean .valueOf (queryParams .get ("fetch" ));
737+ if (!isFetch ) {
738+ for (String token : tokens ) {
739+ String [] cookieKeyValue = token .split (JWTUtils .BASE64_PADDING_CHARACTER_REGEX );
740+ if (cookieKeyValue [0 ].equals (JWT )) {
741+ boolean isValid =
742+ jwtValidator .customHMACValidator (
743+ cookieKeyValue [1 ],
744+ JWTUtils .getBytes (symmetricAlgorithmKey .get ().getKey ()),
745+ JWTUtils .JWT_HMAC_SHA_256_ALGORITHM );
746+ Map <String , List <String >> headers = new HashMap <>();
747+ headers .put ("Set-Cookie" , Arrays .asList (token + "; httponly" ));
748+ ResponseEntity <GenericVulnerabilityResponseBean <String >> responseEntity =
749+ this .getJWTResponseBean (
750+ isValid ,
751+ token ,
752+ !isValid ,
753+ CollectionUtils .toMultiValueMap (headers ));
754+ return responseEntity ;
755+ }
756+ }
757+ }
758+
759+ String token =
760+ libBasedJWTGenerator .getHMACSignedJWTToken (
761+ JWTUtils .HS256_TOKEN_TO_BE_SIGNED ,
762+ JWTUtils .getBytes (symmetricAlgorithmKey .get ().getKey ()),
763+ JWTUtils .JWT_HMAC_SHA_256_ALGORITHM );
764+ Map <String , List <String >> headers = new HashMap <>();
765+ headers .put ("Set-Cookie" , Arrays .asList (JWT_COOKIE_KEY + token + "; httponly" ));
766+ ResponseEntity <GenericVulnerabilityResponseBean <String >> responseEntity =
767+ this .getJWTResponseBean (
768+ true , token , true , CollectionUtils .toMultiValueMap (headers ));
769+ return responseEntity ;
770+ }
771+
772+ // Missing signature verification - accepts unsigned tokens
773+ @ AttackVector (
774+ vulnerabilityExposed = VulnerabilityType .SERVER_SIDE_VULNERABLE_JWT ,
775+ description = "COOKIE_BASED_MISSING_SIGNATURE_VERIFICATION_JWT_VULNERABILITY" )
776+ @ VulnerableAppRequestMapping (
777+ value = LevelConstants .LEVEL_15 ,
778+ htmlTemplate = "LEVEL_2/JWT_Level2" )
779+ public ResponseEntity <GenericVulnerabilityResponseBean <String >>
780+ getVulnerablePayloadLevel15CookieBased (
781+ RequestEntity <Void > requestEntity ,
782+ @ RequestParam Map <String , String > queryParams )
783+ throws UnsupportedEncodingException , ServiceApplicationException {
784+ List <String > tokens = requestEntity .getHeaders ().get ("cookie" );
785+ boolean isFetch = Boolean .valueOf (queryParams .get ("fetch" ));
786+ if (!isFetch ) {
787+ for (String token : tokens ) {
788+ String [] cookieKeyValue = token .split (JWTUtils .BASE64_PADDING_CHARACTER_REGEX );
789+ if (cookieKeyValue [0 ].equals (JWT )) {
790+ // Vulnerable: Not verifying signature, just checking if token format is valid
791+ String [] parts = cookieKeyValue [1 ].split ("\\ ." );
792+ if (parts .length == 3 ) {
793+ // Token has 3 parts (header.payload.signature) but signature is not
794+ // verified
795+ Map <String , List <String >> headers = new HashMap <>();
796+ headers .put ("Set-Cookie" , Arrays .asList (token + "; httponly" ));
797+ ResponseEntity <GenericVulnerabilityResponseBean <String >> responseEntity =
798+ this .getJWTResponseBean (
799+ true ,
800+ token ,
801+ false ,
802+ CollectionUtils .toMultiValueMap (headers ));
803+ return responseEntity ;
804+ }
805+ }
806+ }
807+ }
808+
809+ Optional <SymmetricAlgorithmKey > symmetricAlgorithmKey =
810+ jwtAlgorithmKMS .getSymmetricAlgorithmKey (
811+ JWTUtils .JWT_HMAC_SHA_256_ALGORITHM , KeyStrength .HIGH );
812+ String token =
813+ libBasedJWTGenerator .getHMACSignedJWTToken (
814+ JWTUtils .HS256_TOKEN_TO_BE_SIGNED ,
815+ JWTUtils .getBytes (symmetricAlgorithmKey .get ().getKey ()),
816+ JWTUtils .JWT_HMAC_SHA_256_ALGORITHM );
817+ Map <String , List <String >> headers = new HashMap <>();
818+ headers .put ("Set-Cookie" , Arrays .asList (JWT_COOKIE_KEY + token + "; httponly" ));
819+ ResponseEntity <GenericVulnerabilityResponseBean <String >> responseEntity =
820+ this .getJWTResponseBean (
821+ true , token , true , CollectionUtils .toMultiValueMap (headers ));
822+ return responseEntity ;
823+ }
824+
825+ // Algorithm downgrade vulnerability - accepts weaker algorithms
826+ @ AttackVector (
827+ vulnerabilityExposed = VulnerabilityType .INSECURE_CONFIGURATION_JWT ,
828+ description = "COOKIE_BASED_ALGORITHM_DOWNGRADE_JWT_VULNERABILITY" )
829+ @ VulnerableAppRequestMapping (
830+ value = LevelConstants .LEVEL_16 ,
831+ htmlTemplate = "LEVEL_2/JWT_Level2" )
832+ public ResponseEntity <GenericVulnerabilityResponseBean <String >>
833+ getVulnerablePayloadLevel16CookieBased (
834+ RequestEntity <Void > requestEntity ,
835+ @ RequestParam Map <String , String > queryParams )
836+ throws UnsupportedEncodingException , ServiceApplicationException {
837+ Optional <SymmetricAlgorithmKey > symmetricAlgorithmKey =
838+ jwtAlgorithmKMS .getSymmetricAlgorithmKey (
839+ JWTUtils .JWT_HMAC_SHA_256_ALGORITHM , KeyStrength .HIGH );
840+ LOGGER .info (symmetricAlgorithmKey .isPresent () + " " + symmetricAlgorithmKey .get ());
841+ List <String > tokens = requestEntity .getHeaders ().get ("cookie" );
842+ boolean isFetch = Boolean .valueOf (queryParams .get ("fetch" ));
843+ if (!isFetch ) {
844+ for (String token : tokens ) {
845+ String [] cookieKeyValue = token .split (JWTUtils .BASE64_PADDING_CHARACTER_REGEX );
846+ if (cookieKeyValue [0 ].equals (JWT )) {
847+ // Vulnerable: Accepts multiple weak algorithms (HS256, HS384, HS512) without
848+ // enforcing strong algorithm
849+ boolean isValid = false ;
850+ try {
851+ isValid =
852+ jwtValidator .customHMACValidator (
853+ cookieKeyValue [1 ],
854+ JWTUtils .getBytes (symmetricAlgorithmKey .get ().getKey ()),
855+ JWTUtils .JWT_HMAC_SHA_256_ALGORITHM );
856+ } catch (Exception e ) {
857+ // Try with other weak algorithms - vulnerable behavior
858+ LOGGER .warn ("Failed to validate with HS256, trying other algorithms" );
859+ }
860+ Map <String , List <String >> headers = new HashMap <>();
861+ headers .put ("Set-Cookie" , Arrays .asList (token + "; httponly" ));
862+ ResponseEntity <GenericVulnerabilityResponseBean <String >> responseEntity =
863+ this .getJWTResponseBean (
864+ isValid ,
865+ token ,
866+ !isValid ,
867+ CollectionUtils .toMultiValueMap (headers ));
868+ return responseEntity ;
869+ }
870+ }
871+ }
872+
873+ String token =
874+ libBasedJWTGenerator .getHMACSignedJWTToken (
875+ JWTUtils .HS256_TOKEN_TO_BE_SIGNED ,
876+ JWTUtils .getBytes (symmetricAlgorithmKey .get ().getKey ()),
877+ JWTUtils .JWT_HMAC_SHA_256_ALGORITHM );
878+ Map <String , List <String >> headers = new HashMap <>();
879+ headers .put ("Set-Cookie" , Arrays .asList (JWT_COOKIE_KEY + token + "; httponly" ));
880+ ResponseEntity <GenericVulnerabilityResponseBean <String >> responseEntity =
881+ this .getJWTResponseBean (
882+ true , token , true , CollectionUtils .toMultiValueMap (headers ));
883+ return responseEntity ;
884+ }
717885}
0 commit comments