Refactoring (#1201)

* Some initial refactoring

* Make it one application

* Got it working

* Fix problem on Windows

* Move WebWolf

* Move first lesson

* Moved all lessons

* Fix pom.xml

* Fix tests

* Add option to initialize a lesson

This way we can create content for each user inside a lesson. The initialize method will be called when a new user is created or when a lesson reset happens

* Clean up pom.xml files

* Remove fetching labels based on language.

We only support English at the moment, all the lesson explanations are written in English which makes it very difficult to translate. If we only had labels it would make sense to support multiple languages

* Fix SonarLint issues

* And move it all to the main project

* Fix for documentation paths

* Fix pom warnings

* Remove PMD as it does not work

* Update release notes about refactoring

Update release notes about refactoring

Update release notes about refactoring

* Fix lesson template

* Update release notes

* Keep it in the same repo in Dockerhub

* Update documentation to show how the connection is obtained.

Resolves: #1180

* Rename all integration tests

* Remove command from Dockerfile

* Simplify GitHub actions

Currently, we use a separate actions for pull-requests and branch build.
This is now consolidated in one action.
The PR action triggers always, it now only trigger when the PR is
opened and not in draft.
Running all platforms on a branch build is a bit too much, it is better
 to only run all platforms when someone opens a PR.

* Remove duplicate entry from release notes

* Add explicit registry for base image

* Lesson scanner not working when fat jar

When running the fat jar we have to take into account we
are reading from the jar file and not the filesystem. In
this case you cannot use `getFile` for example.

* added info in README and fixed release docker

* changed base image and added ignore file

Co-authored-by: Zubcevic.com <rene@zubcevic.com>
This commit is contained in:
Nanne Baars
2022-04-09 14:56:12 +02:00
committed by GitHub
parent f3d8206a07
commit 711649924b
1130 changed files with 3540 additions and 7643 deletions

View File

@@ -0,0 +1,47 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2021 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.
*/
package org.owasp.webgoat.lessons.spoofcookie;
import org.owasp.webgoat.container.lessons.Category;
import org.owasp.webgoat.container.lessons.Lesson;
import org.springframework.stereotype.Component;
/***
*
* @author Angel Olle Blazquez
*
*/
@Component
public class SpoofCookie extends Lesson {
@Override
public Category getDefaultCategory() {
return Category.SESSION_MANAGEMENT;
}
@Override
public String getTitle() {
return "spoofcookie.title";
}
}

View File

@@ -0,0 +1,121 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2021 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.
*/
package org.owasp.webgoat.lessons.spoofcookie;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult;
import org.owasp.webgoat.lessons.spoofcookie.encoders.EncDec;
import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/***
*
* @author Angel Olle Blazquez
*
*/
@RestController
public class SpoofCookieAssignment extends AssignmentEndpoint {
private static final String COOKIE_NAME = "spoof_auth";
private static final String COOKIE_INFO = "Cookie details for user %s:<br />" + COOKIE_NAME + "=%s";
private static final String ATTACK_USERNAME = "tom";
private static final Map<String, String> users = Map.of(
"webgoat", "webgoat",
"admin", "admin",
ATTACK_USERNAME, "apasswordfortom");
@PostMapping(path = "/SpoofCookie/login")
@ResponseBody
@ExceptionHandler(UnsatisfiedServletRequestParameterException.class)
public AttackResult login(
@RequestParam String username,
@RequestParam String password,
@CookieValue(value = COOKIE_NAME, required = false) String cookieValue,
HttpServletResponse response) {
if (StringUtils.isEmpty(cookieValue)) {
return credentialsLoginFlow(username, password, response);
} else {
return cookieLoginFlow(cookieValue);
}
}
@GetMapping(path = "/SpoofCookie/cleanup")
public void cleanup(HttpServletResponse response) {
Cookie cookie = new Cookie(COOKIE_NAME, "");
cookie.setMaxAge(0);
response.addCookie(cookie);
}
private AttackResult credentialsLoginFlow(String username, String password, HttpServletResponse response) {
String lowerCasedUsername = username.toLowerCase();
if (ATTACK_USERNAME.equals(lowerCasedUsername) && users.get(lowerCasedUsername).equals(password)) {
return informationMessage(this).feedback("spoofcookie.cheating").build();
}
String authPassword = users.getOrDefault(lowerCasedUsername, "");
if (!authPassword.isBlank() && authPassword.equals(password)) {
String newCookieValue = EncDec.encode(lowerCasedUsername);
Cookie newCookie = new Cookie(COOKIE_NAME, newCookieValue);
newCookie.setPath("/WebGoat");
newCookie.setSecure(true);
response.addCookie(newCookie);
return informationMessage(this).feedback("spoofcookie.login").output(String.format(COOKIE_INFO, lowerCasedUsername, newCookie.getValue())).build();
}
return informationMessage(this).feedback("spoofcookie.wrong-login").build();
}
private AttackResult cookieLoginFlow(String cookieValue) {
String cookieUsername;
try {
cookieUsername = EncDec.decode(cookieValue).toLowerCase();
} catch (Exception e) {
// for providing some instructive guidance, we won't return 4xx error here
return failed(this).output(e.getMessage()).build();
}
if (users.containsKey(cookieUsername)) {
if (cookieUsername.equals(ATTACK_USERNAME)) {
return success(this).build();
}
return failed(this).feedback("spoofcookie.cookie-login").output(String.format(COOKIE_INFO, cookieUsername, cookieValue)).build();
}
return failed(this).feedback("spoofcookie.wrong-cookie").build();
}
}

View File

@@ -0,0 +1,98 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2021 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.
*/
package org.owasp.webgoat.lessons.spoofcookie.encoders;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.security.crypto.codec.Hex;
/***
*
* @author Angel Olle Blazquez
*
*/
public class EncDec {
// PoC: weak encoding method
private static final String SALT = RandomStringUtils.randomAlphabetic(10);
private EncDec() {
}
public static String encode(final String value) {
if (value == null) {
return null;
}
String encoded = value.toLowerCase() + SALT;
encoded = revert(encoded);
encoded = hexEncode(encoded);
return base64Encode(encoded);
}
public static String decode(final String encodedValue) throws IllegalArgumentException {
if (encodedValue == null) {
return null;
}
String decoded = base64Decode(encodedValue);
decoded = hexDecode(decoded);
decoded = revert(decoded);
return decoded.substring(0, decoded.length() - SALT.length());
}
private static String revert(final String value) {
return new StringBuilder(value)
.reverse()
.toString();
}
private static String hexEncode(final String value) {
char[] encoded = Hex.encode(value.getBytes(StandardCharsets.UTF_8));
return new String(encoded);
}
private static String hexDecode(final String value) {
byte[] decoded = Hex.decode(value);
return new String(decoded);
}
private static String base64Encode(final String value) {
return Base64
.getEncoder()
.encodeToString(value.getBytes());
}
private static String base64Decode(final String value) {
byte[] decoded = Base64
.getDecoder()
.decode(value.getBytes());
return new String(decoded);
}
}