feat: implement JWT jku example (#1552)

Closes #1539
This commit is contained in:
Nanne Baars
2023-08-08 17:18:22 +02:00
committed by GitHub
parent 8f6e47e6d4
commit a9b1fd66b8
16 changed files with 544 additions and 32 deletions

View File

@ -0,0 +1,70 @@
package org.owasp.webgoat.lessons.jwt.claimmisuse;
import com.auth0.jwk.JwkException;
import com.auth0.jwk.JwkProvider;
import com.auth0.jwk.JwkProviderBuilder;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.interfaces.RSAPublicKey;
import org.apache.commons.lang3.StringUtils;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/JWT/jku")
@RestController
@AssignmentHints({
"jwt-jku-hint1",
"jwt-jku-hint2",
"jwt-jku-hint3",
"jwt-jku-hint4",
"jwt-jku-hint5"
})
public class JWTHeaderJKUEndpoint extends AssignmentEndpoint {
@PostMapping("/follow/{user}")
public @ResponseBody String follow(@PathVariable("user") String user) {
if ("Jerry".equals(user)) {
return "Following yourself seems redundant";
} else {
return "You are now following Tom";
}
}
@PostMapping("/delete")
public @ResponseBody AttackResult resetVotes(@RequestParam("token") String token) {
if (StringUtils.isEmpty(token)) {
return failed(this).feedback("jwt-invalid-token").build();
} else {
try {
var decodedJWT = JWT.decode(token);
var jku = decodedJWT.getHeaderClaim("jku");
JwkProvider jwkProvider = new JwkProviderBuilder(new URL(jku.asString())).build();
var jwk = jwkProvider.get(decodedJWT.getKeyId());
var algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey());
JWT.require(algorithm).build().verify(decodedJWT);
String username = decodedJWT.getClaims().get("username").asString();
if ("Jerry".equals(username)) {
return failed(this).feedback("jwt-final-jerry-account").build();
}
if ("Tom".equals(username)) {
return success(this).build();
} else {
return failed(this).feedback("jwt-final-not-tom").build();
}
} catch (MalformedURLException | JWTVerificationException | JwkException e) {
return failed(this).feedback("jwt-invalid-token").output(e.toString()).build();
}
}
}
}

View File

@ -20,7 +20,7 @@
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
*/
package org.owasp.webgoat.lessons.jwt;
package org.owasp.webgoat.lessons.jwt.claimmisuse;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwsHeader;
@ -38,28 +38,30 @@ import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@AssignmentHints({
"jwt-final-hint1",
"jwt-final-hint2",
"jwt-final-hint3",
"jwt-final-hint4",
"jwt-final-hint5",
"jwt-final-hint6"
"jwt-kid-hint1",
"jwt-kid-hint2",
"jwt-kid-hint3",
"jwt-kid-hint4",
"jwt-kid-hint5",
"jwt-kid-hint6"
})
public class JWTFinalEndpoint extends AssignmentEndpoint {
@RequestMapping("/JWT/kid")
public class JWTHeaderKIDEndpoint extends AssignmentEndpoint {
private final LessonDataSource dataSource;
private JWTFinalEndpoint(LessonDataSource dataSource) {
private JWTHeaderKIDEndpoint(LessonDataSource dataSource) {
this.dataSource = dataSource;
}
@PostMapping("/JWT/final/follow/{user}")
@PostMapping("/follow/{user}")
public @ResponseBody String follow(@PathVariable("user") String user) {
if ("Jerry".equals(user)) {
return "Following yourself seems redundant";
@ -68,7 +70,7 @@ public class JWTFinalEndpoint extends AssignmentEndpoint {
}
}
@PostMapping("/JWT/final/delete")
@PostMapping("/delete")
public @ResponseBody AttackResult resetVotes(@RequestParam("token") String token) {
if (StringUtils.isEmpty(token)) {
return failed(this).feedback("jwt-invalid-token").build();