Skip to content

Commit db29231

Browse files
authored
Merge pull request #149 from SasanLabs/Fix1
Few Changes to JWT Vulnerability
2 parents 659a0b4 + 5fde75a commit db29231

File tree

3 files changed

+55
-35
lines changed

3 files changed

+55
-35
lines changed

src/main/java/org/sasanlabs/service/vulnerability/jwt/JWTVulnerability.java

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,13 @@ public class JWTVulnerability implements ICustomVulnerableEndPoint {
5656

5757
private static final transient Logger LOGGER = LogManager.getLogger(JWTVulnerability.class);
5858

59-
private ResponseBean<JWTResponseBean> getJWTResponseBean(boolean isValid, String jwtToken) {
59+
private ResponseBean<JWTResponseBean> getJWTResponseBean(
60+
boolean isValid, String jwtToken, boolean includeToken) {
6061
JWTResponseBean jwtResponseBean = new JWTResponseBean();
61-
jwtResponseBean.setValid(isValid);
62-
jwtResponseBean.setJwtToken(jwtToken);
62+
jwtResponseBean.setIsValid(isValid);
63+
if (includeToken) {
64+
jwtResponseBean.setJwtToken(jwtToken);
65+
}
6366
if (!isValid) {
6467
ResponseBean<JWTResponseBean> responseBean =
6568
new ResponseBean<JWTResponseBean>(jwtResponseBean);
@@ -91,14 +94,14 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure(
9194
token,
9295
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
9396
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
94-
return this.getJWTResponseBean(isValid, token);
97+
return this.getJWTResponseBean(isValid, token, !isValid);
9598
} else {
9699
token =
97100
libBasedJWTGenerator.getHMACSignedJWTToken(
98101
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
99102
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
100103
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
101-
return this.getJWTResponseBean(true, token);
104+
return this.getJWTResponseBean(true, token, true);
102105
}
103106
}
104107

@@ -118,7 +121,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure2CookieBas
118121
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM, KeyStrength.HIGH);
119122
LOGGER.error(symmetricAlgorithmKey.isPresent() + " " + symmetricAlgorithmKey.get());
120123
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
121-
if (tokens != null) {
124+
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
125+
if (!isFetch) {
122126
for (String token : tokens) {
123127
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
124128
if (cookieKeyValue[0].equals("JWTToken")) {
@@ -128,7 +132,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure2CookieBas
128132
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
129133
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
130134
ResponseBean<JWTResponseBean> responseBean =
131-
this.getJWTResponseBean(isValid, token);
135+
this.getJWTResponseBean(isValid, token, !isValid);
132136
responseBean.getResponseHeaders().put("Set-Cookie", Arrays.asList(token));
133137
return responseBean;
134138
}
@@ -139,7 +143,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure2CookieBas
139143
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
140144
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
141145
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
142-
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
146+
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
143147
responseBean.getResponseHeaders().put("Set-Cookie", Arrays.asList("JWTToken=" + token));
144148
return responseBean;
145149
}
@@ -160,7 +164,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure3CookieBas
160164
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM, KeyStrength.HIGH);
161165
LOGGER.error(symmetricAlgorithmKey.isPresent() + " " + symmetricAlgorithmKey.get());
162166
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
163-
if (tokens != null) {
167+
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
168+
if (!isFetch) {
164169
for (String token : tokens) {
165170
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
166171
if (cookieKeyValue[0].equals("JWTToken")) {
@@ -170,7 +175,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure3CookieBas
170175
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
171176
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
172177
ResponseBean<JWTResponseBean> responseBean =
173-
this.getJWTResponseBean(isValid, token);
178+
this.getJWTResponseBean(isValid, token, !isValid);
174179
responseBean
175180
.getResponseHeaders()
176181
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
@@ -183,7 +188,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure3CookieBas
183188
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
184189
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
185190
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
186-
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
191+
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
187192
responseBean
188193
.getResponseHeaders()
189194
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
@@ -209,7 +214,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure4CookieBas
209214
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM, KeyStrength.LOW);
210215
LOGGER.error(symmetricAlgorithmKey.isPresent() + " " + symmetricAlgorithmKey.get());
211216
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
212-
if (tokens != null) {
217+
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
218+
if (!isFetch) {
213219
for (String token : tokens) {
214220
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
215221
if (cookieKeyValue[0].equals("JWTToken")) {
@@ -219,7 +225,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure4CookieBas
219225
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
220226
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
221227
ResponseBean<JWTResponseBean> responseBean =
222-
this.getJWTResponseBean(isValid, token);
228+
this.getJWTResponseBean(isValid, token, !isValid);
223229
responseBean
224230
.getResponseHeaders()
225231
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
@@ -233,7 +239,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure4CookieBas
233239
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
234240
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
235241
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
236-
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
242+
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
237243
responseBean
238244
.getResponseHeaders()
239245
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
@@ -259,7 +265,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure5CookieBas
259265
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM, KeyStrength.HIGH);
260266
LOGGER.error(symmetricAlgorithmKey.isPresent() + " " + symmetricAlgorithmKey.get());
261267
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
262-
if (tokens != null) {
268+
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
269+
if (!isFetch) {
263270
for (String token : tokens) {
264271
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
265272
if (cookieKeyValue[0].equals("JWTToken")) {
@@ -269,7 +276,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure5CookieBas
269276
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
270277
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
271278
ResponseBean<JWTResponseBean> responseBean =
272-
this.getJWTResponseBean(isValid, token);
279+
this.getJWTResponseBean(isValid, token, !isValid);
273280
responseBean
274281
.getResponseHeaders()
275282
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
@@ -283,7 +290,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure5CookieBas
283290
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
284291
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
285292
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
286-
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
293+
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
287294
responseBean
288295
.getResponseHeaders()
289296
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
@@ -310,7 +317,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure6CookieBas
310317
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM, KeyStrength.HIGH);
311318
LOGGER.error(symmetricAlgorithmKey.isPresent() + " " + symmetricAlgorithmKey.get());
312319
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
313-
if (tokens != null) {
320+
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
321+
if (!isFetch) {
314322
for (String token : tokens) {
315323
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
316324
if (cookieKeyValue[0].equals("JWTToken")) {
@@ -320,7 +328,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure6CookieBas
320328
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
321329
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
322330
ResponseBean<JWTResponseBean> responseBean =
323-
this.getJWTResponseBean(isValid, token);
331+
this.getJWTResponseBean(isValid, token, !isValid);
324332
responseBean
325333
.getResponseHeaders()
326334
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
@@ -334,7 +342,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure6CookieBas
334342
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
335343
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
336344
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
337-
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
345+
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
338346
responseBean
339347
.getResponseHeaders()
340348
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
@@ -360,7 +368,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure7CookieBas
360368
LOGGER.error(
361369
asymmetricAlgorithmKeyPair.isPresent() + " " + asymmetricAlgorithmKeyPair.get());
362370
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
363-
if (tokens != null) {
371+
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
372+
if (!isFetch) {
364373
for (String token : tokens) {
365374
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
366375
if (cookieKeyValue[0].equals("JWTToken")) {
@@ -369,7 +378,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure7CookieBas
369378
cookieKeyValue[1],
370379
asymmetricAlgorithmKeyPair.get().getPublic());
371380
ResponseBean<JWTResponseBean> responseBean =
372-
this.getJWTResponseBean(isValid, token);
381+
this.getJWTResponseBean(isValid, token, !isValid);
373382
responseBean
374383
.getResponseHeaders()
375384
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
@@ -382,7 +391,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure7CookieBas
382391
libBasedJWTGenerator.getJWTToken_RS256(
383392
JWTUtils.RS256_TOKEN_TO_BE_SIGNED,
384393
asymmetricAlgorithmKeyPair.get().getPrivate());
385-
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
394+
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
386395
responseBean
387396
.getResponseHeaders()
388397
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
@@ -409,15 +418,16 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure8CookieBas
409418
LOGGER.error(
410419
asymmetricAlgorithmKeyPair.isPresent() + " " + asymmetricAlgorithmKeyPair.get());
411420
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
412-
if (tokens != null) {
421+
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
422+
if (!isFetch) {
413423
for (String token : tokens) {
414424
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
415425
if (cookieKeyValue[0].equals("JWTToken")) {
416426
boolean isValid =
417427
jwtValidator.jwkKeyHeaderPublicKeyTrustingVulnerableValidator(
418428
cookieKeyValue[1]);
419429
ResponseBean<JWTResponseBean> responseBean =
420-
this.getJWTResponseBean(isValid, token);
430+
this.getJWTResponseBean(isValid, token, !isValid);
421431
responseBean
422432
.getResponseHeaders()
423433
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
@@ -445,7 +455,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure8CookieBas
445455
+ JWTUtils.JWT_TOKEN_PERIOD_CHARACTER
446456
+ GENERIC_BASE64_ENCODED_PAYLOAD,
447457
asymmetricAlgorithmKeyPair.get().getPrivate());
448-
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
458+
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
449459
responseBean
450460
.getResponseHeaders()
451461
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
@@ -471,7 +481,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure9CookieBas
471481
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM, KeyStrength.HIGH);
472482
LOGGER.error(symmetricAlgorithmKey.isPresent() + " " + symmetricAlgorithmKey.get());
473483
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
474-
if (tokens != null) {
484+
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
485+
if (!isFetch) {
475486
for (String token : tokens) {
476487
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
477488
if (cookieKeyValue[0].equals("JWTToken")) {
@@ -481,7 +492,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure9CookieBas
481492
symmetricAlgorithmKey.get().getKey(),
482493
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
483494
ResponseBean<JWTResponseBean> responseBean =
484-
this.getJWTResponseBean(isValid, token);
495+
this.getJWTResponseBean(isValid, token, !isValid);
485496
responseBean
486497
.getResponseHeaders()
487498
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
@@ -495,7 +506,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure9CookieBas
495506
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
496507
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
497508
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
498-
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
509+
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
499510
responseBean
500511
.getResponseHeaders()
501512
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
@@ -516,7 +527,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure10CookieBa
516527
ParameterBean parameterBean)
517528
throws UnsupportedEncodingException, ServiceApplicationException {
518529
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
519-
if (tokens != null) {
530+
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
531+
if (!isFetch) {
520532
for (String token : tokens) {
521533
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
522534
if (cookieKeyValue[0].equals("JWTToken")) {
@@ -530,7 +542,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure10CookieBa
530542
this.jwtValidator.genericJWTTokenValidator(
531543
cookieKeyValue[1], rsaPublicKey, "RS256");
532544
ResponseBean<JWTResponseBean> responseBean =
533-
this.getJWTResponseBean(isValid, token);
545+
this.getJWTResponseBean(isValid, token, !isValid);
534546
responseBean
535547
.getResponseHeaders()
536548
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
@@ -546,7 +558,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure10CookieBa
546558
String token =
547559
libBasedJWTGenerator.getJWTToken_RS256(
548560
JWTUtils.RS256_TOKEN_TO_BE_SIGNED, rsaPrivateKey);
549-
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
561+
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
550562
responseBean
551563
.getResponseHeaders()
552564
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));

src/main/java/org/sasanlabs/service/vulnerability/jwt/bean/JWTResponseBean.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,15 @@ public void setJwtToken(String jwtToken) {
1919
this.jwtToken = jwtToken;
2020
}
2121

22-
public boolean isValid() {
22+
/* Here getter and setters are not as per the standard
23+
* because of Jackson library issue.
24+
* <a href="https://stackoverflow.com/questions/32270422/jackson-renames-primitive-boolean-field-by-removing-is">Issue</a>
25+
*/
26+
public boolean getIsValid() {
2327
return isValid;
2428
}
2529

26-
public void setValid(boolean isValid) {
30+
public void setIsValid(boolean isValid) {
2731
this.isValid = isValid;
2832
}
2933
}

0 commit comments

Comments
 (0)