Skip to content

Commit

Permalink
More JWT work
Browse files Browse the repository at this point in the history
  • Loading branch information
nbaars committed May 23, 2018
1 parent 7a0820b commit 9d7886d
Show file tree
Hide file tree
Showing 13 changed files with 354 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,39 @@ private void createServersTable(Connection connection) throws SQLException {
}
}

/**
* Description of the Method
*
* @param connection Description of the Parameter
* @throws SQLException Description of the Exception
*/
private void createJWTKeys(Connection connection) throws SQLException {
Statement statement = connection.createStatement();

// Drop servers table
try {
String dropTable = "DROP TABLE jwt_keys";
statement.executeUpdate(dropTable);
} catch (SQLException e) {
System.out.println("Info - Could not drop jwtkeys table");
}

// Create the new table
try {
String createTableStatement = "CREATE TABLE jwt_keys"
+ " (" + "id varchar(10),"
+ "key varchar(20))";
statement.executeUpdate(createTableStatement);

String insertData1 = "INSERT INTO jwt_keys VALUES ('webgoat_key', 'qwertyqwerty1234')";
String insertData2 = "INSERT INTO jwt_keys VALUES ('webwolf_key', 'doesnotreallymatter')";
statement.executeUpdate(insertData1);
statement.executeUpdate(insertData2);
} catch (SQLException e) {
System.out.println("Error creating product table " + e.getLocalizedMessage());
}
}


/**
* Description of the Method
Expand Down Expand Up @@ -975,6 +1008,7 @@ public void makeDB(Connection connection) throws SQLException {
createTanTable(connection);
createMFEImagesTable(connection);
createModifyWithSQLLessonTable(connection);
createJWTKeys(connection);
System.out.println("Success: creating tables.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package org.owasp.webgoat.plugin;

import com.google.common.base.Charsets;
import io.jsonwebtoken.*;
import org.apache.commons.lang3.StringUtils;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.WebSession;
import org.springframework.beans.factory.annotation.Autowired;
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 java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
* @author nbaars
* @since 4/23/17.
*/
@AssignmentPath("/JWT/final")
@AssignmentHints({"jwt-final-hint1", "jwt-final-hint2", "jwt-final-hint3", "jwt-final-hint4", "jwt-final-hint5", "jwt-final-hint6"})
public class JWTFinalEndpoint extends AssignmentEndpoint {

@Autowired
private WebSession webSession;

@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 trackProgress(failed().feedback("jwt-invalid-token").build());
} else {
try {
final String[] errorMessage = {null};
Jwt jwt = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
@Override
public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
final String kid = (String) header.get("kid");
try {
Connection connection = DatabaseUtilities.getConnection(webSession);
ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = " + kid);
while (rs.next()) {
return rs.getString(1).getBytes(Charsets.UTF_8);
}
} catch (SQLException e) {
errorMessage[0] = e.getMessage();
}
return null;
}
}).parse(token);
if (errorMessage[0] != null) {
return trackProgress(failed().output(errorMessage[0]).build());
}
Claims claims = (Claims) jwt.getBody();
String username = (String) claims.get("username");
if ("Jerry".equals(username)) {
return trackProgress(failed().feedback("jwt-final-jerry-account").build());
}
if ("Tom".equals(username)) {
return trackProgress(success().build());
} else {
return trackProgress(failed().feedback("jwt-final-not-tom").build());
}
} catch (JwtException e) {
return trackProgress(failed().feedback("jwt-invalid-token").output(e.toString()).build());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.owasp.webgoat.plugin.refresh;

public class RefreshEndpoint {

private static final String TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0OTUyODU3NDUsImV4cCI6MTQ5NTI4NTc0NSwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJuYW1lIjoiVG9tIiwiZW1haWwiOiJ0b21Ad2ViZ29hdC5jb20iLCJyb2xlIjoiQ2F0In0.NTd3E17JZlVKZk52Wq_AWZ0RDafV5KDRMuJner_zUn4";
private static final String JWT_KEY = "qwertyuiopasdfghjklzxcvbnm123456";


}
104 changes: 104 additions & 0 deletions webgoat-lessons/jwt/src/main/resources/css/jwt.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,108 @@ a.list-group-item.active small {
}
.img-responsive {
min-width: 100%;
}


.card {
font-size: 1em;
overflow: hidden;
padding: 0;
border: none;
border-radius: .28571429rem;
box-shadow: 0 1px 3px 0 #d4d4d5, 0 0 0 1px #d4d4d5;
}

.card-block {
font-size: 1em;
position: relative;
margin: 0;
padding: 1em;
border: none;
border-top: 1px solid rgba(34, 36, 38, .1);
box-shadow: none;
}

.card-img-top {
display: block;
width: 100%;
height: auto;
}

.card-title {
font-size: 1.28571429em;
font-weight: 700;
line-height: 1.2857em;
}

.card-text {
clear: both;
margin-top: .5em;
color: rgba(0, 0, 0, .68);
}

.card-footer {
font-size: 1em;
position: static;
top: 0;
left: 0;
max-width: 100%;
padding: .75em 1em;
color: rgba(0, 0, 0, .4);
border-top: 1px solid rgba(0, 0, 0, .05) !important;
background: #fff;
}

.card-inverse .btn {
border: 1px solid rgba(0, 0, 0, .05);
}

.profile {
position: absolute;
top: -12px;
display: inline-block;
overflow: hidden;
box-sizing: border-box;
width: 50px;
height: 50px;
margin: 0;
border: 1px solid #fff;
border-radius: 50%;
}

.profile-avatar {
display: block;
width: 100%;
height: auto;
border-radius: 50%;
}

.profile-inline {
position: relative;
top: 0;
display: inline-block;
}

.profile-inline ~ .card-title {
display: inline-block;
margin-left: 4px;
vertical-align: top;
}

.text-bold {
font-weight: 700;
}

.meta {
font-size: 1em;
color: rgba(0, 0, 0, .4);
}

.meta a {
text-decoration: none;
color: rgba(0, 0, 0, .4);
}

.meta a:hover {
color: rgba(0, 0, 0, .87);
}
123 changes: 88 additions & 35 deletions webgoat-lessons/jwt/src/main/resources/html/JWT.html
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@ <h3>Vote for your favorite</h3>
</div>

<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:JWT_refresh_assignment"></div>
<div class="adoc-content" th:replace="doc:JWT_refresh_assignment.adoc"></div>

<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/jwt.css}"/>
<script th:src="@{/lesson_js/bootstrap.min.js}" language="JavaScript"></script>
<script th:src="@{/lesson_js/jwt-signing.js}" language="JavaScript"></script>
<script th:src="@{/lesson_js/jwt-final.js}" language="JavaScript"></script>
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
Expand All @@ -119,44 +119,97 @@ <h3>Vote for your favorite</h3>
action="/WebGoat/JWT/refresh/reset"
enctype="application/json;charset=UTF-8">
<div class="container-fluid">

