diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/jwt/JWTFinalEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/jwt/JWTFinalEndpoint.java index 3bbe8ed62..44d19a1f2 100644 --- a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/jwt/JWTFinalEndpoint.java +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/jwt/JWTFinalEndpoint.java @@ -22,24 +22,34 @@ package org.owasp.webgoat.jwt; -import io.jsonwebtoken.*; -import io.jsonwebtoken.impl.TextCodec; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.sql.ResultSet; +import java.sql.SQLException; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.sql.DataSource; + import org.apache.commons.lang3.StringUtils; import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentHints; import org.owasp.webgoat.assignments.AttackResult; import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; -import javax.servlet.http.HttpServletRequest; -import javax.sql.DataSource; - -import java.nio.charset.Charset; -import java.security.NoSuchAlgorithmException; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Base64; -import java.util.Random; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.JwsHeader; +import io.jsonwebtoken.Jwt; +import io.jsonwebtoken.JwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SigningKeyResolverAdapter; +import io.jsonwebtoken.impl.TextCodec; /** *
@@ -81,17 +91,54 @@ public class JWTFinalEndpoint extends AssignmentEndpoint { @RequestParam("jsonPayload") String jsonPayload, @RequestParam("jsonSecret") String jsonSecret) throws NoSuchAlgorithmException { - String header = Base64.getUrlEncoder().encodeToString(jsonHeader.getBytes(Charset.defaultCharset())); - String body = Base64.getUrlEncoder().encodeToString(jsonPayload.getBytes(Charset.defaultCharset())); - String signature = ""; - return "{\"header\":\""+header+"\",\"payload\":\""+body+"\",\"secret\":\""+signature+"\"}"; + //System.out.println(jsonHeader); + //System.out.println(jsonPayload); + String encodedHeader; + String encodedPayload; + String encodedSignature; + try { + encodedHeader = TextCodec.BASE64URL.encode(jsonHeader); + encodedPayload = TextCodec.BASE64URL.encode(jsonPayload); + if (jsonHeader.toLowerCase().contains("none")) { + encodedSignature=""; + } else { + encodedSignature = TextCodec.BASE64URL.encode(getJWTSignature(jsonHeader, encodedHeader, encodedPayload, jsonSecret)); + } + } catch (Exception e) { + encodedHeader=""; + encodedPayload="signature type not supported in this tool, try jwt.io"; + encodedSignature = ""; + } + String result = "{\"encodedHeader\":\""+encodedHeader+"\",\"encodedPayload\":\""+encodedPayload+"\",\"encodedSignature\":\""+encodedSignature+"\"}"; + //System.out.println(result); + return result; + } + + private byte[] getJWTSignature(String jsonHeader, String encodedHeader, String encodedPayload, String jsonSecret) throws NoSuchAlgorithmException, InvalidKeyException { + String message = encodedHeader+"."+encodedPayload; + String algorithm = "HmacSHA256"; + if (jsonHeader.equals("HS512")) { + algorithm = "HmacSHA512"; + } + Mac macInstance = Mac.getInstance(algorithm); + SecretKeySpec secret_key = new SecretKeySpec(TextCodec.BASE64.decode(jsonSecret), algorithm); + macInstance.init(secret_key); + + return macInstance.doFinal(message.getBytes(StandardCharsets.UTF_8)); } - @PostMapping(path="/JWT/decode",produces=MediaType.APPLICATION_JSON_VALUE) + @PostMapping(path="/JWT/decode",produces=MediaType.TEXT_HTML_VALUE) @ResponseBody - public String decode(@RequestParam("token") String token) throws NoSuchAlgorithmException { - - return new String(Base64.getUrlDecoder().decode(token.getBytes(Charset.defaultCharset()))); + public String decode(@RequestParam("jwtToken") String jwtToken) throws NoSuchAlgorithmException { + try { + String encodedHeader = jwtToken.substring(0, jwtToken.indexOf(".")); + String encodedPayload = jwtToken.substring(jwtToken.indexOf(".")+1, jwtToken.lastIndexOf(".")); + String jsonHeader = TextCodec.BASE64URL.decodeToString(encodedHeader); + String jsonPayload = TextCodec.BASE64URL.decodeToString(encodedPayload); + return "{\"jsonHeader\":\""+jsonHeader.replace("\"", "\\\"")+"\",\"jsonPayload\":\""+jsonPayload.replace("\"", "\\\"").replace("\t","").replace("\r", "").replace("\n", "")+"\"}"; + } catch (Exception e) { + return "{\"jsonHeader\":\"\",\"jsonPayload\":\"\"}"; + } } @PostMapping("/JWT/final/follow/{user}") diff --git a/webgoat-lessons/jwt/src/main/resources/html/JWT.html b/webgoat-lessons/jwt/src/main/resources/html/JWT.html index a75f170aa..01303ea3d 100644 --- a/webgoat-lessons/jwt/src/main/resources/html/JWT.html +++ b/webgoat-lessons/jwt/src/main/resources/html/JWT.html @@ -20,22 +20,41 @@ $(document).ready(- ++
+ ++ JWT header: + JWT payload: + + + . + encryption key: + @@ -318,10 +337,37 @@ $(document).ready(