Skip to content

Commit

Permalink
Merge branch 'release/v8.0.0.M18'
Browse files Browse the repository at this point in the history
  • Loading branch information
nbaars committed Jun 20, 2018
2 parents 9af0054 + c7da546 commit 12123ef
Show file tree
Hide file tree
Showing 29 changed files with 93 additions and 73 deletions.
4 changes: 4 additions & 0 deletions platformQuickStarts/GCP/GKE-Docker/deploy.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CURTAG=webgoat/webgoat-8.0
DEST_TAG=gcr.io/astech-training/raging-wire-webgoat
CLUSTER_NAME=raging-wire-webgoat
PORT_NUM=8080
4 changes: 4 additions & 0 deletions platformQuickStarts/GCP/GKE-Docker/gke-deploy-config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CURTAG=webgoat/webgoat-8.0
DEST_TAG=gcr.io/your-gke-project/your-webgoat-tag
CLUSTER_NAME=your-cluster-name
PORT_NUM=8080
Original file line number Diff line number Diff line change
Expand Up @@ -232,19 +232,19 @@ private void createUserAdminTable(Connection connection) throws SQLException {

// Create the new table
try {
String createTableStatement = "CREATE TABLE user_system_data (" + "userid varchar(5) not null primary key,"
String createTableStatement = "CREATE TABLE user_system_data (" + "userid int not null primary key,"
+ "user_name varchar(12)," + "password varchar(10)," + "cookie varchar(30)" + ")";
statement.executeUpdate(createTableStatement);
} catch (SQLException e) {
System.out.println("Error creating user admin table " + e.getLocalizedMessage());
}

// Populate
String insertData1 = "INSERT INTO user_system_data VALUES ('101','jsnow','passwd1', '')";
String insertData2 = "INSERT INTO user_system_data VALUES ('102','jdoe','passwd2', '')";
String insertData3 = "INSERT INTO user_system_data VALUES ('103','jplane','passwd3', '')";
String insertData4 = "INSERT INTO user_system_data VALUES ('104','jeff','jeff', '')";
String insertData5 = "INSERT INTO user_system_data VALUES ('105','dave','dave', '')";
String insertData1 = "INSERT INTO user_system_data VALUES (101,'jsnow','passwd1', '')";
String insertData2 = "INSERT INTO user_system_data VALUES (102,'jdoe','passwd2', '')";
String insertData3 = "INSERT INTO user_system_data VALUES (103,'jplane','passwd3', '')";
String insertData4 = "INSERT INTO user_system_data VALUES (104,'jeff','jeff', '')";
String insertData5 = "INSERT INTO user_system_data VALUES (105,'dave','passW0rD', '')";
statement.executeUpdate(insertData1);
statement.executeUpdate(insertData2);
statement.executeUpdate(insertData3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class UserForm {

@NotNull
@Size(min=6, max=20)
@Pattern(regexp = "[a-zA-Z0-9]*", message = "can only contain letters and digits")
@Pattern(regexp = "[a-zA-Z0-9-]*", message = "can only contain letters, digits, and -")
private String username;
@NotNull
@Size(min=6, max=10)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ define(['jquery',
this.listenTo(this.lessonHintView, 'hints:hideButton', this.onHideHintsButton);
this.lessonContentView.navToPage(pageNum);
this.lessonHintView.hideHints();
this.lessonHintView.showFirstHint();
//this.lessonHintView.selectHints();
this.titleView.render(this.lessonInfoModel.get('lessonTitle'));
return;
Expand Down Expand Up @@ -160,7 +161,7 @@ define(['jquery',
}
//
this.lessonHintView.render();
if (this.lessonHintView.getHintsCount > 0) {
if (this.lessonHintView.getHintsCount() > 0) {
this.helpControlsView.showHintsButton();
} else {
this.helpControlsView.hideHintsButton();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ define(['jquery',
}
this.set('content',content);
this.set('lessonUrl',document.URL.replace(/\.lesson.*/,'.lesson'));
this.set('pageNum',document.URL.replace(/.*\.lesson\/(\d{1,4})$/,'$1'));
if (/.*\.lesson\/(\d{1,4})$/.test(document.URL)) {
this.set('pageNum',document.URL.replace(/.*\.lesson\/(\d{1,4})$/,'$1'));
} else {
this.set('pageNum',0);
}
this.trigger('content:loaded',this,loadHelps);
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,19 @@ function($,

toggleLabel: function() {
if (this.isVisible()) {
$('show-hints-button').text('Hide hints');
$('#show-hints-button').text('Hide hints');
} else {
$('show-hints-button').text('Show hints');
$('#show-hints-button').text('Show hints');
}
},

render:function() {
if (this.isVisible()) {
this.$el.hide(350);
this.$el.hide(350, this.toggleLabel.bind(this));
} else if (this.hintsToShow.length > 0) {
this.$el.show(350);
this.$el.show(350, this.toggleLabel.bind(this));
}

this.toggleLabel()

if (this.hintsToShow.length > 0) {
this.hideShowPrevNextButtons();
}
Expand Down Expand Up @@ -90,9 +88,9 @@ function($,

hideHints: function() {
if (this.$el.is(':visible')) {
this.$el.hide(350);
this.$el.hide(350, this.toggleLabel.bind(this));
}
},
},

showNextHint: function() {
this.curHint = (this.curHint < this.hintsToShow.length -1) ? this.curHint+1 : this.curHint;
Expand All @@ -106,6 +104,12 @@ function($,
this.displayHint(this.curHint);
},

showFirstHint: function() {
this.curHint = 0;
this.hideShowPrevNextButtons();
this.displayHint(this.curHint);
},

displayHint: function(curHint) {
if(this.hintsToShow.length == 0) {
// this.hideHints();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@
<section class="main-content-wrapper">
<section id="main-content"> <!--ng-controller="goatLesson"-->
<div id="lesson-page" class="pages">
<span th:text="${numUsers}"> Users in WebGoat</span>
<!-- iterate over users below -->su
<span th:text="${numUsers}"></span>
<span> Users in WebGoat</span>

<div sec:authorize="hasAuthority('WEBGOAT_ADMIN')">
<h3>WebGoat Users</h3>
<div th:each="user : ${allUsers}">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@

import static org.springframework.http.MediaType.ALL_VALUE;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.*;

import static org.springframework.web.bind.annotation.RequestMethod.GET;

Expand All @@ -72,20 +69,19 @@ public class StoredXssComments extends AssignmentEndpoint {
comments.add(new Comment("secUriTy", DateTime.now().toString(fmt), "<script>console.warn('unit test me')</script>Comment for Unit Testing"));
comments.add(new Comment("webgoat", DateTime.now().toString(fmt), "This comment is safe"));
comments.add(new Comment("guest", DateTime.now().toString(fmt), "This one is safe too."));
comments.add(new Comment("guest", DateTime.now().toString(fmt), "Can you post a comment, calling webgoat.customjs.phoneHome() ?"));
comments.add(new Comment("guest", DateTime.now().toString(fmt), "Can you post a comment, calling webgoat.customjs.phoneHome() ?"));
}

@RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE,consumes = ALL_VALUE)
@ResponseBody
public Collection<Comment> retrieveComments() {
Collection<Comment> allComments = Lists.newArrayList();
List<Comment> allComments = Lists.newArrayList();
Collection<Comment> newComments = userComments.get(webSession.getUserName());
allComments.addAll(comments);
if (newComments != null) {
allComments.addAll(newComments);
}

allComments.addAll(comments);

Collections.reverse(allComments);
return allComments;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ xss-reflected-5a-failure=Try again. We do want to see this specific javascript (
xss-reflected-5b-success=Correct ... because <ul><li>The script was not triggered by the URL/QueryString</li><li>Even if you use the attack URL in a new tab, it won't execute (becuase of response type). Try it if you like.</li></ul>
xss-reflected-5b-failure=Nope, pretty easy to guess now though.
xss-reflected-6a-success=Correct! Now, see if you can send in an exploit to that route in the next assignment.
xss-reflected-6a-failure=No, look at the example. Check the GoatRouter.js file. It should be pretty easy to determine.
xss-reflected-6a-failure=No, look at the example. Check the <a href="/WebGoat/js/goatApp/view/GoatRouter.js" target="_blank">GoatRouter.js</a> file. It should be pretty easy to determine.
xss.lesson1.failure=Are you sure? Try using a tab from a different site.
xss-dom-message-success=Correct, I hope you didn't cheat, using the console!
xss-dom-message-failure=Incorrect, keep trying. It should be obvious in the log when you are successful.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ You should have been able to execute script with the last example. At this point

Why is that?

That is because there is no link that would tigger that XSS.
That is because there is no link that would trigger that XSS.
You can try it yourself to see what happens ... go to (substitute localhost with your server's name or IP if you need to):

link: http://localhost:8080/WebGoat/CrossSiteScripting/attack5a?QTY1=1&QTY2=1&QTY3=1&QTY4=1&field1=<script>alert('myjavascripthere')</script>4128+3214+0002+1999&field2=111
link: http://localhost:8080/WebGoat/CrossSiteScripting/attack5a?QTY1=1&QTY2=1&QTY3=1&QTY4=1&field1=<script>alert('my%20javascript%20here')</script>4128+3214+0002+1999&field2=111
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
== Ientify Potential for DOM-Based XSS
== Identify Potential for DOM-Based XSS

DOM-Based XSS can usually be found by looking for the route configurations in the client-side code.
Look for a route that takes inputs that you can ID being 'reflected' to the page.
Look for a route that takes inputs that are being 'reflected' to the page.

For this example, you'll want to look for some 'test' code in the route handlers (WebGoat uses backbone as its primary javascript library).
Sometimes, test code gets left in production (and often times test code is very simple and lacks security or any quality controls!).

Your objective is to find the route and exploit it. First though ... what is the base route? As an example, look at the URL for this lesson ...
it should look something like /WebGoat/start.mvc#lesson/CrossSiteScripting.lesson/5 (although maybe slightly different). The 'base route' in this case is:
it should look something like /WebGoat/start.mvc#lesson/CrossSiteScripting.lesson/9. The 'base route' in this case is:
*start.mvc#lesson/*
The *CrossSiteScripting.lesson/9* after that are parameters that are processed by the javascript route handler.

The *CrossSiteScripting.lesson/#* after that are parameters that are processed by javascript route handler.

So, what is test route for this test code?
So, what is the route for the test code that stayed in the app during production?
To answer this question, you have to check the javascript source.
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ The function you want to execute is ...

Sure, you could just use console/debug to trigger it, but you need to trigger it via a URL in a new tab.

Once you do trigger it, a subsequent response will come to the browser with a random number. Put that random number in below.
Once you do trigger it, a subsequent response will come to your browser's console with a random number. Put that random number in below.
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ public AttackResult flag(@RequestParam("confirmFlagVal") String flag) {

private boolean hostOrRefererDifferentHost(HttpServletRequest request) {
String referer = request.getHeader("referer");
String origin = request.getHeader("origin");
String host = request.getHeader("host");
if (referer != null) {
return !referer.contains(origin);
return !referer.contains(host);
} else {
return true; //this case referer is null or origin does not matter we cannot compare so we return true which should of course be false
return true;
}
}

Expand Down
2 changes: 1 addition & 1 deletion webgoat-lessons/csrf/src/main/resources/html/CSRF.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
action="/WebGoat/csrf/basic-get-flag"
enctype="application/json;charset=UTF-8">
<input name="csrf" type="hidden" value="false"/>
<input type="submit" name="ubmit="/>
<input type="submit" name="submit"/>

</form>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ the activities of the user.
image::images/login-csrf.png[caption="Figure: ", title="Login CSRF from Robust Defenses for Cross-Site Request Forgery", width="800", height="500", style="lesson-image" link="http://seclab.stanford.edu/websec/csrf/csrf.pdf"]

{blank}
For more information read the following http://seclab.stanford.edu/websec/csrf/csrf.pdf[paper]
For more information read the following http://seclab.stanford.edu/websec/csrf/csrf.pdf[paper].

In this assignment try to see if WebGoat is also vulnerable for a login CSRF attack. First create a user
based on your own username prefixed with csrf. So if your username is `tom` you must create
a new user called `csrf-tom`
In this assignment try to see if WebGoat is also vulnerable for a login CSRF attack.
Leave this tab open and in another tab create a user based on your own username prefixed with `csrf-`.
So if your username is `tom` you must create a new user called `csrf-tom`.

Login as the new user. This is what an attacker would do using CSRF. Then click the button in the original tab.
Because you are logged in as a different user, the attacker learns that you clicked the button.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public void csrfAttack() throws Exception {
mockMvc.perform(post("/csrf/feedback/message")
.contentType(MediaType.TEXT_PLAIN)
.cookie(new Cookie("JSESSIONID", "test"))
.header("origin", "localhost:8080")
.header("host", "localhost:8080")
.header("referer", "webgoat.org")
.content("{\"name\": \"Test\", \"email\": \"[email protected]\", \"subject\": \"service\", \"message\":\"dsaffd\"}"))
.andExpect(jsonPath("lessonCompleted", is(true)))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.owasp.webgoat.plugin;

import com.google.common.collect.Lists;
import io.jsonwebtoken.impl.TextCodec;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
Expand All @@ -23,7 +24,7 @@
@AssignmentHints({"jwt-secret-hint1", "jwt-secret-hint2", "jwt-secret-hint3"})
public class JWTSecretKeyEndpoint extends AssignmentEndpoint {

public static final String JWT_SECRET = "victory";
public static final String JWT_SECRET = TextCodec.BASE64.encode("victory");
private static final String WEBGOAT_USER = "WebGoat";
private static final List<String> expectedClaims = Lists.newArrayList("iss", "iat", "exp", "aud", "sub", "username", "Email", "Role");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.impl.TextCodec;
import org.apache.commons.lang3.StringUtils;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
Expand All @@ -25,7 +26,6 @@
import java.time.Instant;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static java.util.Comparator.comparingLong;
import static java.util.Optional.ofNullable;
Expand All @@ -39,7 +39,7 @@
@AssignmentHints({"jwt-change-token-hint1", "jwt-change-token-hint2", "jwt-change-token-hint3", "jwt-change-token-hint4", "jwt-change-token-hint5"})
public class JWTVotesEndpoint extends AssignmentEndpoint {

public static final String JWT_PASSWORD = "victory";
public static final String JWT_PASSWORD = TextCodec.BASE64.encode("victory");
private static String validUsers = "TomJerrySylvester";

private static int totalVotes = 38929;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ whether the location is still the same if not revoke all the tokens and let the
=== Need for refresh tokens

Does it make sense to use a refresh token in a modern single page application (SPA)? As we have seen in the section
about storing tokens there are two option: web storage or a cookie which mean a refresh token is right beside an
access token, so if the access token is leaked changes are the refresh token will also be compromised. Most of the time
there is a difference of course, the access token is send when you make an API call, the refresh token is only send
about storing tokens there are two options: web storage or a cookie which mean a refresh token is right beside an
access token, so if the access token is leaked chances are the refresh token will also be compromised. Most of the time
there is a difference of course. The access token is sent when you make an API call, the refresh token is only sent
when a new access token should be obtained, which in most cases is a different endpoint. If you end up on the same
server you can chose to only use the access token.
server you can choose to only use the access token.

As stated above using an access token and a separate refresh token gives some leverage for the server not to check
the access token over and over. Only perform the check when the user needs a new access token.
It is certainly possible to only use an access token, at the server you store the exact same information you would
It is certainly possible to only use an access token. At the server you store the exact same information you would
store for a refresh token, see previous paragraph. This way you need to check the token each time but this might
be suitable depending on the application. In the case the refresh tokens are stored for validation it is important to protect these tokens as well (at least
use a hash function to store them in your database).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ dictionary attack is not feasible. Once you have a token you can start an offlin
Given we have the following token try to find out secret key and submit a new key with the userId changed to WebGoat.

```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5jb20iLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQuY29tIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.m-jSyfYEsVzD3CBI6N39wZ7AcdKdp_GiO7F_Ym12u-0
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5jb20iLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQuY29tIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.vPe-qQPOt78zK8wrbN1TjNJj3LeX9Qbch6oo23RUJgM
```
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
@AssignmentPath("/access-control/user-hash")
@AssignmentHints({"access-control.hash.hint1","access-control.hash.hint2","access-control.hash.hint3",
"access-control.hash.hint4","access-control.hash.hint5","access-control.hash.hint6","access-control.hash.hint7",
"access-control.hash.hint8","access-control.hash.hint9"})
"access-control.hash.hint8","access-control.hash.hint9","access-control.hash.hint10","access-control.hash.hint11","access-control.hash.hint12"})
public class MissingFunctionACYourHash extends AssignmentEndpoint {

@Autowired
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ protected HashMap<Integer, HashMap> getUsers (HttpServletRequest req) {
userMap.put("cc", results.getString(3));
userMap.put("ccType", results.getString(4));
userMap.put("cookie", results.getString(5));
userMap.put("loginCOunt",Integer.toString(results.getInt(6)));
userMap.put("loginCount",Integer.toString(results.getInt(6)));
allUsersMap.put(id,userMap);
}
userSessionData.setValue("allUsers",allUsersMap);
Expand Down
Loading

0 comments on commit 12123ef

Please sign in to comment.