<div class="row">

<div class="well">
<div class="pull-right">
<div class="dropdown">
<button type="button" data-toggle="dropdown" class="btn btn-default dropdown-toggle"
title="Change user">
<i class="fa fa-user"></i> <span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-left">
<li role="presentation"><a role="menuitem" tabindex="-1"
onclick="javascript:login('Guest')"
th:text="Guest">current</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1"
onclick="javascript:login('Tom')"
th:text="Tom">current</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1"
onclick="javascript:login('Jerry')"
th:text="Jerry">current</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1"
onclick="javascript:login('Sylvester')"
th:text="Sylvester">current</a></li>
</ul>
<button type="button" class="btn btn-default fa fa-refresh" title="Refresh votes"
onclick="javascript:getVotings()"/>
<button type="submit" class="btn btn-default fa fa-trash-o" title="Reset votes"/>
<div class="col-sm-6 col-md-4 col-lg-3 mt-4">
<div class="card card-inverse card-info">
<img th:src="@{/images/jerry.png}" class="card-img-top"></img>
<div class="card-block">
<figure class="profile profile-inline">
<img th:src="@{/images/jerry.png}" class="profile-avatar" alt=""></img>
</figure>
<h4 class="card-title">Jerry</h4>
<div class="card-text">
Jerry is a small, brown, house mouse.
</div>
<div>
<p class="text-right">Welcome back, <b><span id="name"></span></b></p>
</div>
<div class="card-footer">
<small>Last updated 12 minutes ago</small>
<button class="btn btn-info float-right btn-sm">Follow</button>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 col-lg-3 mt-4">
<div class="card card-inverse card-info">
<img th:src="@{/images/tom.png}" class="card-img-top"></img>
<div class="card-block">
<figure class="profile profile-inline">
<img th:src="@{/images/tom.png}" class="profile-avatar" alt=""></img>
</figure>
<h4 class="card-title">Tom</h4>
<div class="card-text">
Tom is a grey and white domestic short hair cat.
</div>
</div>

<div>
<h3>Vote for your favorite</h3>
<div class="card-footer">
<small>Last updated 12 days ago</small>
<button class="btn btn-info float-right btn-sm">Follow</button>
</div>
<div id="votesList" class="list-group">
</div>
</div>
</div>
</form>

<br/>
<div class="attack-feedback"></div>
<div class="attack-output"></div>
</div>
</div>

<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:JWT_final.adoc"></div>

<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/jwt.css}"/>
<script th:src="@{/lesson_js/bootstrap.min.js}" language="JavaScript"></script>
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST"
action="/WebGoat/JWT/final/delete?token=eyJ0eXAiOiJKV1QiLCJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8"
enctype="application/json;charset=UTF-8">
<div class="container-fluid">
<div class="col-sm-6 col-md-4 col-lg-3 mt-4">
<div class="card card-inverse card-info">
<img th:src="@{/images/jerry.png}" class="card-img-top"></img>
<div class="card-block">
<figure class="profile profile-inline">
<img th:src="@{/images/jerry.png}" class="profile-avatar" alt=""></img>
</figure>
<h4 class="card-title">Jerry</h4>
<div class="card-text">
Jerry is a small, brown, house mouse.
</div>
</div>
<div class="card-footer">
<small>Last updated 12 minutes ago</small>
<button class="btn btn-info float-right btn-sm">Delete</button>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 col-lg-3 mt-4">
<div class="card card-inverse card-info">
<img th:src="@{/images/tom.png}" class="card-img-top"></img>
<div class="card-block">
<figure class="profile profile-inline">
<img th:src="@{/images/tom.png}" class="profile-avatar" alt=""></img>
</figure>
<h4 class="card-title">Tom</h4>
<div class="card-text">
Tom is a grey and white domestic short hair cat.
</div>
</div>
<div class="card-footer">
<small>Last updated 12 days ago</small>
<button class="btn btn-info float-right btn-sm" onclick="javascript:follow('Tom')">Follow</button>
<button class="btn btn-info float-right btn-sm">Delete</button>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 9d7886d

Please sign in to comment.