Skip to content

Commit

Permalink
Merge pull request #149 from SasanLabs/Fix1
Browse files Browse the repository at this point in the history
Few Changes to JWT Vulnerability
  • Loading branch information
preetkaran20 authored Jul 5, 2020
2 parents 659a0b4 + 5fde75a commit db29231
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,13 @@ public class JWTVulnerability implements ICustomVulnerableEndPoint {

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

private ResponseBean<JWTResponseBean> getJWTResponseBean(boolean isValid, String jwtToken) {
private ResponseBean<JWTResponseBean> getJWTResponseBean(
boolean isValid, String jwtToken, boolean includeToken) {
JWTResponseBean jwtResponseBean = new JWTResponseBean();
jwtResponseBean.setValid(isValid);
jwtResponseBean.setJwtToken(jwtToken);
jwtResponseBean.setIsValid(isValid);
if (includeToken) {
jwtResponseBean.setJwtToken(jwtToken);
}
if (!isValid) {
ResponseBean<JWTResponseBean> responseBean =
new ResponseBean<JWTResponseBean>(jwtResponseBean);
Expand Down Expand Up @@ -91,14 +94,14 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure(
token,
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
return this.getJWTResponseBean(isValid, token);
return this.getJWTResponseBean(isValid, token, !isValid);
} else {
token =
libBasedJWTGenerator.getHMACSignedJWTToken(
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
return this.getJWTResponseBean(true, token);
return this.getJWTResponseBean(true, token, true);
}
}

Expand All @@ -118,7 +121,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure2CookieBas
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM, KeyStrength.HIGH);
LOGGER.error(symmetricAlgorithmKey.isPresent() + " " + symmetricAlgorithmKey.get());
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
if (tokens != null) {
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
if (!isFetch) {
for (String token : tokens) {
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
if (cookieKeyValue[0].equals("JWTToken")) {
Expand All @@ -128,7 +132,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure2CookieBas
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
ResponseBean<JWTResponseBean> responseBean =
this.getJWTResponseBean(isValid, token);
this.getJWTResponseBean(isValid, token, !isValid);
responseBean.getResponseHeaders().put("Set-Cookie", Arrays.asList(token));
return responseBean;
}
Expand All @@ -139,7 +143,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure2CookieBas
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
responseBean.getResponseHeaders().put("Set-Cookie", Arrays.asList("JWTToken=" + token));
return responseBean;
}
Expand All @@ -160,7 +164,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure3CookieBas
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM, KeyStrength.HIGH);
LOGGER.error(symmetricAlgorithmKey.isPresent() + " " + symmetricAlgorithmKey.get());
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
if (tokens != null) {
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
if (!isFetch) {
for (String token : tokens) {
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
if (cookieKeyValue[0].equals("JWTToken")) {
Expand All @@ -170,7 +175,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure3CookieBas
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
ResponseBean<JWTResponseBean> responseBean =
this.getJWTResponseBean(isValid, token);
this.getJWTResponseBean(isValid, token, !isValid);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
Expand All @@ -183,7 +188,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure3CookieBas
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
Expand All @@ -209,7 +214,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure4CookieBas
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM, KeyStrength.LOW);
LOGGER.error(symmetricAlgorithmKey.isPresent() + " " + symmetricAlgorithmKey.get());
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
if (tokens != null) {
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
if (!isFetch) {
for (String token : tokens) {
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
if (cookieKeyValue[0].equals("JWTToken")) {
Expand All @@ -219,7 +225,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure4CookieBas
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
ResponseBean<JWTResponseBean> responseBean =
this.getJWTResponseBean(isValid, token);
this.getJWTResponseBean(isValid, token, !isValid);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
Expand All @@ -233,7 +239,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure4CookieBas
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
Expand All @@ -259,7 +265,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure5CookieBas
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM, KeyStrength.HIGH);
LOGGER.error(symmetricAlgorithmKey.isPresent() + " " + symmetricAlgorithmKey.get());
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
if (tokens != null) {
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
if (!isFetch) {
for (String token : tokens) {
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
if (cookieKeyValue[0].equals("JWTToken")) {
Expand All @@ -269,7 +276,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure5CookieBas
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
ResponseBean<JWTResponseBean> responseBean =
this.getJWTResponseBean(isValid, token);
this.getJWTResponseBean(isValid, token, !isValid);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
Expand All @@ -283,7 +290,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure5CookieBas
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
Expand All @@ -310,7 +317,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure6CookieBas
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM, KeyStrength.HIGH);
LOGGER.error(symmetricAlgorithmKey.isPresent() + " " + symmetricAlgorithmKey.get());
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
if (tokens != null) {
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
if (!isFetch) {
for (String token : tokens) {
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
if (cookieKeyValue[0].equals("JWTToken")) {
Expand All @@ -320,7 +328,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure6CookieBas
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
ResponseBean<JWTResponseBean> responseBean =
this.getJWTResponseBean(isValid, token);
this.getJWTResponseBean(isValid, token, !isValid);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
Expand All @@ -334,7 +342,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure6CookieBas
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
Expand All @@ -360,7 +368,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure7CookieBas
LOGGER.error(
asymmetricAlgorithmKeyPair.isPresent() + " " + asymmetricAlgorithmKeyPair.get());
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
if (tokens != null) {
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
if (!isFetch) {
for (String token : tokens) {
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
if (cookieKeyValue[0].equals("JWTToken")) {
Expand All @@ -369,7 +378,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure7CookieBas
cookieKeyValue[1],
asymmetricAlgorithmKeyPair.get().getPublic());
ResponseBean<JWTResponseBean> responseBean =
this.getJWTResponseBean(isValid, token);
this.getJWTResponseBean(isValid, token, !isValid);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
Expand All @@ -382,7 +391,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure7CookieBas
libBasedJWTGenerator.getJWTToken_RS256(
JWTUtils.RS256_TOKEN_TO_BE_SIGNED,
asymmetricAlgorithmKeyPair.get().getPrivate());
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
Expand All @@ -409,15 +418,16 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure8CookieBas
LOGGER.error(
asymmetricAlgorithmKeyPair.isPresent() + " " + asymmetricAlgorithmKeyPair.get());
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
if (tokens != null) {
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
if (!isFetch) {
for (String token : tokens) {
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
if (cookieKeyValue[0].equals("JWTToken")) {
boolean isValid =
jwtValidator.jwkKeyHeaderPublicKeyTrustingVulnerableValidator(
cookieKeyValue[1]);
ResponseBean<JWTResponseBean> responseBean =
this.getJWTResponseBean(isValid, token);
this.getJWTResponseBean(isValid, token, !isValid);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
Expand Down Expand Up @@ -445,7 +455,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure8CookieBas
+ JWTUtils.JWT_TOKEN_PERIOD_CHARACTER
+ GENERIC_BASE64_ENCODED_PAYLOAD,
asymmetricAlgorithmKeyPair.get().getPrivate());
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
Expand All @@ -471,7 +481,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure9CookieBas
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM, KeyStrength.HIGH);
LOGGER.error(symmetricAlgorithmKey.isPresent() + " " + symmetricAlgorithmKey.get());
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
if (tokens != null) {
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
if (!isFetch) {
for (String token : tokens) {
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
if (cookieKeyValue[0].equals("JWTToken")) {
Expand All @@ -481,7 +492,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure9CookieBas
symmetricAlgorithmKey.get().getKey(),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
ResponseBean<JWTResponseBean> responseBean =
this.getJWTResponseBean(isValid, token);
this.getJWTResponseBean(isValid, token, !isValid);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
Expand All @@ -495,7 +506,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure9CookieBas
JWTUtils.HS256_TOKEN_TO_BE_SIGNED,
JWTUtils.getBytes(symmetricAlgorithmKey.get().getKey()),
JWTUtils.JWT_HMAC_SHA_256_ALGORITHM);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
Expand All @@ -516,7 +527,8 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure10CookieBa
ParameterBean parameterBean)
throws UnsupportedEncodingException, ServiceApplicationException {
List<String> tokens = parameterBean.getRequestHeadersMap().get("cookie");
if (tokens != null) {
boolean isFetch = Boolean.valueOf(parameterBean.getQueryParamKeyValueMap().get("fetch"));
if (!isFetch) {
for (String token : tokens) {
String[] cookieKeyValue = token.split(JWTUtils.BASE64_PADDING_CHARACTER_REGEX);
if (cookieKeyValue[0].equals("JWTToken")) {
Expand All @@ -530,7 +542,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure10CookieBa
this.jwtValidator.genericJWTTokenValidator(
cookieKeyValue[1], rsaPublicKey, "RS256");
ResponseBean<JWTResponseBean> responseBean =
this.getJWTResponseBean(isValid, token);
this.getJWTResponseBean(isValid, token, !isValid);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList(token + "; httponly"));
Expand All @@ -546,7 +558,7 @@ public ResponseBean<JWTResponseBean> getVulnerablePayloadLevelUnsecure10CookieBa
String token =
libBasedJWTGenerator.getJWTToken_RS256(
JWTUtils.RS256_TOKEN_TO_BE_SIGNED, rsaPrivateKey);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token);
ResponseBean<JWTResponseBean> responseBean = this.getJWTResponseBean(true, token, true);
responseBean
.getResponseHeaders()
.put("Set-Cookie", Arrays.asList("JWTToken=" + token + "; httponly"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ public void setJwtToken(String jwtToken) {
this.jwtToken = jwtToken;
}

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

public void setValid(boolean isValid) {
public void setIsValid(boolean isValid) {
this.isValid = isValid;
}
}
Loading

0 comments on commit db29231

Please sign in to comment.