diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFConfirmFlag1.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFConfirmFlag1.java index 6ec24f9f2..03ca8d239 100644 --- a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFConfirmFlag1.java +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFConfirmFlag1.java @@ -17,7 +17,7 @@ import javax.servlet.http.HttpServletRequest; */ @AssignmentPath("/csrf/confirm-flag-1") -@AssignmentHints({""}) +@AssignmentHints({"csrf-get.hint1","csrf-get.hint2","csrf-get.hint3","csrf-get.hint4"}) public class CSRFConfirmFlag1 extends AssignmentEndpoint { @Autowired @@ -25,15 +25,11 @@ public class CSRFConfirmFlag1 extends AssignmentEndpoint { @PostMapping(produces = {"application/json"}) public @ResponseBody AttackResult completed(String confirmFlagVal) { -// String host = (req.getHeader("host") == null) ? "NULL" : req.getHeader("host"); -// String origin = (req.getHeader("origin") == null) ? "NULL" : req.getHeader("origin"); -// Integer serverPort = (req.getServerPort() < 1) ? 0 : req.getServerPort(); -// String serverName = (req.getServerName() == null) ? "NULL" : req.getServerName(); -// String referer = (req.getHeader("referer") == null) ? "NULL" : req.getHeader("referer"); - if (confirmFlagVal.equals(userSessionData.getValue("csrf-get-success"))) { - return success().feedback("csrf-get-success").output("Correct, the flag was " + userSessionData.getValue("csrf-get-success")).build(); + if (confirmFlagVal.equals(userSessionData.getValue("csrf-get-success").toString())) { + return success().feedback("csrf-get-null-referer.success").output("Correct, the flag was " + userSessionData.getValue("csrf-get-success")).build(); } + return failed().feedback("").build(); } } diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetFlag.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetFlag.java index 9aa681378..56fdde8d6 100644 --- a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetFlag.java +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetFlag.java @@ -14,6 +14,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.Random; /** * Created by jason on 9/30/17. @@ -33,14 +34,15 @@ public class CSRFGetFlag extends Endpoint { Map response = new HashMap<>(); String host = (req.getHeader("host") == null) ? "NULL" : req.getHeader("host"); - String origin = (req.getHeader("origin") == null) ? "NULL" : req.getHeader("origin"); - Integer serverPort = (req.getServerPort() < 1) ? 0 : req.getServerPort(); - String serverName = (req.getServerName() == null) ? "NULL" : req.getServerName(); +// String origin = (req.getHeader("origin") == null) ? "NULL" : req.getHeader("origin"); +// Integer serverPort = (req.getServerPort() < 1) ? 0 : req.getServerPort(); +// String serverName = (req.getServerName() == null) ? "NULL" : req.getServerName(); String referer = (req.getHeader("referer") == null) ? "NULL" : req.getHeader("referer"); String[] refererArr = referer.split("/"); if (referer.equals("NULL") && req.getParameter("csrf").equals("true")) { - userSessionData.setValue("csrf-get-success", Math.floor(Math.random()*100000)); + Random random = new Random(); + userSessionData.setValue("csrf-get-success", random.nextInt(65536)); response.put("success",true); response.put("message",pluginMessages.getMessage("csrf-get-null-referer.success")); response.put("flag",userSessionData.getValue("csrf-get-success")); @@ -49,9 +51,11 @@ public class CSRFGetFlag extends Endpoint { response.put("message", "Appears the request came from the original host"); response.put("flag", null); } else { - response.put("success", false); - response.put("message", "TBD"); - response.put("flag", null); + Random random = new Random(); + userSessionData.setValue("csrf-get-success", random.nextInt(65536)); + response.put("success",true); + response.put("message",pluginMessages.getMessage("csrf-get-other-referer.success")); + response.put("flag",userSessionData.getValue("csrf-get-success")); } return response; diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetXhrFlag.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetXhrFlag.java new file mode 100644 index 000000000..f7f2e246d --- /dev/null +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFGetXhrFlag.java @@ -0,0 +1,69 @@ +package org.owasp.webgoat.plugin; + +import org.owasp.webgoat.assignments.Endpoint; +import org.owasp.webgoat.i18n.PluginMessages; +import org.owasp.webgoat.session.UserSessionData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +/** + * Created by jason on 9/30/17. + */ + +public class CSRFGetXhrFlag extends Endpoint { + + @Autowired + UserSessionData userSessionData; + @Autowired + private PluginMessages pluginMessages; + + @RequestMapping(produces = {"application/json"}, method = RequestMethod.GET) + @ResponseBody + public Map invoke(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + Map response = new HashMap<>(); + + String host = (req.getHeader("host") == null) ? "NULL" : req.getHeader("host"); +// String origin = (req.getHeader("origin") == null) ? "NULL" : req.getHeader("origin"); +// Integer serverPort = (req.getServerPort() < 1) ? 0 : req.getServerPort(); +// String serverName = (req.getServerName() == null) ? "NULL" : req.getServerName(); + String referer = (req.getHeader("referer") == null) ? "NULL" : req.getHeader("referer"); + String[] refererArr = referer.split("/"); + + if (referer.equals("NULL") && req.getParameter("csrf").equals("true")) { + Random random = new Random(); + userSessionData.setValue("csrf-get-success", random.nextInt(65536)); + response.put("success",true); + response.put("message",pluginMessages.getMessage("csrf-get-null-referer.success")); + response.put("flag",userSessionData.getValue("csrf-get-success")); + } else if (refererArr[2].equals(host)) { + response.put("success", false); + response.put("message", "Appears the request came from the original host"); + response.put("flag", null); + } else { + Random random = new Random(); + userSessionData.setValue("csrf-get-success", random.nextInt(65536)); + response.put("success",true); + response.put("message",pluginMessages.getMessage("csrf-get-other-referer.success")); + response.put("flag",userSessionData.getValue("csrf-get-success")); + } + + return response; + + } + + @Override + public String getPath() { + return "/csrf/get-xhr-flag"; + } +} diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/ForgedReviews.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/ForgedReviews.java new file mode 100644 index 000000000..89485a874 --- /dev/null +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/ForgedReviews.java @@ -0,0 +1,139 @@ +/*************************************************************************************************** + * + * + * This file is part of WebGoat, an Open Web Application Security Project utility. For details, + * please see http://www.owasp.org/ + * + * Copyright (c) 2002 - 20014 Bruce Mayhew + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Getting Source ============== + * + * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software + * projects. + * + * For details, please see http://webgoat.github.io + * + * @author Bruce Mayhew WebGoat + * @created October 28, 2003 + */ + +package org.owasp.webgoat.plugin; + +import com.beust.jcommander.internal.Lists; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.EvictingQueue; +import com.google.common.collect.Maps; +import org.apache.catalina.servlet4preview.http.HttpServletRequest; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; +import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentPath; +import org.owasp.webgoat.assignments.AttackResult; +import org.owasp.webgoat.session.WebSession; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.io.IOException; +import java.util.Collection; +import java.util.Map; + +import static org.springframework.http.MediaType.ALL_VALUE; +import static org.springframework.web.bind.annotation.RequestMethod.GET; + +@AssignmentPath("/csrf/review") +public class ForgedReviews extends AssignmentEndpoint { + + @Autowired + private WebSession webSession; + private static DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd, HH:mm:ss"); + + private static final Map> userReviews = Maps.newHashMap(); + private static final EvictingQueue REVIEWS = EvictingQueue.create(100); + private static final String weakAntiCSRF = "2aa14227b9a13d0bede0388a7fba9aa9"; + + + static { + REVIEWS.add(new Review("secUriTy", DateTime.now().toString(fmt), "This is like swiss cheese", 0)); + REVIEWS.add(new Review("webgoat", DateTime.now().toString(fmt), "It works, sorta", 2)); + REVIEWS.add(new Review("guest", DateTime.now().toString(fmt), "Best, App, Ever", 5)); + REVIEWS.add(new Review("guest", DateTime.now().toString(fmt), "This app is so insecure, I didn't even post this review, can you pull that off too?",1)); + } + + @RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE,consumes = ALL_VALUE) + @ResponseBody + public Collection retrieveReviews() { + Collection allReviews = Lists.newArrayList(); + Collection newReviews = userReviews.get(webSession.getUserName()); + if (newReviews != null) { + allReviews.addAll(newReviews); + } + + allReviews.addAll(REVIEWS); + + return allReviews; + } + + @RequestMapping(method = RequestMethod.POST) + @ResponseBody + public AttackResult createNewReview (String reviewText, Integer stars, String validateReq, HttpServletRequest request) throws IOException { + + String host = (request.getHeader("host") == null) ? "NULL" : request.getHeader("host"); +// String origin = (req.getHeader("origin") == null) ? "NULL" : req.getHeader("origin"); +// Integer serverPort = (req.getServerPort() < 1) ? 0 : req.getServerPort(); +// String serverName = (req.getServerName() == null) ? "NULL" : req.getServerName(); + String referer = (request.getHeader("referer") == null) ? "NULL" : request.getHeader("referer"); + String[] refererArr = referer.split("/"); + + EvictingQueue reviews = userReviews.getOrDefault(webSession.getUserName(), EvictingQueue.create(100)); + Review review = new Review(); + + review.setText(reviewText); + review.setDateTime(DateTime.now().toString(fmt)); + review.setUser(webSession.getUserName()); + review.setStars(stars); + + reviews.add(review); + userReviews.put(webSession.getUserName(), reviews); + //short-circuit + if (validateReq == null || !validateReq.equals(weakAntiCSRF)) { + return failed().feedback("csrf-you-forgot-something").build(); + } + //we have the spoofed files + if (referer != "NULL" && refererArr[2].equals(host) ) { + return (failed().feedback("csrf-same-host").build()); + } else { + return (success().feedback("csrf-review.success").build()); //feedback("xss-stored-comment-failure") + } + } + + private Review parseJson(String comment) { + ObjectMapper mapper = new ObjectMapper(); + try { + return mapper.readValue(comment, Review.class); + } catch (IOException e) { + return new Review(); + } + } +} + + + + + diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/Review.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/Review.java new file mode 100644 index 000000000..00f4f0fbc --- /dev/null +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/Review.java @@ -0,0 +1,25 @@ +package org.owasp.webgoat.plugin; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author nbaars + * @since 4/8/17. + */ +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@XmlRootElement +public class Review { + private String user; + private String dateTime; + private String text; + private Integer stars; +} + diff --git a/webgoat-lessons/csrf/src/main/resources/css/reviews.css b/webgoat-lessons/csrf/src/main/resources/css/reviews.css new file mode 100644 index 000000000..3bc2ca4eb --- /dev/null +++ b/webgoat-lessons/csrf/src/main/resources/css/reviews.css @@ -0,0 +1,75 @@ +/* Component: Posts */ +.post .post-heading { + height: 95px; + padding: 20px 15px; +} +.post .post-heading .avatar { + width: 60px; + height: 60px; + display: block; + margin-right: 15px; +} +.post .post-heading .meta .title { + margin-bottom: 0; +} +.post .post-heading .meta .title a { + color: black; +} +.post .post-heading .meta .title a:hover { + color: #aaaaaa; +} +.post .post-heading .meta .time { + margin-top: 8px; + color: #999; +} +.post .post-image .image { + width:20%; + height: 40%; +} +.post .post-description { + padding: 5px; +} +.post .post-footer { + border-top: 1px solid #ddd; + padding: 15px; +} +.post .post-footer .input-group-addon a { + color: #454545; +} +.post .post-footer .comments-list { + padding: 0; + margin-top: 20px; + list-style-type: none; +} +.post .post-footer .comments-list .comment { + display: block; + width: 100%; + margin: 20px 0; +} +.post .post-footer .comments-list .comment .avatar { + width: 35px; + height: 35px; +} +.post .post-footer .comments-list .comment .comment-heading { + display: block; + width: 100%; +} +.post .post-footer .comments-list .comment .comment-heading .user { + font-size: 14px; + font-weight: bold; + display: inline; + margin-top: 0; + margin-right: 10px; +} +.post .post-footer .comments-list .comment .comment-heading .time { + font-size: 12px; + color: #aaa; + margin-top: 0; + display: inline; +} +.post .post-footer .comments-list .comment .comment-body { + margin-left: 50px; +} +.post .post-footer .comments-list .comment > .comments-list { + margin-left: 50px; +} \ No newline at end of file diff --git a/webgoat-lessons/csrf/src/main/resources/html/CSRF.html b/webgoat-lessons/csrf/src/main/resources/html/CSRF.html index 2a9ef3041..53417c6ac 100644 --- a/webgoat-lessons/csrf/src/main/resources/html/CSRF.html +++ b/webgoat-lessons/csrf/src/main/resources/html/CSRF.html @@ -22,14 +22,9 @@ - - -
- -