diff --git a/.github/workflows/deploy-to-gcp.yml b/.github/workflows/deploy-to-gcp.yml new file mode 100644 index 000000000..6baf04805 --- /dev/null +++ b/.github/workflows/deploy-to-gcp.yml @@ -0,0 +1,28 @@ +name: Deploy to GCP + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Authenticate to GCP + uses: google-github-actions/auth@v1 + with: + credentials_json: ${{ secrets.GCP_KEY }} + + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@v1 + with: + project_id: your-gcp-project-id + + - name: Deploy to App Engine + run: | + gcloud app deploy --quiet \ No newline at end of file diff --git a/.github/workflows/java-ci.yml b/.github/workflows/java-ci.yml new file mode 100644 index 000000000..550096bf1 --- /dev/null +++ b/.github/workflows/java-ci.yml @@ -0,0 +1,37 @@ +name: Java CI + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up JDK + uses: actions/setup-java@v3 + with: + java-version: '11' # Adjust the Java version as needed + distribution: 'temurin' + + - name: Cache Gradle dependencies + uses: actions/cache@v3 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Build with Gradle + run: ./gradlew build + + - name: Run tests + run: ./gradlew test \ No newline at end of file diff --git a/.gradle/8.8/checksums/checksums.lock b/.gradle/8.8/checksums/checksums.lock new file mode 100644 index 000000000..a26c3c916 Binary files /dev/null and b/.gradle/8.8/checksums/checksums.lock differ diff --git a/.gradle/8.8/checksums/md5-checksums.bin b/.gradle/8.8/checksums/md5-checksums.bin new file mode 100644 index 000000000..4a0c987e2 Binary files /dev/null and b/.gradle/8.8/checksums/md5-checksums.bin differ diff --git a/.gradle/8.8/checksums/sha1-checksums.bin b/.gradle/8.8/checksums/sha1-checksums.bin new file mode 100644 index 000000000..4b75f8204 Binary files /dev/null and b/.gradle/8.8/checksums/sha1-checksums.bin differ diff --git a/.gradle/8.8/dependencies-accessors/gc.properties b/.gradle/8.8/dependencies-accessors/gc.properties new file mode 100644 index 000000000..e69de29bb diff --git a/.gradle/8.8/fileChanges/last-build.bin b/.gradle/8.8/fileChanges/last-build.bin new file mode 100644 index 000000000..f76dd238a Binary files /dev/null and b/.gradle/8.8/fileChanges/last-build.bin differ diff --git a/.gradle/8.8/fileHashes/fileHashes.bin b/.gradle/8.8/fileHashes/fileHashes.bin new file mode 100644 index 000000000..4ba622b78 Binary files /dev/null and b/.gradle/8.8/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.8/fileHashes/fileHashes.lock b/.gradle/8.8/fileHashes/fileHashes.lock new file mode 100644 index 000000000..bf4d4cdc1 Binary files /dev/null and b/.gradle/8.8/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.8/gc.properties b/.gradle/8.8/gc.properties new file mode 100644 index 000000000..e69de29bb diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 000000000..4a5e57e19 Binary files /dev/null and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 000000000..fc3224c17 --- /dev/null +++ b/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Thu Apr 10 16:20:23 IST 2025 +gradle.version=8.8 diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties new file mode 100644 index 000000000..e69de29bb diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..d53ecaf3d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "java.compile.nullAnalysis.mode": "automatic", + "java.configuration.updateBuildConfiguration": "automatic" +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..e6cc329dc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +# Use an official OpenJDK runtime as a parent image +FROM openjdk:11-jre-slim + +# Set the working directory in the container +WORKDIR /app + +# Copy the application WAR file into the container +COPY target/WebGoat.war /app/WebGoat.war + +# Expose the port your application runs on +EXPOSE 8080 + +# Run the application +CMD ["java", "-jar", "/app/WebGoat.war"] \ No newline at end of file diff --git a/README.MD b/README.MD index fac90c4ae..66db05b8a 100644 --- a/README.MD +++ b/README.MD @@ -1,88 +1,88 @@ -# Sonatype DepShield -[![DepShield Badge](https://depshield.sonatype.org/badges/WebGoat/WebGoat-Legacy/depshield.svg)](https://depshield.github.io) - -# Important Information - -Thank you for downloading WebGoat! This is the WebGoat Legacy version which is essentially the WebGoat 5 with a new UI. - -This program is a demonstration of common server-side application flaws. The -exercises are intended to be used by people to learn about application -penetration testing techniques. - -* [Home Page](http://webgoat.github.io) -* [OWASP Project Home Page](http://www.owasp.org/index.php/Category:OWASP_WebGoat_Project) -* [Source Code](https://github.com/WebGoat/WebGoat-Legacy) -* [Easy-Run Download](https://webgoat.atlassian.net/builds/browse/WEB-WGM/latestSuccessful/artifact/JOB1/WebGoat-Embedded-Tomcat/WebGoat-6.0-SNAPSHOT-war-exec.jar ) -* [Wiki](https://github.com/WebGoat/WebGoat-Legacy/wiki) -* [FAQ (old info):](http://code.google.com/p/webgoat/wiki/FAQ) -* [Contact Info - Direct to Bruce Mayhew](webgoat@owasp.org) -* [Mailing List - WebGoat Community - For most questions](owasp-webgoat@lists.owasp.org) - -**WARNING 1:** *While running this program your machine will be extremely -vulnerable to attack. You should to disconnect from the Internet while using -this program.* - -**WARNING 2:** *This program is for educational purposes only. If you attempt -these techniques without authorization, you are very likely to get caught. If -you are caught engaging in unauthorized hacking, most companies will fire you. -Claiming that you were doing security research will not work as that is the -first thing that all hackers claim.* - -You can find more information about WebGoat at: -(https://github.com/WebGoat/) +# WebGoat Legacy +[![DepShield Badge](https://depshield.sonatype.org/badges/WebGoat/WebGoat-Legacy/depshield.svg)](https://depshield.github.io) -# Easy Run Instructions ( For non-developers ) +## Overview -Follow these instructions if you simply wish to run WebGoat +WebGoat Legacy is a demonstration of common server-side application flaws. It is designed to teach application penetration testing techniques through hands-on exercises. This version is based on WebGoat 5 with a new user interface. -**Prerequisites:** +**WARNING:** This program is for educational purposes only. Running it will make your machine vulnerable to attacks. Disconnect from the Internet while using it. -Java VM >= 1.6 installed ( JDK 1.7 recommended) +## Features -1. Download the executable jar file to any location of your choice: +- Hands-on exercises to learn about application security vulnerabilities. +- Demonstrates common server-side application flaws. +- Includes a modernized user interface. +- Supports easy and standard run modes for both non-developers and developers. - (https://webgoat.atlassian.net/builds/browse/WEB-WGM/latestSuccessful/artifact/shared/WebGoat-Embedded-Tomcat/WebGoat-6.0.1-war-exec.jar) +## Prerequisites -2. Run it using java: +- **Java VM**: Version >= 1.6 (JDK 1.7 recommended). +- **Maven**: Version > 2.0.9 (for developers). +- **IDE**: NetBeans, IntelliJ, or Eclipse with Maven support (for developers). +- **Git**: Required for source code management. - > java -jar WebGoat-6.0-exec-war.jar +## Easy Run Instructions (For Non-Developers) -3. Then navigate in your browser to: (http://localhost:8080/WebGoat) +1. Download the executable jar file: + [WebGoat-6.0.1-war-exec.jar](https://webgoat.atlassian.net/builds/browse/WEB-WGM/latestSuccessful/artifact/shared/WebGoat-Embedded-Tomcat/WebGoat-6.0.1-war-exec.jar) +2. Run it using Java: + ``` + java -jar WebGoat-6.0-exec-war.jar + ``` +3. Open your browser and navigate to: + [http://localhost:8080/WebGoat](http://localhost:8080/WebGoat) +4. To change the port or other options, use: + ``` + java -jar WebGoat-6.0-exec-war.jar --help + ``` -4. If you would like to change the port or other options, use: +## Standard Run Instructions (For Developers) - > java -jar WebGoat-6.0-exec-war.jar --help +1. Clone the repository: + ``` + git clone https://github.com/WebGoat/WebGoat-Legacy.git + ``` +2. Build the project using Maven: + ``` + cd webgoat + mvn clean package + ``` +3. Run the project in an embedded Tomcat server: + ``` + mvn tomcat:run-war + ``` +4. Alternatively, run the executable jar file: + ``` + cd target + java -jar WebGoat-6.0-exec-war.jar + ``` +## Contributing -# Standard Run Instructions (For Developers) +Contributions are welcome! Please follow these steps: -Follow These instructions if you wish to run Webgoat and modify the source code -as well. +1. Fork the repository. +2. Create a new branch for your feature or bug fix. +3. Commit your changes and push them to your fork. +4. Submit a pull request with a detailed description of your changes. -**Prerequisites:** +## License -* Java >= 1.6 ( JDK 1.7 recommended ) -* Maven > 2.0.9 -* Your favorite IDE, with Maven awareness: Netbeans/IntelliJ/Eclipse with m2e - installed. If you are setting up an IDE, Netbeans 8.0 contains the Maven and - Git support you need: (https://netbeans.org/downloads/) -* Git, or Git support in your IDE - -**Note:** WebGoat source code can be downloaded at: (https://github.com/WebGoat/WebGoat-Legacy). - +This project is licensed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). -1. Building the project (Developers) using a command shell/window: +## Support - > cd webgoat - > mvn clean package +For questions or support, please use the following resources: -2. After opening the project in Netbeans or Eclipse, you can easily run the -project using maven: +- [WebGoat Wiki](https://github.com/WebGoat/WebGoat-Legacy/wiki) +- [Mailing List](mailto:owasp-webgoat@lists.owasp.org) +- [Contact Bruce Mayhew](mailto:webgoat@owasp.org) - > mvn tomcat:run-war +## Additional Resources -3. Maven will run the project in an embedded tomcat. The package phase also builds an executable jar file. You can run it using: +- [Home Page](http://webgoat.github.io) +- [OWASP Project Home Page](http://www.owasp.org/index.php/Category:OWASP_WebGoat_Project) +- [FAQ](http://code.google.com/p/webgoat/wiki/FAQ) - > cd target - > java -jar WebGoat-6.0-exec-war.jar http://localhost:8080/WebGoat +Thank you for using WebGoat Legacy! diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..015700ff5 --- /dev/null +++ b/build.gradle @@ -0,0 +1,69 @@ +plugins { + id 'java' + id 'war' + id 'org.gretty' version '4.0.3' +} + +group = 'WebGoat' +version = '6.0.1' + +sourceCompatibility = '17' +targetCompatibility = '17' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'com.h2database:h2:2.1.214' + implementation 'com.sun.activation:jakarta.activation:1.2.2' + implementation 'org.apache.axis:axis:1.4' + implementation 'org.apache.commons:commons-lang3:3.12.0' + implementation 'commons-collections:commons-collections:3.2.2' + implementation 'org.slf4j:jcl-over-slf4j:2.0.9' + implementation 'com.sun.mail:jakarta.mail:1.6.7' + implementation 'javax.mail:mailapi:1.4.2' + implementation 'hsqldb:hsqldb:1.8.0.7' + implementation 'wsdl4j:wsdl4j:1.5.1' + implementation 'java2html:j2h:1.3.1' + implementation 'ecs:ecs:1.4.2' + implementation 'jakarta.transaction:jakarta.transaction-api:2.0.1' + implementation 'net.sourceforge.jtds:jtds:1.2.2' + providedCompile 'org.apache.tomcat:tomcat-catalina:9.0.78' + providedCompile 'javax:javaee-api:6.0' + implementation 'org.springframework:spring-core:5.3.22' + implementation 'org.springframework:spring-webmvc:5.3.22' + implementation 'org.springframework.security:spring-security-core:5.7.8' + implementation 'org.springframework.security:spring-security-config:5.7.8' + implementation 'org.springframework.security:spring-security-web:5.7.8' + implementation 'commons-fileupload:commons-fileupload:1.4' + implementation 'commons-io:commons-io:2.11.0' + implementation 'javax.servlet:jstl:1.2' + implementation 'taglibs:standard:1.1.2' + implementation 'log4j:log4j:1.2.17' + testImplementation 'junit:junit:4.13.2' + implementation 'org.apache.tiles:tiles-core:3.0.8' + implementation 'org.slf4j:slf4j-api:2.0.9' + implementation 'org.slf4j:slf4j-log4j12:2.0.9' + implementation 'org.springframework.security:spring-security-oauth2-client:5.7.8' + implementation 'org.springframework.security:spring-security-oauth2-jose:5.7.8' +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +war { + manifest { + attributes( + 'Specification-Title': project.name, + 'Specification-Version': project.version, + 'Implementation-Version': 'local' + ) + } +} + +gretty { + contextPath = '/WebGoat' + servletContainer = 'tomcat9' +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..91bafbb02 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,29 @@ +version: '3.8' + +services: + webgoat: + build: + context: . + dockerfile: Dockerfile + ports: + - "8080:8080" # Map port 8080 of the container to port 8080 on the host + volumes: + - ./src/main/resources:/usr/local/tomcat/resources # Example volume mapping + environment: + - JAVA_OPTS=-Xms512m -Xmx1024m # Example Java options + + database: + image: mysql:8.0 + container_name: webgoat-db + environment: + MYSQL_ROOT_PASSWORD: rootpassword + MYSQL_DATABASE: webgoat + MYSQL_USER: webgoat + MYSQL_PASSWORD: webgoatpassword + ports: + - "3306:3306" + volumes: + - db_data:/var/lib/mysql + +volumes: + db_data: \ No newline at end of file diff --git a/newDesign/index.html b/newDesign/index.html index d1020068a..882b9ef95 100644 --- a/newDesign/index.html +++ b/newDesign/index.html @@ -57,14 +57,14 @@

Lesson Title in here

- - -
@@ -176,7 +176,7 @@

Lesson Title in here

-
+

About WebGoat


@@ -210,15 +210,15 @@

Hints

- - + +
+
+
diff --git a/pom.xml b/pom.xml index ded96c17c..fa898b33d 100644 --- a/pom.xml +++ b/pom.xml @@ -9,9 +9,9 @@ - 3.2.4.RELEASE - 3.2.4.RELEASE - 2.2.2 + 5.3.22 + 5.7.8 + 3.0.8 local @@ -30,9 +30,9 @@ org.apache.maven.plugins maven-compiler-plugin - 1.6 - 1.6 - ISO-8859-1 + 17 + 17 + UTF-8 @@ -75,59 +75,34 @@ - com.h2database - h2 - 1.4.187 - - - javax.activation - activation - 1.1 + com.h2database + h2 + 2.1.214 - axis - axis - 1.2 - - - axis - axis-saaj - 1.2 - - - axis - axis-jaxrpc - 1.2 + com.sun.activation + jakarta.activation + 1.2.2 - axis - axis-ant - 1.2 + org.apache.axis + axis + 1.4 org.apache.commons commons-lang3 - 3.3.2 + 3.12.0 - - commons-collections commons-collections - 3.1 + 3.2.2 commons-digester commons-digester - 1.4.1 + 2.1 xml-apis @@ -135,25 +110,15 @@ - - commons-logging - commons-logging - 1.1.3 - org.slf4j jcl-over-slf4j - 1.7.7 + 2.0.9 - commons-discovery - commons-discovery - 0.2 - - - javax.mail - mail - 1.4.2 + com.sun.mail + jakarta.mail + 1.6.7 javax.mail @@ -165,12 +130,6 @@ hsqldb 1.8.0.7 - - wsdl4j wsdl4j @@ -187,9 +146,9 @@ 1.4.2 - javax.transaction - javax.transaction-api - 1.2 + jakarta.transaction + jakarta.transaction-api + 2.0.1 net.sourceforge.jtds @@ -199,7 +158,7 @@ org.apache.tomcat tomcat-catalina - 7.0.27 + 9.0.78 provided @@ -224,12 +183,12 @@ com.fasterxml.jackson.core jackson-core - 2.0.4 + 2.15.2 com.fasterxml.jackson.core jackson-databind - 2.0.4 + 2.15.2 @@ -258,18 +217,29 @@ ${spring.security.version} + + org.springframework.security + spring-security-oauth2-client + ${spring.security.version} + + + org.springframework.security + spring-security-oauth2-jose + ${spring.security.version} + + commons-fileupload commons-fileupload - 1.2.2 + 1.4 commons-io commons-io - 1.3.2 + 2.11.0 @@ -307,7 +277,7 @@ junit junit - 4.8.1 + 4.13.2 jar @@ -319,13 +289,13 @@ org.slf4j slf4j-api - 1.7.7 + 2.0.9 jar org.slf4j slf4j-log4j12 - 1.7.7 + 2.0.9 jar diff --git a/src/main/java/org/owasp/SecurityConfig.java b/src/main/java/org/owasp/SecurityConfig.java new file mode 100644 index 000000000..04329c3a3 --- /dev/null +++ b/src/main/java/org/owasp/SecurityConfig.java @@ -0,0 +1,36 @@ +package org.owasp; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .headers() + .contentSecurityPolicy("default-src 'self'; script-src 'self'; style-src 'self'") + .and() + .xssProtection().block(true) + .and() + .frameOptions().deny() + .and() + .httpStrictTransportSecurity().includeSubDomains(true).maxAgeInSeconds(31536000) + .and() + .and() + .authorizeRequests() + .antMatchers("/", "/login", "/css/**", "/js/**", "/images/**").permitAll() + .anyRequest().authenticated() + .and() + .oauth2Login() + .loginPage("/login") + .defaultSuccessUrl("/", true) + .and() + .logout() + .logoutSuccessUrl("/"); + } +} \ No newline at end of file diff --git a/src/main/java/org/owasp/webgoat/ApiController.java b/src/main/java/org/owasp/webgoat/ApiController.java new file mode 100644 index 000000000..b785f380d --- /dev/null +++ b/src/main/java/org/owasp/webgoat/ApiController.java @@ -0,0 +1,15 @@ +package org.owasp.webgoat; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +public class ApiController { + + @GetMapping("/status") + public String getStatus() { + return "WebGoat API is running"; + } +} \ No newline at end of file diff --git a/src/main/java/org/owasp/webgoat/Catcher.java b/src/main/java/org/owasp/webgoat/Catcher.java index ce937367e..356451122 100644 --- a/src/main/java/org/owasp/webgoat/Catcher.java +++ b/src/main/java/org/owasp/webgoat/Catcher.java @@ -1,8 +1,6 @@ - package org.owasp.webgoat; import java.io.IOException; -import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -10,7 +8,6 @@ import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.WebSession; - /*************************************************************************************************** * * @@ -72,17 +69,11 @@ public class Catcher extends HammerHead * @exception ServletException * Description of the Exception */ - public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - try - { - // System.out.println( "Entering doPost: " ); - // System.out.println( " - request " + request); - // System.out.println( " - principle: " + request.getUserPrincipal() ); - // setCacheHeaders(response, 0); + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + try { WebSession session = (WebSession) request.getSession(true).getAttribute(WebSession.SESSION); - session.update(request, response, this.getServletName()); // FIXME: Too much in this - // call. + session.update(request, response, this.getServletName()); int scr = session.getCurrentScreen(); Course course = session.getCourse(); @@ -90,28 +81,23 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr log(request, lesson.getClass().getName() + " | " + session.getParser().toString()); - String property = new String(session.getParser().getStringParameter(PROPERTY, EMPTY_STRING)); + String property = session.getParser().getStringParameter(PROPERTY, EMPTY_STRING); - // if the PROPERTY parameter is available - write all the parameters to the - // property file. No other control parameters are supported at this time. - if (!property.equals(EMPTY_STRING)) - { - Enumeration e = session.getParser().getParameterNames(); - - while (e.hasMoreElements()) - { - String name = (String) e.nextElement(); - String value = session.getParser().getParameterValues(name)[0]; + if (!property.isEmpty()) { + var parameterNames = session.getParser().getParameterNames(); + while (parameterNames.hasMoreElements()) { + var name = (String) parameterNames.nextElement(); + var value = session.getParser().getParameterValues(name)[0]; lesson.getLessonTracker(session).getLessonProperties().setProperty(name, value); } } lesson.getLessonTracker(session).store(session, lesson); - // BDM MC - if ( request.getParameter("Deleter") != null ){org.owasp.webgoat.lessons.BlindScript.StaticDeleter();} + if (request.getParameter("Deleter") != null) { + org.owasp.webgoat.lessons.BlindScript.StaticDeleter(); + } - } catch (Throwable t) - { + } catch (Throwable t) { t.printStackTrace(); log("ERROR: " + t); } diff --git a/src/main/java/org/owasp/webgoat/HammerHead.java b/src/main/java/org/owasp/webgoat/HammerHead.java index 2a69f3c03..0f1541a07 100644 --- a/src/main/java/org/owasp/webgoat/HammerHead.java +++ b/src/main/java/org/owasp/webgoat/HammerHead.java @@ -2,10 +2,11 @@ import java.io.IOException; import java.io.PrintWriter; -import java.text.SimpleDateFormat; +import java.time.format.DateTimeFormatter; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Date; import java.util.Locale; -import java.util.TimeZone; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -15,7 +16,6 @@ import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.WelcomeScreen; import org.owasp.webgoat.lessons.admin.WelcomeAdminScreen; -import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.ErrorScreen; import org.owasp.webgoat.session.Screen; import org.owasp.webgoat.session.UserTracker; @@ -64,17 +64,16 @@ public class HammerHead extends HttpServlet { final Logger logger = LoggerFactory.getLogger(HammerHead.class); - private static final String WELCOMED = "welcomed"; - /** * */ private static final long serialVersionUID = 645640331343188020L; /** - * Description of the Field + * Replacing SimpleDateFormat with DateTimeFormatter for thread safety and modern API usage. */ - protected static SimpleDateFormat httpDateFormat; + protected static final DateTimeFormatter HTTP_DATE_FORMAT = + DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US).withZone(ZoneId.of("GMT")); /** * Set the session timeout to be 2 days @@ -215,15 +214,13 @@ private String getViewPage(WebSession webSession) { } /** - * Description of the Method + * Updated formatHttpDate to use DateTimeFormatter. * * @param date Description of the Parameter * @return RFC 1123 http date format */ protected static String formatHttpDate(Date date) { - synchronized (httpDateFormat) { - return httpDateFormat.format(date); - } + return HTTP_DATE_FORMAT.format(ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("GMT"))); } /** @@ -244,8 +241,6 @@ public String getServletInfo() { @Override public void init() throws ServletException { logger.info("Initializing main webgoat servlet"); - httpDateFormat = new SimpleDateFormat("EEE, dd MMM yyyyy HH:mm:ss z", Locale.US); - httpDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); propertiesPath = getServletContext().getRealPath("/WEB-INF/webgoat.properties"); webgoatContext = new WebgoatContext(this); } @@ -268,81 +263,30 @@ public void log(HttpServletRequest request, String message) { * ArrayList(course.getLessons(category, role)); return course.getLessons(category, role); } */ /** - * Description of the Method + * Refactored makeScreen method to use switch expressions for cleaner logic. * * @param s Description of the Parameter * @return Description of the Return Value */ protected Screen makeScreen(WebSession s) { - Screen screen = null; - int scr = s.getCurrentScreen(); - Course course = s.getCourse(); - - if (s.isUser() || s.isChallenge()) { - if (scr == WebSession.WELCOME) { - screen = new WelcomeScreen(s); - } else { - AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE); + return switch (s.getCurrentScreen()) { + case WebSession.WELCOME -> s.isAdmin() ? new WelcomeAdminScreen(s) : new WelcomeScreen(s); + default -> { + AbstractLesson lesson = s.getCourse().getLesson(s, s.getCurrentScreen(), + s.isAdmin() ? AbstractLesson.ADMIN_ROLE : AbstractLesson.USER_ROLE); if (lesson == null && s.isHackedAdmin()) { - // If admin was hacked, let the user see some of the - // admin screens - lesson = course.getLesson(s, scr, AbstractLesson.HACKED_ADMIN_ROLE); + lesson = s.getCourse().getLesson(s, s.getCurrentScreen(), AbstractLesson.HACKED_ADMIN_ROLE); } - if (lesson != null) { - screen = lesson; - - // We need to do some bookkeeping for the hackable admin - // interface. - // This is the only place we can tell if the user - // successfully hacked the hackable - // admin and has actually accessed an admin screen. You - // need BOTH pieces of information - // in order to satisfy the remote admin lesson. - s.setHasHackableAdmin(screen.getRole()); - + s.setHasHackableAdmin(lesson.getRole()); lesson.handleRequest(s); s.setCurrentMenu(lesson.getCategory().getRanking()); + yield lesson; } else { - screen = new ErrorScreen(s, "Invalid screen requested. Try: http://localhost/WebGoat/attack"); + yield new ErrorScreen(s, "Invalid screen requested. Try: http://localhost/WebGoat/attack"); } } - } else if (s.isAdmin()) { - if (scr == WebSession.WELCOME) { - screen = new WelcomeAdminScreen(s); - } else { - // Admin can see all roles. - // FIXME: should be able to pass a list of roles. - AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.ADMIN_ROLE); - if (lesson == null) { - lesson = course.getLesson(s, scr, AbstractLesson.HACKED_ADMIN_ROLE); - } - if (lesson == null) { - lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE); - } - - if (lesson != null) { - screen = lesson; - - // We need to do some bookkeeping for the hackable admin - // interface. - // This is the only place we can tell if the user - // successfully hacked the hackable - // admin and has actually accessed an admin screen. You - // need BOTH pieces of information - // in order to satisfy the remote admin lesson. - s.setHasHackableAdmin(screen.getRole()); - - lesson.handleRequest(s); - s.setCurrentMenu(lesson.getCategory().getRanking()); - } else { - screen = new ErrorScreen(s, - "Invalid screen requested. Try Setting Admin to false or Try: http://localhost/WebGoat/attack"); - } - } - } - - return (screen); + }; } /** diff --git a/src/main/java/org/owasp/webgoat/LessonSource.java b/src/main/java/org/owasp/webgoat/LessonSource.java index 8223d5142..29b1cfa9d 100644 --- a/src/main/java/org/owasp/webgoat/LessonSource.java +++ b/src/main/java/org/owasp/webgoat/LessonSource.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.io.PrintWriter; +import java.util.Objects; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -64,39 +65,23 @@ public class LessonSource extends HammerHead { * @exception IOException Description of the Exception * @exception ServletException Description of the Exception */ + @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String source = null; try { - // System.out.println( "Entering doPost: " ); - // System.out.println( " - request " + request); - // System.out.println( " - principle: " + request.getUserPrincipal() - // ); - // setCacheHeaders(response, 0); - WebSession session = (WebSession) request.getSession(true).getAttribute(WebSession.SESSION); - // FIXME: Too much in this call. + var session = (WebSession) request.getSession(true).getAttribute(WebSession.SESSION); session.update(request, response, this.getServletName()); boolean showSolution = session.getParser().getBooleanParameter("solution", false); boolean showSource = session.getParser().getBooleanParameter("source", false); if (showSolution) { - - // Get the Java solution of the lesson. source = getSolution(session); - - int scr = session.getCurrentScreen(); - Course course = session.getCourse(); - AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson.USER_ROLE); + var lesson = session.getCourse().getLesson(session, session.getCurrentScreen(), AbstractLesson.USER_ROLE); lesson.getLessonTracker(session).setViewedSolution(true); - } else if (showSource) { - - // Get the Java source of the lesson. FIXME: Not needed source = getSource(session); - - int scr = session.getCurrentScreen(); - Course course = session.getCourse(); - AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson.USER_ROLE); + var lesson = session.getCourse().getLesson(session, session.getCurrentScreen(), AbstractLesson.USER_ROLE); lesson.getLessonTracker(session).setViewedSource(true); } } catch (Throwable t) { @@ -109,8 +94,6 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr thr.printStackTrace(); log(request, "Could not write error screen: " + thr.getMessage()); } - // System.out.println( "Leaving doPost: " ); - } } @@ -173,13 +156,8 @@ protected String getSolution(WebSession s) { protected void writeSource(String s, HttpServletResponse response) throws IOException { response.setContentType("text/html"); - PrintWriter out = response.getWriter(); - - if (s == null) { - s = new String(); + try (var out = response.getWriter()) { + out.print(Objects.requireNonNullElse(s, "")); } - - out.print(s); - out.close(); } } diff --git a/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java b/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java index e689f7d1f..ba6064496 100644 --- a/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java +++ b/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java @@ -10,10 +10,8 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; import java.util.Map; +import java.util.List; import org.apache.ecs.Element; import org.apache.ecs.ElementContainer; import org.apache.ecs.StringElement; @@ -22,7 +20,6 @@ import org.apache.ecs.html.Head; import org.apache.ecs.html.Html; import org.apache.ecs.html.IMG; -import org.apache.ecs.html.PRE; import org.apache.ecs.html.Title; import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.Screen; @@ -105,13 +102,13 @@ public abstract class AbstractLesson extends Screen implements Comparable lessonPlanFileName = new HashMap(); + private Map lessonPlanFileName = Map.of(); private String lessonSolutionFileName; private WebgoatContext webgoatContext; - private LinkedList availableLanguages = new LinkedList(); + private List availableLanguages = List.of(); private String defaultLanguage = "en"; @@ -121,7 +118,7 @@ public abstract class AbstractLesson extends Screen implements Comparable getAvailableLanguages() { diff --git a/src/main/java/org/owasp/webgoat/lessons/NewLesson.java b/src/main/java/org/owasp/webgoat/lessons/NewLesson.java index 90b22af3d..30a956f3d 100644 --- a/src/main/java/org/owasp/webgoat/lessons/NewLesson.java +++ b/src/main/java/org/owasp/webgoat/lessons/NewLesson.java @@ -1,88 +1,36 @@ - package org.owasp.webgoat.lessons; -import org.apache.ecs.Element; -import org.apache.ecs.StringElement; import org.owasp.webgoat.session.WebSession; +import org.owasp.webgoat.session.Screen; +import java.util.List; - -/*************************************************************************************************** - * - * - * 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 Sherif Koussa Software Secured - * @created October 28, 2003 +/** + * A new lesson for WebGoat. */ -public class NewLesson extends LessonAdapter -{ - /** - * Description of the Method - * - * @param s - * Description of the Parameter - * @return Description of the Return Value - */ - protected Element createContent(WebSession s) - { - return super.createContent(s); - // makeSuccess(s); - // ec.addElement(new StringElement("Welcome to the WebGoat hall of fame !!")); - // return (ec); - } +public class RaduLesson extends AbstractLesson { - /** - * Gets the category attribute of the NEW_LESSON object - * - * @return The category value - */ - protected Category getDefaultCategory() - { - return Category.INTRODUCTION; + @Override + public String getTitle() { + return "Radu Lesson"; } - private final static Integer DEFAULT_RANKING = new Integer(85); - - protected Integer getDefaultRanking() - { - return DEFAULT_RANKING; + @Override + protected void handleRequest(WebSession session) { + // Lesson logic goes here } - /** - * Gets the title attribute of the DirectoryScreen object - * - * @return The title value - */ - public String getTitle() - { - return ("How to create a Lesson"); + @Override + public Category getDefaultCategory() { + return Category.GENERAL; } - public Element getCredits() - { - return super.getCustomCredits("Created by: Your name goes here!", new StringElement("")); + @Override + public String getInstructions(WebSession session) { + return "Complete the tasks in this Radu lesson."; } + @Override + protected List getScreens() { + return List.of(new Screen("RaduLessonScreen", "Radu Lesson Screen")); + } } diff --git a/src/main/java/org/owasp/webgoat/lessons/RaduLesson.java b/src/main/java/org/owasp/webgoat/lessons/RaduLesson.java new file mode 100644 index 000000000..1402ecf08 --- /dev/null +++ b/src/main/java/org/owasp/webgoat/lessons/RaduLesson.java @@ -0,0 +1,36 @@ +package org.owasp.webgoat.lessons; + +import org.owasp.webgoat.session.WebSession; +import org.owasp.webgoat.session.Screen; +import java.util.List; + +/** + * A new lesson for WebGoat. + */ +public class RaduLesson extends AbstractLesson { + + @Override + public String getTitle() { + return "Radu Lesson"; + } + + @Override + protected void handleRequest(WebSession session) { + // Lesson logic goes here + } + + @Override + public Category getDefaultCategory() { + return Category.GENERAL; + } + + @Override + public String getInstructions(WebSession session) { + return "Complete the tasks in this Radu lesson."; + } + + @Override + protected List getScreens() { + return List.of(new Screen("RaduLessonScreen", "Radu Lesson Screen")); + } +} diff --git a/src/main/java/org/owasp/webgoat/lessons/admin/AdminScreen.java b/src/main/java/org/owasp/webgoat/lessons/admin/AdminScreen.java index bea43efcf..c9cf3f8d3 100644 --- a/src/main/java/org/owasp/webgoat/lessons/admin/AdminScreen.java +++ b/src/main/java/org/owasp/webgoat/lessons/admin/AdminScreen.java @@ -1,4 +1,3 @@ - package org.owasp.webgoat.lessons.admin; import org.owasp.webgoat.lessons.AbstractLesson; @@ -52,11 +51,8 @@ public abstract class AdminScreen extends Screen * @param q * Description of the Parameter */ - public AdminScreen(WebSession s, String q) - { - setQuery(q); - - // setupAdmin(s); FIXME: what was this supposed to do? + public AdminScreen(WebSession s, String q) { + this.query = q; } /** @@ -65,15 +61,15 @@ public AdminScreen(WebSession s, String q) * @param s * Description of the Parameter */ - public AdminScreen(WebSession s) - { + public AdminScreen(WebSession s) { + this(s, null); } /** * Constructor for the AdminScreen object */ - public AdminScreen() - { + public AdminScreen() { + this(null, null); } /** diff --git a/src/main/java/org/owasp/webgoat/service/ApplicationService.java b/src/main/java/org/owasp/webgoat/service/ApplicationService.java index 188620c24..eb5523326 100644 --- a/src/main/java/org/owasp/webgoat/service/ApplicationService.java +++ b/src/main/java/org/owasp/webgoat/service/ApplicationService.java @@ -50,10 +50,8 @@ public class ApplicationService extends BaseService { * @return */ @RequestMapping(value = "/application.mvc", produces = "application/json") - public @ResponseBody - Application showApplication(HttpSession session) { - Application app = Application.getInstance(); - return app; + public @ResponseBody Application showApplication(HttpSession session) { + return Application.getInstance(); } } diff --git a/src/main/java/org/owasp/webgoat/service/BaseService.java b/src/main/java/org/owasp/webgoat/service/BaseService.java index 1232e57b8..ac32ea1f1 100644 --- a/src/main/java/org/owasp/webgoat/service/BaseService.java +++ b/src/main/java/org/owasp/webgoat/service/BaseService.java @@ -67,22 +67,20 @@ ExceptionInfo handleException(HttpServletRequest request, Exception ex) { } public WebSession getWebSession(HttpSession session) { - WebSession ws; - Object o = session.getAttribute(WebSession.SESSION); + var o = session.getAttribute(WebSession.SESSION); if (o == null) { - throw new IllegalArgumentException("No valid WebSession object found, has session timed out? [" + session.getId() + "]"); + throw new IllegalArgumentException(String.format("No valid WebSession object found, has session timed out? [%s]", session.getId())); } - if (!(o instanceof WebSession)) { - throw new IllegalArgumentException("Invalid WebSession object found, this is probably a bug! [" + o.getClass() + " | " + session.getId() + "]"); + if (!(o instanceof WebSession ws)) { + throw new IllegalArgumentException(String.format("Invalid WebSession object found, this is probably a bug! [%s | %s]", o.getClass(), session.getId())); } - ws = (WebSession) o; return ws; } - public String getStringStackTrace(Throwable t){ - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - t.printStackTrace(pw); - return sw.toString(); + public String getStringStackTrace(Throwable t) { + try (var sw = new StringWriter(); var pw = new PrintWriter(sw)) { + t.printStackTrace(pw); + return sw.toString(); + } } } diff --git a/src/main/java/org/owasp/webgoat/service/DummyService.java b/src/main/java/org/owasp/webgoat/service/DummyService.java index b57e8c1ae..c05017490 100644 --- a/src/main/java/org/owasp/webgoat/service/DummyService.java +++ b/src/main/java/org/owasp/webgoat/service/DummyService.java @@ -27,7 +27,6 @@ */ package org.owasp.webgoat.service; -import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @@ -40,12 +39,13 @@ @Controller public class DummyService extends BaseService{ + /** + * Retrieves a list of first names. + * + * @return a list of strings containing first names + */ @RequestMapping(value = "/first.mvc", produces = "application/json") - public @ResponseBody - List firstNames() { - List test = new ArrayList(); - test.add("one"); - test.add("two)"); - return test; + public @ResponseBody List firstNames() { + return List.of("one", "two"); } } diff --git a/src/main/java/org/owasp/webgoat/service/ExceptionInfo.java b/src/main/java/org/owasp/webgoat/service/ExceptionInfo.java index 04479ccd3..985be88ed 100644 --- a/src/main/java/org/owasp/webgoat/service/ExceptionInfo.java +++ b/src/main/java/org/owasp/webgoat/service/ExceptionInfo.java @@ -28,27 +28,7 @@ package org.owasp.webgoat.service; /** - * - * @author rlawson + * Represents exception information with a URL and a message. */ -public class ExceptionInfo { - - private String url; - private String message; - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } +public record ExceptionInfo(String url, String message) { } diff --git a/src/main/java/org/owasp/webgoat/service/ExportService.java b/src/main/java/org/owasp/webgoat/service/ExportService.java new file mode 100644 index 000000000..e34c26142 --- /dev/null +++ b/src/main/java/org/owasp/webgoat/service/ExportService.java @@ -0,0 +1,28 @@ +package org.owasp.webgoat.service; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +@Controller +public class ExportService { + + @GetMapping(value = "/export", produces = "text/csv") + public void exportData(HttpServletResponse response) throws IOException { + // Set response headers + response.setContentType("text/csv"); + response.setHeader("Content-Disposition", "attachment; filename=export.csv"); + + // Write CSV data + try (PrintWriter writer = response.getWriter()) { + writer.println("ID,Name,Role"); + writer.println("1,John Doe,Manager"); + writer.println("2,Jane Smith,Employee"); + writer.println("3,Bob Johnson,HR"); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/owasp/webgoat/service/HintService.java b/src/main/java/org/owasp/webgoat/service/HintService.java index e85e11fa9..7d7021a19 100644 --- a/src/main/java/org/owasp/webgoat/service/HintService.java +++ b/src/main/java/org/owasp/webgoat/service/HintService.java @@ -31,33 +31,25 @@ public class HintService extends BaseService { * @return */ @RequestMapping(value = "/hint.mvc", produces = "application/json") - public @ResponseBody - List showHint(HttpSession session) { - List listHints = new ArrayList(); - WebSession ws = getWebSession(session); - AbstractLesson l = ws.getCurrentLesson(); - if (l == null) { - return listHints; - } - List hints; - hints = l.getHintsPublic(ws); - if (hints == null) { - return listHints; - } - int maxHintViewed = l.getLessonTracker(ws).getMaxHintLevel(); + public @ResponseBody List showHint(HttpSession session) { + var listHints = new ArrayList(); + var ws = getWebSession(session); + var lesson = ws.getCurrentLesson(); + if (lesson == null) return listHints; + + var hints = lesson.getHintsPublic(ws); + if (hints == null) return listHints; + + int maxHintViewed = lesson.getLessonTracker(ws).getMaxHintLevel(); System.out.println("maxHintViewed: " + maxHintViewed); - int idx = 0; - for (String h : hints) { - Hint hint = new Hint(); - hint.setHint(h); - hint.setLesson(l.getName()); + for (int idx = 0; idx < hints.size(); idx++) { + var hint = new Hint(); + hint.setHint(hints.get(idx)); + hint.setLesson(lesson.getName()); hint.setNumber(idx); - if (idx <= maxHintViewed) { - hint.setViewed(true); - } + hint.setViewed(idx <= maxHintViewed); listHints.add(hint); - idx++; } return listHints; } diff --git a/src/main/java/org/owasp/webgoat/service/LessonMenuService.java b/src/main/java/org/owasp/webgoat/service/LessonMenuService.java index 3c7f0cbb4..827da2dd1 100644 --- a/src/main/java/org/owasp/webgoat/service/LessonMenuService.java +++ b/src/main/java/org/owasp/webgoat/service/LessonMenuService.java @@ -40,6 +40,7 @@ import org.owasp.webgoat.lessons.model.LessonMenuItemType; import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.WebSession; +import org.owasp.webgoat.util.InputSanitizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; @@ -56,71 +57,74 @@ public class LessonMenuService extends BaseService { private static final Logger logger = LoggerFactory.getLogger(LessonMenuService.class); /** - * Returns the lesson menu which is used to build the left nav + * Retrieves the lesson menu used to build the left navigation. * - * @param session - * @return + * @param session the HTTP session object + * @return a list of lesson menu items */ @RequestMapping(value = "/lessonmenu.mvc", produces = "application/json") - public @ResponseBody - List showLeftNav(HttpSession session) { - List menu = new ArrayList(); - WebSession ws = getWebSession(session); - // Get the categories, these are the main menu items - Course course = ws.getCourse(); - List categories = course.getCategories(); + public @ResponseBody List showLeftNav(HttpSession session) { + var menu = new ArrayList(); + var ws = getWebSession(session); - for (Category category : categories) { - LessonMenuItem categoryItem = new LessonMenuItem(); - categoryItem.setName(category.getName()); + // Validate session object + if (ws == null) { + logger.warn("Invalid session: WebSession is null"); + return menu; // Return an empty menu if session is invalid + } + + var course = ws.getCourse(); + if (course == null) { + logger.warn("Invalid session: Course is null"); + return menu; + } + + var categories = course.getCategories(); + for (var category : categories) { + // Sanitize category name + var sanitizedCategoryName = InputSanitizer.sanitize(category.getName()); + + var categoryItem = new LessonMenuItem(); + categoryItem.setName(sanitizedCategoryName); categoryItem.setType(LessonMenuItemType.CATEGORY); - // check for any lessons for this category - List lessons = ws.getLessons(category); - String role = ws.getRole(); - logger.info("Role: " + role); - for (AbstractLesson lesson : lessons) { - LessonMenuItem lessonItem = new LessonMenuItem(); - lessonItem.setName(lesson.getTitle()); - lessonItem.setLink(lesson.getLink()); - lessonItem.setType(LessonMenuItemType.LESSON); - if (lesson.isCompleted(ws)) { - lessonItem.setComplete(true); + + var lessons = ws.getLessons(category); + var role = ws.getRole(); + + // Avoid logging sensitive information + logger.debug("Processing role for category: " + sanitizedCategoryName); + + for (var lesson : lessons) { + // Authorization check + if (!lesson.isAuthorized(ws, role)) { + logger.warn("Unauthorized access attempt to lesson: " + lesson.getTitle()); + continue; } - /* @TODO - do this in a more efficient way - if (lesson.isAuthorized(ws, role, WebSession.SHOWHINTS)) { - lessonItem.setShowHints(true); - } - if (lesson.isAuthorized(ws, role, WebSession.SHOWSOURCE)) { - lessonItem.setShowSource(true); - } - */ - // special handling for challenge role + var lessonItem = new LessonMenuItem(); + lessonItem.setName(InputSanitizer.sanitize(lesson.getTitle())); + lessonItem.setLink(InputSanitizer.sanitize(lesson.getLink())); + lessonItem.setType(LessonMenuItemType.LESSON); + lessonItem.setComplete(lesson.isCompleted(ws)); + if (Category.CHALLENGE.equals(lesson.getCategory())) { lessonItem.setShowHints(lesson.isAuthorized(ws, AbstractLesson.CHALLENGE_ROLE, WebSession.SHOWHINTS)); lessonItem.setShowSource(lesson.isAuthorized(ws, AbstractLesson.CHALLENGE_ROLE, WebSession.SHOWHINTS)); } categoryItem.addChild(lessonItem); - // Does the lesson have stages - if (lesson instanceof RandomLessonAdapter) { - RandomLessonAdapter rla = (RandomLessonAdapter) lesson; - String[] stages = rla.getStages(); + + if (lesson instanceof RandomLessonAdapter rla) { + var stages = rla.getStages(); if (stages != null) { - String lessonLink = lesson.getLink(); - int stageIdx = 1; - for (String stage : stages) { - LessonMenuItem stageItem = new LessonMenuItem(); - stageItem.setName("Stage " + stageIdx + ": " + stage); - // build the link for the stage - String stageLink = lessonLink + "&stage=" + stageIdx; - stageItem.setLink(stageLink); + var lessonLink = lesson.getLink(); + for (int stageIdx = 1; stageIdx <= stages.length; stageIdx++) { + var stageItem = new LessonMenuItem(); + stageItem.setName("Stage " + stageIdx + ": " + InputSanitizer.sanitize(stages[stageIdx - 1])); + stageItem.setLink(lessonLink + "&stage=" + stageIdx); stageItem.setType(LessonMenuItemType.STAGE); - if (rla.isStageComplete(ws, stage)) { - stageItem.setComplete(true); - } + stageItem.setComplete(rla.isStageComplete(ws, stages[stageIdx - 1])); lessonItem.addChild(stageItem); - stageIdx++; } } } @@ -128,6 +132,5 @@ List showLeftNav(HttpSession session) { menu.add(categoryItem); } return menu; - } } diff --git a/src/main/java/org/owasp/webgoat/service/LessonPlanService.java b/src/main/java/org/owasp/webgoat/service/LessonPlanService.java index 7f48f3b4b..d73a6645e 100644 --- a/src/main/java/org/owasp/webgoat/service/LessonPlanService.java +++ b/src/main/java/org/owasp/webgoat/service/LessonPlanService.java @@ -49,45 +49,33 @@ public class LessonPlanService extends BaseService { /** - * Returns source for current attack + * Retrieves the lesson plan for the current attack. * - * @param session - * @return + * @param session the HTTP session object + * @return the lesson plan as a string */ @RequestMapping(value = "/lessonplan.mvc", produces = "application/html") - public @ResponseBody - String showPlan(HttpSession session) { - WebSession ws = getWebSession(session); - String plan = getPlan(ws); - return plan; - //SourceListing sl = new SourceListing(); - //sl.setSource(source); - //return sl; + public @ResponseBody String showPlan(HttpSession session) { + var ws = getWebSession(session); + return getPlan(ws); } /** - * Description of the Method + * Retrieves the lesson plan for the current lesson. * - * @param s Description of the Parameter - * @return Description of the Return Value + * @param s the current web session + * @return the lesson plan as a string, or a message indicating no plan is available */ protected String getPlan(WebSession s) { - - String plan = null; - int scr = s.getCurrentScreen(); - Course course = s.getCourse(); + var scr = s.getCurrentScreen(); + var course = s.getCourse(); if (s.isUser() || s.isChallenge()) { - - AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE); - + var lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE); if (lesson != null) { - plan = lesson.getLessonPlan(s); + return lesson.getLessonPlan(s); } } - if (plan == null) { - plan = "Plan is not available for this lesson."; - } - return plan; + return "Plan is not available for this lesson."; } } diff --git a/src/main/java/org/owasp/webgoat/service/LessonTitleService.java b/src/main/java/org/owasp/webgoat/service/LessonTitleService.java index 938a06850..823161374 100644 --- a/src/main/java/org/owasp/webgoat/service/LessonTitleService.java +++ b/src/main/java/org/owasp/webgoat/service/LessonTitleService.java @@ -12,29 +12,33 @@ @Controller public class LessonTitleService extends BaseService { - /** - * Returns the title for the current attack + /** + * Retrieves the title for the current lesson. * - * @param session - * @return + * @param session the HTTP session object + * @return the title of the current lesson */ @RequestMapping(value = "/lessontitle.mvc", produces = "application/html") - public @ResponseBody - String showPlan(HttpSession session) { - WebSession ws = getWebSession(session); + public @ResponseBody String showPlan(HttpSession session) { + var ws = getWebSession(session); return getLessonTitle(ws); } + /** + * Retrieves the title of the current lesson. + * + * @param s the current web session + * @return the title of the lesson, or an empty string if unavailable + */ private String getLessonTitle(WebSession s) { - String title = ""; - int scr = s.getCurrentScreen(); - Course course = s.getCourse(); + var scr = s.getCurrentScreen(); + var course = s.getCourse(); if (s.isUser() || s.isChallenge()) { - AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE); - title = lesson != null ? lesson.getTitle() : ""; + var lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE); + return lesson != null ? lesson.getTitle() : ""; } - return title; + return ""; } } diff --git a/src/main/java/org/owasp/webgoat/service/ParameterService.java b/src/main/java/org/owasp/webgoat/service/ParameterService.java index db1c3807f..d9ff6ded6 100644 --- a/src/main/java/org/owasp/webgoat/service/ParameterService.java +++ b/src/main/java/org/owasp/webgoat/service/ParameterService.java @@ -51,16 +51,15 @@ public class ParameterService extends BaseService { final Logger logger = LoggerFactory.getLogger(ParameterService.class); /** - * Returns request parameters for last attack + * Retrieves the request parameters for the last attack. * - * @param session - * @return + * @param session the HTTP session object + * @return a sorted list of request parameters */ @RequestMapping(value = "/parameter.mvc", produces = "application/json") - public @ResponseBody - List showParameters(HttpSession session) { - WebSession ws = getWebSession(session); - List listParms = ws.getParmsOnLastRequest(); + public @ResponseBody List showParameters(HttpSession session) { + var ws = getWebSession(session); + var listParms = ws.getParmsOnLastRequest(); Collections.sort(listParms); return listParms; } diff --git a/src/main/java/org/owasp/webgoat/service/RestartLessonService.java b/src/main/java/org/owasp/webgoat/service/RestartLessonService.java index 1f0c994ed..976a21fed 100644 --- a/src/main/java/org/owasp/webgoat/service/RestartLessonService.java +++ b/src/main/java/org/owasp/webgoat/service/RestartLessonService.java @@ -41,18 +41,16 @@ public class RestartLessonService extends BaseService { /** - * Returns current lesson + * Restarts the current lesson. * - * @param session - * @return + * @param session the HTTP session object + * @return the link to the current lesson */ @RequestMapping(value = "/restartlesson.mvc", produces = "text/text") - public @ResponseBody - String restartLesson(HttpSession session) { - WebSession ws = getWebSession(session); - int currentScreen = ws.getCurrentScreen(); - if(currentScreen > 0){ - ws.restartLesson(currentScreen); + public @ResponseBody String restartLesson(HttpSession session) { + var ws = getWebSession(session); + if (ws.getCurrentScreen() > 0) { + ws.restartLesson(ws.getCurrentScreen()); } return ws.getCurrentLesson().getLink(); } diff --git a/src/main/java/org/owasp/webgoat/service/SessionService.java b/src/main/java/org/owasp/webgoat/service/SessionService.java index 6d5810e5b..935be70e3 100644 --- a/src/main/java/org/owasp/webgoat/service/SessionService.java +++ b/src/main/java/org/owasp/webgoat/service/SessionService.java @@ -8,7 +8,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Date; -import java.util.Enumeration; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @@ -24,32 +23,27 @@ public class SessionService extends BaseService { /** - * Returns hints for current lesson + * Displays session details for the current HTTP session. * - * @param session - * @return + * @param request the HTTP request object + * @param session the HTTP session object + * @return a string containing session details */ @RequestMapping(value = "/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 attributes = new ArrayList(); - Enumeration keys = session.getAttributeNames(); - while (keys.hasMoreElements()) { - String name = (String) keys.nextElement(); - attributes.add(name); - } + public @ResponseBody String showSession(HttpServletRequest request, HttpSession session) { + var sb = new StringBuilder(); + sb.append("id = ").append(session.getId()).append("\n") + .append("created = ").append(new Date(session.getCreationTime())).append("\n") + .append("last access = ").append(new Date(session.getLastAccessedTime())).append("\n") + .append("timeout (secs) = ").append(session.getMaxInactiveInterval()).append("\n") + .append("session from cookie? = ").append(request.isRequestedSessionIdFromCookie()).append("\n") + .append("session from url? = ").append(request.isRequestedSessionIdFromURL()).append("\n") + .append("=====================================\n"); + + var attributes = Collections.list(session.getAttributeNames()); Collections.sort(attributes); - for (String attribute : attributes) { - String value = session.getAttribute(attribute) + ""; + for (var attribute : attributes) { + var value = session.getAttribute(attribute) + ""; sb.append(attribute).append(" = ").append(value).append("\n"); } return sb.toString(); diff --git a/src/main/java/org/owasp/webgoat/service/SolutionService.java b/src/main/java/org/owasp/webgoat/service/SolutionService.java index d9db4c626..608e953c7 100644 --- a/src/main/java/org/owasp/webgoat/service/SolutionService.java +++ b/src/main/java/org/owasp/webgoat/service/SolutionService.java @@ -46,37 +46,33 @@ public class SolutionService extends BaseService { /** - * Returns solution for current attack + * Retrieves the solution for the current attack. * - * @param session - * @return + * @param session the HTTP session object + * @return the solution as a string */ @RequestMapping(value = "/solution.mvc", produces = "text/html") - public @ResponseBody - String showSolution(HttpSession session) { - WebSession ws = getWebSession(session); - String source = getSolution(ws); - return source; + public @ResponseBody String showSolution(HttpSession session) { + var ws = getWebSession(session); + return getSolution(ws); } + /** + * Retrieves the solution for the current lesson. + * + * @param s the current web session + * @return the solution as a string, or a message indicating no solution is available + */ protected String getSolution(WebSession s) { - - String source = null; - int scr = s.getCurrentScreen(); - Course course = s.getCourse(); + var scr = s.getCurrentScreen(); + var course = s.getCourse(); if (s.isUser() || s.isChallenge()) { - - AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE); - + var lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE); if (lesson != null) { - source = lesson.getSolution(s); + return lesson.getSolution(s); } } - if (source == null) { - return "Solution is not available. Contact " - + s.getWebgoatContext().getFeedbackAddressHTML(); - } - return (source); + return "Solution is not available. Contact " + s.getWebgoatContext().getFeedbackAddressHTML(); } } diff --git a/src/main/java/org/owasp/webgoat/service/SourceService.java b/src/main/java/org/owasp/webgoat/service/SourceService.java index ae3eaa8c9..309b76f44 100644 --- a/src/main/java/org/owasp/webgoat/service/SourceService.java +++ b/src/main/java/org/owasp/webgoat/service/SourceService.java @@ -48,49 +48,35 @@ public class SourceService extends BaseService { /** - * Returns source for current attack + * Retrieves the source code for the current attack. * - * @param session - * @return + * @param session the HTTP session object + * @return the source code as a string, or a message indicating no source is available */ @RequestMapping(value = "/source.mvc", produces = "application/text") - public @ResponseBody - String showSource(HttpSession session) { - WebSession ws = getWebSession(session); - String source = getSource(ws); - if (source == null) { - source = "No source listing found"; - } - return source; - //SourceListing sl = new SourceListing(); - //sl.setSource(source); - //return sl; + public @ResponseBody String showSource(HttpSession session) { + var ws = getWebSession(session); + var source = getSource(ws); + return source != null ? source : "No source listing found"; } /** - * Description of the Method + * Retrieves the raw source code for the current lesson. * - * @param s Description of the Parameter - * @return Description of the Return Value + * @param s the current web session + * @return the raw source code with omitted sections replaced, or a message indicating no source is available */ protected String getSource(WebSession s) { - - String source = null; - int scr = s.getCurrentScreen(); - Course course = s.getCourse(); + var scr = s.getCurrentScreen(); + var course = s.getCourse(); if (s.isUser() || s.isChallenge()) { - - AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE); - + var lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE); if (lesson != null) { - source = lesson.getRawSource(s); + return lesson.getRawSource(s).replaceAll("(?s)" + START_SOURCE_SKIP + ".*" + END_SOURCE_SKIP, + "Code Section Deliberately Omitted"); } } - if (source == null) { - return "Source code is not available for this lesson."; - } - return (source.replaceAll("(?s)" + START_SOURCE_SKIP + ".*" + END_SOURCE_SKIP, - "Code Section Deliberately Omitted")); + return "Source code is not available for this lesson."; } } diff --git a/src/main/java/org/owasp/webgoat/session/CreateDB.java b/src/main/java/org/owasp/webgoat/session/CreateDB.java index 0e04b2033..eccd58ec5 100644 --- a/src/main/java/org/owasp/webgoat/session/CreateDB.java +++ b/src/main/java/org/owasp/webgoat/session/CreateDB.java @@ -1,11 +1,11 @@ - package org.owasp.webgoat.session; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import org.owasp.webgoat.lessons.AbstractLesson; - +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /*************************************************************************************************** * @@ -36,1003 +36,393 @@ * * @author Jeff Williams Aspect Security */ -public class CreateDB -{ - - /** - * Description of the Method - * - * @param connection - * Description of the Parameter - * - * @exception SQLException - * Description of the Exception - */ - private void createMessageTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - // Drop admin user table - try - { - String dropTable = "DROP TABLE messages"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop message database"); - } - - // Create the new table - try - { - String createTableStatement = "CREATE TABLE messages (" + "num int not null," + "title varchar(50)," - + "message varchar(200)," + "user_name varchar(50) not null, " + "lesson_type varchar(50) not null" - + ")"; - statement.executeUpdate(createTableStatement); - } catch (SQLException e) - { - System.out.println("Error creating message database " + e.getLocalizedMessage()); - } - } - - /** - * Description of the Method - * - * @param connection Description of the Parameter - * - * @exception SQLException Description of the Exception - */ - private void createMFEImagesTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - // Drop mfe_images table - try - { - String dropTable = "DROP TABLE mfe_images"; - statement.executeUpdate(dropTable); - } - catch (SQLException e) - { - System.out.println("Info - Could not drop mfe_images table from database"); - } - - // Create the new mfe_images table - try - { - String createTableStatement = "CREATE TABLE mfe_images (" - + "user_name varchar(50) not null, " - + "image_relative_url varchar(50) not null" - + ")"; - statement.executeUpdate(createTableStatement); - } - catch (SQLException e) - { - System.out.println("Error creating mfe_images table in database " + e.getLocalizedMessage()); - } - +public class CreateDB { + + private static final Logger logger = LoggerFactory.getLogger(CreateDB.class); + + private void createMessageTable(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + + try { + String dropTable = "DROP TABLE messages"; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + logger.info("Could not drop message database: {}", e.getMessage()); + } + + try { + String createTableStatement = "CREATE TABLE messages (" + + "num int not null," + + "title varchar(50)," + + "message varchar(200)," + + "user_name varchar(50) not null, " + + "lesson_type varchar(50) not null" + + ")"; + statement.executeUpdate(createTableStatement); + } catch (SQLException e) { + logger.error("Error creating message database: {}", e.getMessage(), e); + } } - - /** - * Description of the Method - * - * @param connection - * Description of the Parameter - * - * @exception SQLException - * Description of the Exception - */ - private void createProductTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - // Drop admin user table - try - { - String dropTable = "DROP TABLE product_system_data"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop product table"); - } - - // Create the new table - try - { - String createTableStatement = "CREATE TABLE product_system_data (" - + "productid varchar(6) not null primary key," + "product_name varchar(20)," + "price varchar(10)" - + ")"; - statement.executeUpdate(createTableStatement); - } catch (SQLException e) - { - System.out.println("Error creating product table " + e.getLocalizedMessage()); - } - - // Populate - String insertData1 = "INSERT INTO product_system_data VALUES ('32226','Dog Bone','$1.99')"; - String insertData2 = "INSERT INTO product_system_data VALUES ('35632','DVD Player','$214.99')"; - String insertData3 = "INSERT INTO product_system_data VALUES ('24569','60 GB Hard Drive','$149.99')"; - String insertData4 = "INSERT INTO product_system_data VALUES ('56970','80 GB Hard Drive','$179.99')"; - String insertData5 = "INSERT INTO product_system_data VALUES ('14365','56 inch HDTV','$6999.99')"; - statement.executeUpdate(insertData1); - statement.executeUpdate(insertData2); - statement.executeUpdate(insertData3); - statement.executeUpdate(insertData4); - statement.executeUpdate(insertData5); - } - - /** - * Description of the Method - * - * @param connection - * Description of the Parameter - * - * @exception SQLException - * Description of the Exception - */ - private void createUserAdminTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - // Drop admin user table - try - { - String dropTable = "DROP TABLE user_system_data"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop user admin table"); - } - // Create the new table - try - { - String createTableStatement = "CREATE TABLE user_system_data (" + "userid varchar(5) 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', '')"; - statement.executeUpdate(insertData1); - statement.executeUpdate(insertData2); - statement.executeUpdate(insertData3); - statement.executeUpdate(insertData4); - statement.executeUpdate(insertData5); - } - - /** - * Description of the Method - * - * @param connection - * Description of the Parameter - * - * @exception SQLException - * Description of the Exception - */ - private void createUserDataTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - // Delete table if there is one - try - { - String dropTable = "DROP TABLE user_data"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop user table"); - } - - // Create the new table - try - { - String createTableStatement = "CREATE TABLE user_data (" + "userid int not null," - + "first_name varchar(20)," + "last_name varchar(20)," + "cc_number varchar(30)," - + "cc_type varchar(10)," + "cookie varchar(20)," + "login_count int" + ")"; - statement.executeUpdate(createTableStatement); - } catch (SQLException e) - { - System.out.println("Error creating user table " + e.getLocalizedMessage()); - } - - // Populate it - String insertData1 = "INSERT INTO user_data VALUES (101,'Joe','Snow','987654321','VISA',' ',0)"; - String insertData2 = "INSERT INTO user_data VALUES (101,'Joe','Snow','2234200065411','MC',' ',0)"; - String insertData3 = "INSERT INTO user_data VALUES (102,'John','Smith','2435600002222','MC',' ',0)"; - String insertData4 = "INSERT INTO user_data VALUES (102,'John','Smith','4352209902222','AMEX',' ',0)"; - String insertData5 = "INSERT INTO user_data VALUES (103,'Jane','Plane','123456789','MC',' ',0)"; - String insertData6 = "INSERT INTO user_data VALUES (103,'Jane','Plane','333498703333','AMEX',' ',0)"; - String insertData7 = "INSERT INTO user_data VALUES (10312,'Jolly','Hershey','176896789','MC',' ',0)"; - String insertData8 = "INSERT INTO user_data VALUES (10312,'Jolly','Hershey','333300003333','AMEX',' ',0)"; - String insertData9 = "INSERT INTO user_data VALUES (10323,'Grumpy','youaretheweakestlink','673834489','MC',' ',0)"; - String insertData10 = "INSERT INTO user_data VALUES (10323,'Grumpy','youaretheweakestlink','33413003333','AMEX',' ',0)"; - String insertData11 = "INSERT INTO user_data VALUES (15603,'Peter','Sand','123609789','MC',' ',0)"; - String insertData12 = "INSERT INTO user_data VALUES (15603,'Peter','Sand','338893453333','AMEX',' ',0)"; - String insertData13 = "INSERT INTO user_data VALUES (15613,'Joesph','Something','33843453533','AMEX',' ',0)"; - statement.executeUpdate(insertData1); - statement.executeUpdate(insertData2); - statement.executeUpdate(insertData3); - statement.executeUpdate(insertData4); - statement.executeUpdate(insertData5); - statement.executeUpdate(insertData6); - statement.executeUpdate(insertData7); - statement.executeUpdate(insertData8); - statement.executeUpdate(insertData9); - statement.executeUpdate(insertData10); - statement.executeUpdate(insertData11); - statement.executeUpdate(insertData12); - statement.executeUpdate(insertData13); - - } - - private void createLoginTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - // Delete table if there is one - try - { - String dropTable = "DROP TABLE user_login"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop user_login table"); - } - - // Create the new table - try - { - String createTableStatement = "CREATE TABLE user_login (" + "userid varchar(5)," - + "webgoat_user varchar(20)" + ")"; - statement.executeUpdate(createTableStatement); - } catch (SQLException e) - { - System.out.println("Error creating user_login table " + e.getLocalizedMessage()); - } - - } - - // creates the table pins which is used in the blind sql injection lesson - private void createBlindSQLLessonTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - // Delete table if there is one - try - { - String dropTable = "DROP TABLE pins"; - statement.executeUpdate(dropTable); - } - catch (SQLException e) - { - System.out.println("Info - Could not drop pins table"); - } - - // Create the new table - try - { - String createTableStatement = "CREATE TABLE pins (" - + "cc_number varchar(30)," - + "pin int," - + "name varchar(20)" - + ")"; - statement.executeUpdate(createTableStatement); - } - catch (SQLException e) - { - System.out.println("Error creating pins table " + e.getLocalizedMessage()); - } - - // Populate it - String insertData1 = "INSERT INTO pins VALUES ('987654321098765', 1234, 'Joe')"; - String insertData2 = "INSERT INTO pins VALUES ('1234567890123456', 4567, 'Jack')"; - String insertData3 = "INSERT INTO pins VALUES ('4321432143214321', 4321, 'Jill')"; - String insertData4 = "INSERT INTO pins VALUES ('1111111111111111', 7777, 'Jim')"; - String insertData5 = "INSERT INTO pins VALUES ('1111222233334444', 2364, 'John')"; - - statement.executeUpdate(insertData1); - statement.executeUpdate(insertData2); - statement.executeUpdate(insertData3); - statement.executeUpdate(insertData4); - statement.executeUpdate(insertData5); - - } - - // creates the table salaries which is used in the lessons - // which add or modify data using sql injection - private void createModifyWithSQLLessonTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - // Delete table if there is one - try - { - String dropTable = "DROP TABLE salaries"; - statement.executeUpdate(dropTable); - } - catch (SQLException e) - { - System.out.println("Info - Could not drop salaries table"); - } - - // Create the new table - try - { - String createTableStatement = "CREATE TABLE salaries (" - + "userid varchar(50)," - + "salary int" - + ")"; - statement.executeUpdate(createTableStatement); - } - catch (SQLException e) - { - System.out.println("Error creating salaries table " + e.getLocalizedMessage()); - } - - // Populate it - String insertData1 = "INSERT INTO salaries VALUES ('jsmith', 20000)"; - String insertData2 = "INSERT INTO salaries VALUES ('lsmith', 45000)"; - String insertData3 = "INSERT INTO salaries VALUES ('wgoat', 100000)"; - String insertData4 = "INSERT INTO salaries VALUES ('rjones', 777777)"; - String insertData5 = "INSERT INTO salaries VALUES ('manderson', 65000)"; - - statement.executeUpdate(insertData1); - statement.executeUpdate(insertData2); - statement.executeUpdate(insertData3); - statement.executeUpdate(insertData4); - statement.executeUpdate(insertData5); - + private void createMFEImagesTable(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + + try { + String dropTable = "DROP TABLE mfe_images"; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + logger.info("Could not drop mfe_images table: {}", e.getMessage()); + } + + try { + String createTableStatement = "CREATE TABLE mfe_images (" + + "user_name varchar(50) not null, " + + "image_relative_url varchar(50) not null" + + ")"; + statement.executeUpdate(createTableStatement); + } catch (SQLException e) { + logger.error("Error creating mfe_images table: {}", e.getMessage(), e); + } } - - /** - * Description of the Method - * - * @param connection - * Description of the Parameter - * - * @exception SQLException - * Description of the Exception - */ - private void createWeatherDataTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - // Delete table if there is one - try - { - String dropTable = "DROP TABLE weather_data"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop weather table"); - } - - // Create the new table - try - { - String createTableStatement = "CREATE TABLE weather_data (" + "station int not null," - + "name varchar(20) not null," + "state char(2) not null," + "min_temp int not null," - + "max_temp int not null" + ")"; - statement.executeUpdate(createTableStatement); - } catch (SQLException e) - { - System.out.println("Error creating weather table " + e.getLocalizedMessage()); - } - - // Populate it - String insertData1 = "INSERT INTO weather_data VALUES (101,'Columbia','MD',-10,102)"; - String insertData2 = "INSERT INTO weather_data VALUES (102,'Seattle','WA',-15,90)"; - String insertData3 = "INSERT INTO weather_data VALUES (103,'New York','NY',-10,110)"; - String insertData4 = "INSERT INTO weather_data VALUES (104,'Houston','TX',20,120)"; - String insertData5 = "INSERT INTO weather_data VALUES (10001,'Camp David','MD',-10,100)"; - String insertData6 = "INSERT INTO weather_data VALUES (11001,'Ice Station Zebra','NA',-60,30)"; - statement.executeUpdate(insertData1); - statement.executeUpdate(insertData2); - statement.executeUpdate(insertData3); - statement.executeUpdate(insertData4); - statement.executeUpdate(insertData5); - statement.executeUpdate(insertData6); - } - - /** - * Create users with tans - * - * @param connection - * @throws SQLException - */ - private void createTanUserDataTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - // Delete table if there is one - try - { - String dropTable = "DROP TABLE user_data_tan"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop user_data_tan table"); - } - - // Create the new table - try - { - String createTableStatement = "CREATE TABLE user_data_tan (" + "userid int not null," - + "first_name varchar(20)," + "last_name varchar(20)," + "cc_number varchar(30)," - + "cc_type varchar(10)," + "cookie varchar(20)," + "login_count int," + "password varchar(20)" - + ")"; - statement.executeUpdate(createTableStatement); - } catch (SQLException e) - { - System.out.println("Error creating user_data_tan table " + e.getLocalizedMessage()); - } - - // Populate it - String insertData1 = "INSERT INTO user_data_tan VALUES (101,'Joe','Snow','987654321','VISA',' ',0, 'banana')"; - String insertData2 = "INSERT INTO user_data_tan VALUES (102,'Jane','Plane','74589864','MC',' ',0, 'tarzan')"; - String insertData3 = "INSERT INTO user_data_tan VALUES (103,'Jack','Sparrow','68659365','MC',' ',0, 'sniffy')"; - - statement.executeUpdate(insertData1); - statement.executeUpdate(insertData2); - statement.executeUpdate(insertData3); - } - - /** - * Create the Table for the tans - * - * @param connection - * @throws SQLException - */ - private void createTanTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - // Delete table if there is one - try - { - String dropTable = "DROP TABLE tan"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop tan table"); - } - - // Create the new table - try - { - String createTableStatement = "CREATE TABLE tan (" + "userid int not null," + "tanNr int," + "tanValue int" - + ")"; - statement.executeUpdate(createTableStatement); - } catch (SQLException e) - { - System.out.println("Error creating tan table " + e.getLocalizedMessage()); - } - - // Populate it - String insertData1 = "INSERT INTO tan VALUES (101,1,15161)"; - String insertData2 = "INSERT INTO tan VALUES (101,2,4894)"; - String insertData3 = "INSERT INTO tan VALUES (101,3,18794)"; - String insertData4 = "INSERT INTO tan VALUES (101,4,1564)"; - String insertData5 = "INSERT INTO tan VALUES (101,5,45751)"; - - String insertData6 = "INSERT INTO tan VALUES (102,1,15648)"; - String insertData7 = "INSERT INTO tan VALUES (102,2,92156)"; - String insertData8 = "INSERT INTO tan VALUES (102,3,4879)"; - String insertData9 = "INSERT INTO tan VALUES (102,4,9458)"; - String insertData10 = "INSERT INTO tan VALUES (102,5,4879)"; - - statement.executeUpdate(insertData1); - statement.executeUpdate(insertData2); - statement.executeUpdate(insertData3); - statement.executeUpdate(insertData4); - statement.executeUpdate(insertData5); - statement.executeUpdate(insertData6); - statement.executeUpdate(insertData7); - statement.executeUpdate(insertData8); - statement.executeUpdate(insertData9); - statement.executeUpdate(insertData10); - - } - - // -------------------------------------------------------------------------- - // -------------------------------------------------------------------------- - // - // The tables below are for WebGoat Financials - // - // DO NOT MODIFY THESE TABLES - unless you change the org chart - // and access control matrix documents - // - // -------------------------------------------------------------------------- - // -------------------------------------------------------------------------- - - private void createEmployeeTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - try - { - String dropTable = "DROP TABLE employee"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop employee table"); - } - - // Create Table - try - { - String createTable = "CREATE TABLE employee (" - // + "userid INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY," - + "userid INT NOT NULL PRIMARY KEY," + "first_name VARCHAR(20)," + "last_name VARCHAR(20)," - + "ssn VARCHAR(12)," + "password VARCHAR(10)," + "title VARCHAR(20)," + "phone VARCHAR(13)," - + "address1 VARCHAR(80)," + "address2 VARCHAR(80)," + "manager INT," + "start_date CHAR(8)," - + "salary INT," + "ccn VARCHAR(30)," + "ccn_limit INT," + "email VARCHAR(30)," // reason - // for the recent write-up - + "disciplined_date CHAR(8)," // date of write up, NA otherwise - + "disciplined_notes VARCHAR(60)," // reason for the recent write-up - + "personal_description VARCHAR(60)" // We can be rude here - // + ",CONSTRAINT fl UNIQUE NONCLUSTERED (first_name, last_name)" - + ")"; - - statement.executeUpdate(createTable); - } catch (SQLException e) - { - System.out.println("Error: unable to create employee table " + e.getLocalizedMessage()); - } - - String insertData1 = "INSERT INTO employee VALUES (101, 'Larry', 'Stooge', '386-09-5451', 'larry'," - + "'Technician','443-689-0192','9175 Guilford Rd','New York, NY', 102, 01012000,55000,'2578546969853547'," - + "5000,'larry@stooges.com',010106,'Constantly harassing coworkers','Does not work well with others')"; - - String insertData2 = "INSERT INTO employee VALUES (102, 'Moe', 'Stooge', '936-18-4524','moe'," - + "'CSO','443-938-5301', '3013 AMD Ave', 'New York, NY', 112, 03082003, 140000, 'NA', 0, 'moe@stooges.com', 0101013, " - + "'Hit Curly over head', 'Very dominating over Larry and Curly')"; - - String insertData3 = "INSERT INTO employee VALUES (103, 'Curly', 'Stooge', '961-08-0047','curly'," - + "'Technician','410-667-6654', '1112 Crusoe Lane', 'New York, NY', 102, 02122001, 50000, 'NA', 0, 'curly@stooges.com', 0101014, " - + "'Hit Moe back', 'Owes three-thousand to company for fradulent purchases')"; - - String insertData4 = "INSERT INTO employee VALUES (104, 'Eric', 'Walker', '445-66-5565','eric'," - + "'Engineer','410-887-1193', '1160 Prescott Rd', 'New York, NY', 107, 12152005, 13000, 'NA', 0, 'eric@modelsrus.com',0101013, " - + "'Bothering Larry about webgoat problems', 'Late. Always needs help. Too intern-ish.')"; - String insertData5 = "INSERT INTO employee VALUES (105, 'Tom', 'Cat', '792-14-6364','tom'," - + "'Engineer','443-599-0762', '2211 HyperThread Rd.', 'New York, NY', 106, 01011999, 80000, '5481360857968521', 30000, 'tom@wb.com', 0, " - + "'NA', 'Co-Owner.')"; - - String insertData6 = "INSERT INTO employee VALUES (106, 'Jerry', 'Mouse', '858-55-4452','jerry'," - + "'Human Resources','443-699-3366', '3011 Unix Drive', 'New York, NY', 102, 01011999, 70000, '6981754825013564', 20000, 'jerry@wb.com', 0, " - + "'NA', 'Co-Owner.')"; - - String insertData7 = "INSERT INTO employee VALUES (107, 'David', 'Giambi', '439-20-9405','david'," - + "'Human Resources','610-521-8413', '5132 DIMM Avenue', 'New York, NY', 102, 05011999, 100000, '6981754825018101', 10000, 'david@modelsrus.com', 061402, " - + "'Hacked into accounting server. Modified personal pay.', 'Strong work habbit. Questionable ethics.')"; - - String insertData8 = "INSERT INTO employee VALUES (108, 'Bruce', 'McGuirre', '707-95-9482','bruce'," - + "'Engineer','610-282-1103', '8899 FreeBSD Drive ', 'New York, NY', 107, 03012000, 110000, '6981754825854136', 30000, 'bruce@modelsrus.com', 061502, " - + "'Tortuous Boot Camp workout at 5am. Employees felt sick.', 'Enjoys watching others struggle in exercises.')"; - - String insertData9 = "INSERT INTO employee VALUES (109, 'Sean', 'Livingston', '136-55-1046','sean'," - + "'Engineer','610-878-9549', '6422 dFlyBSD Road', 'New York, NY', 107, 06012003, 130000, '6981754825014510', 5000, 'sean@modelsrus.com', 072804, " - + "'Late to work 30 days in row due to excessive Halo 2', 'Has some fascination with Steelers. Go Ravens.')"; - - String insertData10 = "INSERT INTO employee VALUES (110, 'Joanne', 'McDougal', '789-54-2413','joanne'," - + "'Human Resources','610-213-6341', '5567 Broadband Lane', 'New York, NY', 106, 01012001, 90000, '6981754825081054', 300, 'joanne@modelsrus.com', 112005, " - + "'Used company cc to purchase new car. Limit adjusted.', 'Finds it necessary to leave early every day.')"; - - String insertData11 = "INSERT INTO employee VALUES (111, 'John', 'Wayne', '129-69-4572', 'john'," - + "'CTO','610-213-1134', '129 Third St', 'New York, NY', 112, 01012001, 200000, '4437334565679921', 300, 'john@guns.com', 112005, " - + "'', '')"; - String insertData12 = "INSERT INTO employee VALUES (112, 'Neville', 'Bartholomew', '111-111-1111', 'socks'," - + "'CEO','408-587-0024', '1 Corporate Headquarters', 'San Jose, CA', 112, 03012000, 450000, '4803389267684109', 300000, 'neville@modelsrus.com', 112005, " - + "'', '')"; - - statement.executeUpdate(insertData1); - statement.executeUpdate(insertData2); - statement.executeUpdate(insertData3); - statement.executeUpdate(insertData4); - statement.executeUpdate(insertData5); - statement.executeUpdate(insertData6); - statement.executeUpdate(insertData7); - statement.executeUpdate(insertData8); - statement.executeUpdate(insertData9); - statement.executeUpdate(insertData10); - statement.executeUpdate(insertData11); - statement.executeUpdate(insertData12); - - } - - private void createRolesTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - try - { - String dropTable = "DROP TABLE roles"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop roles table"); - } - - try - { - String createTable = "CREATE TABLE roles (" + "userid INT NOT NULL," + "role VARCHAR(10) NOT NULL," - + "PRIMARY KEY (userid, role)" + ")"; - - statement.executeUpdate(createTable); - } catch (SQLException e) - { - System.out.println("Error: Unable to create role table: " + e.getLocalizedMessage()); - } - - String insertData1 = "INSERT INTO roles VALUES (101, 'employee')"; - String insertData2 = "INSERT INTO roles VALUES (102, 'manager')"; - String insertData3 = "INSERT INTO roles VALUES (103, 'employee')"; - String insertData4 = "INSERT INTO roles VALUES (104, 'employee')"; - String insertData5 = "INSERT INTO roles VALUES (105, 'employee')"; - String insertData6 = "INSERT INTO roles VALUES (106, 'hr')"; - String insertData7 = "INSERT INTO roles VALUES (107, 'manager')"; - String insertData8 = "INSERT INTO roles VALUES (108, 'employee')"; - String insertData9 = "INSERT INTO roles VALUES (109, 'employee')"; - String insertData10 = "INSERT INTO roles VALUES (110, 'hr')"; - String insertData11 = "INSERT INTO roles VALUES (111, 'admin')"; - String insertData12 = "INSERT INTO roles VALUES (112, 'admin')"; - - statement.executeUpdate(insertData1); - statement.executeUpdate(insertData2); - statement.executeUpdate(insertData3); - statement.executeUpdate(insertData4); - statement.executeUpdate(insertData5); - statement.executeUpdate(insertData6); - statement.executeUpdate(insertData7); - statement.executeUpdate(insertData8); - statement.executeUpdate(insertData9); - statement.executeUpdate(insertData10); - statement.executeUpdate(insertData11); - statement.executeUpdate(insertData12); - } - - private void createAuthTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - try - { - String dropTable = "DROP TABLE auth"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop auth table"); - } - - try - { - String createTable = "CREATE TABLE auth (" + "role VARCHAR(10) NOT NULL," - + "functionid VARCHAR(20) NOT NULL," + "PRIMARY KEY (role, functionid)" + ")"; - - statement.executeUpdate(createTable); - } catch (SQLException e) - { - System.out.println("Error: unable to create auth table: " + e.getLocalizedMessage()); - } - - String insertData1 = "INSERT INTO auth VALUES('employee', 'Logout')"; - String insertData2 = "INSERT INTO auth VALUES('employee', 'ListStaff')"; - String insertData3 = "INSERT INTO auth VALUES('employee', 'ViewProfile')"; - String insertData4 = "INSERT INTO auth VALUES('employee', 'EditProfile')"; - String insertData4_1 = "INSERT INTO auth VALUES('employee', 'SearchStaff')"; - String insertData4_2 = "INSERT INTO auth VALUES('employee', 'FindProfile')"; - String insertData5 = "INSERT INTO auth VALUES('manager', 'Logout')"; - String insertData6 = "INSERT INTO auth VALUES('manager', 'ListStaff')"; - String insertData7 = "INSERT INTO auth VALUES('manager', 'ViewProfile')"; - String insertData7_1 = "INSERT INTO auth VALUES('manager', 'SearchStaff')"; - String insertData7_2 = "INSERT INTO auth VALUES('manager', 'FindProfile')"; - // String insertData8 = "INSERT INTO auth VALUES('manager', 'EditProfile')"; - // String insertData9 = "INSERT INTO auth VALUES('manager', 'CreateProfile')"; - // String insertData10 = "INSERT INTO auth VALUES('manager', 'DeleteProfile')"; - // String insertData11 = "INSERT INTO auth VALUES('manager', 'UpdateProfile')"; - String insertData12 = "INSERT INTO auth VALUES('hr', 'Logout')"; - String insertData13 = "INSERT INTO auth VALUES('hr', 'ListStaff')"; - String insertData14 = "INSERT INTO auth VALUES('hr', 'ViewProfile')"; - String insertData15 = "INSERT INTO auth VALUES('hr', 'EditProfile')"; - String insertData16 = "INSERT INTO auth VALUES('hr', 'CreateProfile')"; - String insertData17 = "INSERT INTO auth VALUES('hr', 'DeleteProfile')"; - String insertData18 = "INSERT INTO auth VALUES('hr', 'UpdateProfile')"; - String insertData18_1 = "INSERT INTO auth VALUES('hr', 'SearchStaff')"; - String insertData18_2 = "INSERT INTO auth VALUES('hr', 'FindProfile')"; - String insertData19 = "INSERT INTO auth VALUES('admin', 'Logout')"; - String insertData20 = "INSERT INTO auth VALUES('admin', 'ListStaff')"; - String insertData21 = "INSERT INTO auth VALUES('admin', 'ViewProfile')"; - String insertData22 = "INSERT INTO auth VALUES('admin', 'EditProfile')"; - String insertData23 = "INSERT INTO auth VALUES('admin', 'CreateProfile')"; - String insertData24 = "INSERT INTO auth VALUES('admin', 'DeleteProfile')"; - String insertData25 = "INSERT INTO auth VALUES('admin', 'UpdateProfile')"; - String insertData25_1 = "INSERT INTO auth VALUES('admin', 'SearchStaff')"; - String insertData25_2 = "INSERT INTO auth VALUES('admin', 'FindProfile')"; - - // Add a permission for the webgoat role to see the source. - // The challenge(s) will change the default role to "challenge" - String insertData26 = "INSERT INTO auth VALUES('" + AbstractLesson.USER_ROLE + "','" + WebSession.SHOWSOURCE - + "')"; - String insertData27 = "INSERT INTO auth VALUES('" + AbstractLesson.USER_ROLE + "','" + WebSession.SHOWHINTS - + "')"; - // Add a permission for the webgoat role to see the solution. - // The challenge(s) will change the default role to "challenge" - String insertData28 = "INSERT INTO auth VALUES('" + AbstractLesson.USER_ROLE + "','" + WebSession.SHOWSOLUTION - + "')"; - - statement.executeUpdate(insertData1); - statement.executeUpdate(insertData2); - statement.executeUpdate(insertData3); - statement.executeUpdate(insertData4); - statement.executeUpdate(insertData4_1); - statement.executeUpdate(insertData4_2); - statement.executeUpdate(insertData5); - statement.executeUpdate(insertData6); - statement.executeUpdate(insertData7); - statement.executeUpdate(insertData7_1); - statement.executeUpdate(insertData7_2); - // statement.executeUpdate(insertData8); - // statement.executeUpdate(insertData9); - // statement.executeUpdate(insertData10); - // statement.executeUpdate(insertData11); - statement.executeUpdate(insertData12); - statement.executeUpdate(insertData13); - statement.executeUpdate(insertData14); - statement.executeUpdate(insertData15); - statement.executeUpdate(insertData16); - statement.executeUpdate(insertData17); - statement.executeUpdate(insertData18); - statement.executeUpdate(insertData18_1); - statement.executeUpdate(insertData18_2); - statement.executeUpdate(insertData19); - statement.executeUpdate(insertData20); - statement.executeUpdate(insertData21); - statement.executeUpdate(insertData22); - statement.executeUpdate(insertData23); - statement.executeUpdate(insertData24); - statement.executeUpdate(insertData25); - statement.executeUpdate(insertData25_1); - statement.executeUpdate(insertData25_2); - statement.executeUpdate(insertData26); - statement.executeUpdate(insertData27); - statement.executeUpdate(insertData28); - } - - private void createOwnershipTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); - - try - { - String dropTable = "DROP TABLE ownership"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop ownership table"); - } - - try - { - String createTable = "CREATE TABLE ownership (" + "employer_id INT NOT NULL," + "employee_id INT NOT NULL," - + "PRIMARY KEY (employee_id, employer_id)" + ")"; - - statement.executeUpdate(createTable); - } catch (SQLException e) - { - System.out.println("Error: unable to create ownership table: " + e.getLocalizedMessage()); - } - - String inputData = "INSERT INTO ownership VALUES (112, 101)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (112, 102)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (112, 103)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (112, 104)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (112, 105)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (112, 106)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (112, 107)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (112, 108)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (112, 109)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (112, 110)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (112, 111)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (112, 112)"; - statement.executeUpdate(inputData); - - inputData = "INSERT INTO ownership VALUES (102, 101)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (102, 102)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (102, 103)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (102, 104)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (102, 105)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (102, 106)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (102, 107)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (102, 108)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (102, 109)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (102, 110)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (102, 111)"; - statement.executeUpdate(inputData); - - inputData = "INSERT INTO ownership VALUES (111, 101)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (111, 102)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (111, 103)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (111, 104)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (111, 105)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (111, 106)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (111, 107)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (111, 108)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (111, 109)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (111, 110)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (111, 111)"; - statement.executeUpdate(inputData); - - inputData = "INSERT INTO ownership VALUES (106, 105)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (106, 106)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (106, 110)"; - statement.executeUpdate(inputData); - - inputData = "INSERT INTO ownership VALUES (101, 101)"; - statement.executeUpdate(inputData); - - inputData = "INSERT INTO ownership VALUES (103, 103)"; - statement.executeUpdate(inputData); - - inputData = "INSERT INTO ownership VALUES (107, 104)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (107, 108)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (107, 109)"; - statement.executeUpdate(inputData); - inputData = "INSERT INTO ownership VALUES (107, 107)"; - statement.executeUpdate(inputData); - - inputData = "INSERT INTO ownership VALUES (105, 105)"; - statement.executeUpdate(inputData); - - inputData = "INSERT INTO ownership VALUES (110, 110)"; - statement.executeUpdate(inputData); - - inputData = "INSERT INTO ownership VALUES (104, 104)"; - statement.executeUpdate(inputData); - - inputData = "INSERT INTO ownership VALUES (108, 108)"; - statement.executeUpdate(inputData); - - inputData = "INSERT INTO ownership VALUES (109, 109)"; - statement.executeUpdate(inputData); + private void createProductTable(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + + try { + String dropTable = "DROP TABLE product_system_data"; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + logger.info("Could not drop product table: {}", e.getMessage()); + } + + try { + String createTableStatement = "CREATE TABLE product_system_data (" + + "productid varchar(6) not null primary key," + + "product_name varchar(20)," + + "price varchar(10)" + + ")"; + statement.executeUpdate(createTableStatement); + } catch (SQLException e) { + logger.error("Error creating product table: {}", e.getMessage(), e); + } + + String insertData1 = "INSERT INTO product_system_data VALUES ('32226','Dog Bone','$1.99')"; + String insertData2 = "INSERT INTO product_system_data VALUES ('35632','DVD Player','$214.99')"; + String insertData3 = "INSERT INTO product_system_data VALUES ('24569','60 GB Hard Drive','$149.99')"; + String insertData4 = "INSERT INTO product_system_data VALUES ('56970','80 GB Hard Drive','$179.99')"; + String insertData5 = "INSERT INTO product_system_data VALUES ('14365','56 inch HDTV','$6999.99')"; + statement.executeUpdate(insertData1); + statement.executeUpdate(insertData2); + statement.executeUpdate(insertData3); + statement.executeUpdate(insertData4); + statement.executeUpdate(insertData5); + } - } + private void createUserAdminTable(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + + try { + String dropTable = "DROP TABLE user_system_data"; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + logger.info("Could not drop user admin table: {}", e.getMessage()); + } + + try { + String createTableStatement = "CREATE TABLE user_system_data (" + + "userid varchar(5) not null primary key," + + "user_name varchar(12)," + + "password varchar(10)," + + "cookie varchar(30)" + + ")"; + statement.executeUpdate(createTableStatement); + } catch (SQLException e) { + logger.error("Error creating user admin table: {}", e.getMessage(), e); + } + + 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', '')"; + statement.executeUpdate(insertData1); + statement.executeUpdate(insertData2); + statement.executeUpdate(insertData3); + statement.executeUpdate(insertData4); + statement.executeUpdate(insertData5); + } - // -------------------------------------------------------------------------- - // - // End of WebGoat Financials - // - // -------------------------------------------------------------------------- + private void createUserDataTable(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + + try { + String dropTable = "DROP TABLE user_data"; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + logger.info("Could not drop user table: {}", e.getMessage()); + } + + try { + String createTableStatement = "CREATE TABLE user_data (" + + "userid int not null," + + "first_name varchar(20)," + + "last_name varchar(20)," + + "cc_number varchar(30)," + + "cc_type varchar(10)," + + "cookie varchar(20)," + + "login_count int" + + ")"; + statement.executeUpdate(createTableStatement); + } catch (SQLException e) { + logger.error("Error creating user table: {}", e.getMessage(), e); + } + + String insertData1 = "INSERT INTO user_data VALUES (101,'Joe','Snow','987654321','VISA',' ',0)"; + String insertData2 = "INSERT INTO user_data VALUES (101,'Joe','Snow','2234200065411','MC',' ',0)"; + String insertData3 = "INSERT INTO user_data VALUES (102,'John','Smith','2435600002222','MC',' ',0)"; + String insertData4 = "INSERT INTO user_data VALUES (102,'John','Smith','4352209902222','AMEX',' ',0)"; + String insertData5 = "INSERT INTO user_data VALUES (103,'Jane','Plane','123456789','MC',' ',0)"; + String insertData6 = "INSERT INTO user_data VALUES (103,'Jane','Plane','333498703333','AMEX',' ',0)"; + String insertData7 = "INSERT INTO user_data VALUES (10312,'Jolly','Hershey','176896789','MC',' ',0)"; + String insertData8 = "INSERT INTO user_data VALUES (10312,'Jolly','Hershey','333300003333','AMEX',' ',0)"; + String insertData9 = "INSERT INTO user_data VALUES (10323,'Grumpy','youaretheweakestlink','673834489','MC',' ',0)"; + String insertData10 = "INSERT INTO user_data VALUES (10323,'Grumpy','youaretheweakestlink','33413003333','AMEX',' ',0)"; + String insertData11 = "INSERT INTO user_data VALUES (15603,'Peter','Sand','123609789','MC',' ',0)"; + String insertData12 = "INSERT INTO user_data VALUES (15603,'Peter','Sand','338893453333','AMEX',' ',0)"; + String insertData13 = "INSERT INTO user_data VALUES (15613,'Joesph','Something','33843453533','AMEX',' ',0)"; + statement.executeUpdate(insertData1); + statement.executeUpdate(insertData2); + statement.executeUpdate(insertData3); + statement.executeUpdate(insertData4); + statement.executeUpdate(insertData5); + statement.executeUpdate(insertData6); + statement.executeUpdate(insertData7); + statement.executeUpdate(insertData8); + statement.executeUpdate(insertData9); + statement.executeUpdate(insertData10); + statement.executeUpdate(insertData11); + statement.executeUpdate(insertData12); + statement.executeUpdate(insertData13); + } - /** - * Start creation of data for WebServices labs - */ + private void createLoginTable(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + + try { + String dropTable = "DROP TABLE user_login"; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + logger.info("Could not drop user_login table: {}", e.getMessage()); + } + + try { + String createTableStatement = "CREATE TABLE user_login (" + + "userid varchar(5)," + + "webgoat_user varchar(20)" + + ")"; + statement.executeUpdate(createTableStatement); + } catch (SQLException e) { + logger.error("Error creating user_login table: {}", e.getMessage(), e); + } + } - private void createTransactionTable(Connection connection) throws SQLException - { - Statement statement = connection.createStatement(); + private void createBlindSQLLessonTable(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + + try { + String dropTable = "DROP TABLE pins"; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + logger.info("Could not drop pins table: {}", e.getMessage()); + } + + try { + String createTableStatement = "CREATE TABLE pins (" + + "cc_number varchar(30)," + + "pin int," + + "name varchar(20)" + + ")"; + statement.executeUpdate(createTableStatement); + } catch (SQLException e) { + logger.error("Error creating pins table: {}", e.getMessage(), e); + } + + String insertData1 = "INSERT INTO pins VALUES ('987654321098765', 1234, 'Joe')"; + String insertData2 = "INSERT INTO pins VALUES ('1234567890123456', 4567, 'Jack')"; + String insertData3 = "INSERT INTO pins VALUES ('4321432143214321', 4321, 'Jill')"; + String insertData4 = "INSERT INTO pins VALUES ('1111111111111111', 7777, 'Jim')"; + String insertData5 = "INSERT INTO pins VALUES ('1111222233334444', 2364, 'John')"; + statement.executeUpdate(insertData1); + statement.executeUpdate(insertData2); + statement.executeUpdate(insertData3); + statement.executeUpdate(insertData4); + statement.executeUpdate(insertData5); + } - try - { - String dropTable = "DROP TABLE transactions"; - statement.executeUpdate(dropTable); - } catch (SQLException e) - { - System.out.println("Info - Could not drop transactions table"); - } + private void createModifyWithSQLLessonTable(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + + try { + String dropTable = "DROP TABLE salaries"; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + logger.info("Could not drop salaries table: {}", e.getMessage()); + } + + try { + String createTableStatement = "CREATE TABLE salaries (" + + "userid varchar(50)," + + "salary int" + + ")"; + statement.executeUpdate(createTableStatement); + } catch (SQLException e) { + logger.error("Error creating salaries table: {}", e.getMessage(), e); + } + + String insertData1 = "INSERT INTO salaries VALUES ('jsmith', 20000)"; + String insertData2 = "INSERT INTO salaries VALUES ('lsmith', 45000)"; + String insertData3 = "INSERT INTO salaries VALUES ('wgoat', 100000)"; + String insertData4 = "INSERT INTO salaries VALUES ('rjones', 777777)"; + String insertData5 = "INSERT INTO salaries VALUES ('manderson', 65000)"; + statement.executeUpdate(insertData1); + statement.executeUpdate(insertData2); + statement.executeUpdate(insertData3); + statement.executeUpdate(insertData4); + statement.executeUpdate(insertData5); + } - try - { - String createTable = "CREATE TABLE Transactions (" + "userName VARCHAR(16) NOT NULL, " - + "sequence INTEGER NOT NULL, " + "from_account VARCHAR(16) NOT NULL, " - + "to_account VARCHAR(16) NOT NULL, " + "transactionDate TIMESTAMP NOT NULL, " - + "description VARCHAR(255) NOT NULL, " + "amount INTEGER NOT NULL" + ")"; + private void createWeatherDataTable(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + + try { + String dropTable = "DROP TABLE weather_data"; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + logger.info("Could not drop weather table: {}", e.getMessage()); + } + + try { + String createTableStatement = "CREATE TABLE weather_data (" + + "station int not null," + + "name varchar(20) not null," + + "state char(2) not null," + + "min_temp int not null," + + "max_temp int not null" + + ")"; + statement.executeUpdate(createTableStatement); + } catch (SQLException e) { + logger.error("Error creating weather table: {}", e.getMessage(), e); + } + + String insertData1 = "INSERT INTO weather_data VALUES (101,'Columbia','MD',-10,102)"; + String insertData2 = "INSERT INTO weather_data VALUES (102,'Seattle','WA',-15,90)"; + String insertData3 = "INSERT INTO weather_data VALUES (103,'New York','NY',-10,110)"; + String insertData4 = "INSERT INTO weather_data VALUES (104,'Houston','TX',20,120)"; + String insertData5 = "INSERT INTO weather_data VALUES (10001,'Camp David','MD',-10,100)"; + String insertData6 = "INSERT INTO weather_data VALUES (11001,'Ice Station Zebra','NA',-60,30)"; + statement.executeUpdate(insertData1); + statement.executeUpdate(insertData2); + statement.executeUpdate(insertData3); + statement.executeUpdate(insertData4); + statement.executeUpdate(insertData5); + statement.executeUpdate(insertData6); + } - statement.executeUpdate(createTable); - } catch (SQLException e) - { - System.out.println("Error: unable to create transactions table: " + e.getLocalizedMessage()); - throw e; - } + private void createTanUserDataTable(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + + try { + String dropTable = "DROP TABLE user_data_tan"; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + logger.info("Could not drop user_data_tan table: {}", e.getMessage()); + } + + try { + String createTableStatement = "CREATE TABLE user_data_tan (" + + "userid int not null," + + "first_name varchar(20)," + + "last_name varchar(20)," + + "cc_number varchar(30)," + + "cc_type varchar(10)," + + "cookie varchar(20)," + + "login_count int," + + "password varchar(20)" + + ")"; + statement.executeUpdate(createTableStatement); + } catch (SQLException e) { + logger.error("Error creating user_data_tan table: {}", e.getMessage(), e); + } + + String insertData1 = "INSERT INTO user_data_tan VALUES (101,'Joe','Snow','987654321','VISA',' ',0, 'banana')"; + String insertData2 = "INSERT INTO user_data_tan VALUES (102,'Jane','Plane','74589864','MC',' ',0, 'tarzan')"; + String insertData3 = "INSERT INTO user_data_tan VALUES (103,'Jack','Sparrow','68659365','MC',' ',0, 'sniffy')"; + statement.executeUpdate(insertData1); + statement.executeUpdate(insertData2); + statement.executeUpdate(insertData3); + } - String[] data = new String[] { - "'dave', 0, '238-4723-4024', '324-7635-9867', '2008-02-06 21:40:00', 'Mortgage', '150'", - "'dave', 1, '238-4723-4024', '324-7635-9867', '2008-02-12 21:41:00', 'Car', '150'", - "'dave', 2, '238-4723-4024', '324-7635-9867', '2008-02-20 21:42:00', 'School fees', '150'", - "'CEO', 3, '348-6324-9872', '345-3490-8345', '2008-02-15 21:40:00', 'Rolls Royce', '-150000'", - "'CEO', 4, '348-6324-9872', '342-5893-4503', '2008-02-25 21:41:00', 'Mansion', '-150000'", - "'CEO', 5, '348-6324-9872', '980-2344-5492', '2008-02-27 21:42:00', 'Vacation', '-150000'", - "'jeff', 6, '934-2002-3485', '783-2409-8234', '2008-02-01 21:40:00', 'Vet', '250'", - "'jeff', 7, '934-2002-3485', '634-5879-0345', '2008-02-19 21:41:00', 'Doctor', '800'", - "'jeff', 8, '934-2002-3485', '435-4325-3358', '2008-02-20 21:42:00', 'X-rays', '200'", }; - try - { - for (int i = 0; i < data.length; i++) - { - statement.executeUpdate("INSERT INTO Transactions VALUES (" + data[i] + ");"); - } - } catch (SQLException sqle) - { - System.out.println("Error: Unable to insert transactions: " + sqle.getLocalizedMessage()); - int errorCode = sqle.getErrorCode(); - System.out.println("Error Code: " + errorCode); - // ignore exceptions for Oracle and SQL Server - if (errorCode != 911 && errorCode != 273) { throw sqle; } - } - } + private void createTanTable(Connection connection) throws SQLException { + Statement statement = connection.createStatement(); + + try { + String dropTable = "DROP TABLE tan"; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + logger.info("Could not drop tan table: {}", e.getMessage()); + } + + try { + String createTableStatement = "CREATE TABLE tan (" + + "userid int not null," + + "tanNr int," + + "tanValue int" + + ")"; + statement.executeUpdate(createTableStatement); + } catch (SQLException e) { + logger.error("Error creating tan table: {}", e.getMessage(), e); + } + + String insertData1 = "INSERT INTO tan VALUES (101,1,15161)"; + String insertData2 = "INSERT INTO tan VALUES (101,2,4894)"; + String insertData3 = "INSERT INTO tan VALUES (101,3,18794)"; + String insertData4 = "INSERT INTO tan VALUES (101,4,1564)"; + String insertData5 = "INSERT INTO tan VALUES (101,5,45751)"; + String insertData6 = "INSERT INTO tan VALUES (102,1,15648)"; + String insertData7 = "INSERT INTO tan VALUES (102,2,92156)"; + String insertData8 = "INSERT INTO tan VALUES (102,3,4879)"; + String insertData9 = "INSERT INTO tan VALUES (102,4,9458)"; + String insertData10 = "INSERT INTO tan VALUES (102,5,4879)"; + statement.executeUpdate(insertData1); + statement.executeUpdate(insertData2); + statement.executeUpdate(insertData3); + statement.executeUpdate(insertData4); + statement.executeUpdate(insertData5); + statement.executeUpdate(insertData6); + statement.executeUpdate(insertData7); + statement.executeUpdate(insertData8); + statement.executeUpdate(insertData9); + statement.executeUpdate(insertData10); + } - /** - * Description of the Method - * - * @param connection - * Description of the Parameter - * - * @exception SQLException - * Description of the Exception - */ - public void makeDB(Connection connection) throws SQLException - { - System.out.println("Successful connection to database"); - createUserDataTable(connection); - createLoginTable(connection); - createBlindSQLLessonTable(connection); - createUserAdminTable(connection); - createProductTable(connection); - createMessageTable(connection); - createEmployeeTable(connection); - createRolesTable(connection); - createAuthTable(connection); - createOwnershipTable(connection); - createWeatherDataTable(connection); - createTransactionTable(connection); - createTanUserDataTable(connection); - createTanTable(connection); - createMFEImagesTable(connection); - createModifyWithSQLLessonTable(connection); - System.out.println("Success: creating tables."); - } + public void makeDB(Connection connection) throws SQLException { + logger.info("Successful connection to database"); + createUserDataTable(connection); + createLoginTable(connection); + createBlindSQLLessonTable(connection); + createUserAdminTable(connection); + createProductTable(connection); + createMessageTable(connection); + createEmployeeTable(connection); + createRolesTable(connection); + createAuthTable(connection); + createOwnershipTable(connection); + createWeatherDataTable(connection); + createTransactionTable(connection); + createTanUserDataTable(connection); + createTanTable(connection); + createMFEImagesTable(connection); + createModifyWithSQLLessonTable(connection); + logger.info("Success: creating tables."); + } } diff --git a/src/main/java/org/owasp/webgoat/session/DatabaseUtilities.java b/src/main/java/org/owasp/webgoat/session/DatabaseUtilities.java index 1a9638a3b..84bb5f354 100644 --- a/src/main/java/org/owasp/webgoat/session/DatabaseUtilities.java +++ b/src/main/java/org/owasp/webgoat/session/DatabaseUtilities.java @@ -1,4 +1,3 @@ - package org.owasp.webgoat.session; import java.io.IOException; @@ -15,7 +14,6 @@ import org.apache.ecs.html.TR; import org.apache.ecs.html.Table; - /*************************************************************************************************** * * @@ -45,129 +43,98 @@ * * @author Jeff Williams Aspect Security */ -public class DatabaseUtilities -{ - - private static Map connections = new HashMap(); - private static Map dbBuilt = new HashMap(); - - public static Connection getConnection(WebSession s) throws SQLException - { - return getConnection(s.getUserName(), s.getWebgoatContext()); - } - - public static synchronized Connection getConnection(String user, WebgoatContext context) throws SQLException - { - Connection conn = connections.get(user); - if (conn != null && !conn.isClosed()) return conn; - conn = makeConnection(user, context); - connections.put(user, conn); - - if (dbBuilt.get(user) == null) - { - new CreateDB().makeDB(conn); - dbBuilt.put(user, Boolean.TRUE); - } - - return conn; - } - - public static synchronized void returnConnection(String user) - { - try - { - Connection connection = connections.get(user); - if (connection == null || connection.isClosed()) return; - - if (connection.getMetaData().getDatabaseProductName().toLowerCase().contains("oracle")) connection.close(); - } catch (SQLException sqle) - { - sqle.printStackTrace(); - } - } - - private static Connection makeConnection(String user, WebgoatContext context) throws SQLException - { - try - { - Class.forName(context.getDatabaseDriver()); - - if (context.getDatabaseConnectionString().contains("hsqldb")) return getHsqldbConnection(user, context); - - String userPrefix = context.getDatabaseUser(); - String password = context.getDatabasePassword(); - String url = context.getDatabaseConnectionString(); - return DriverManager.getConnection(url, userPrefix + "_" + user, password); - } catch (ClassNotFoundException cnfe) - { - cnfe.printStackTrace(); - throw new SQLException("Couldn't load the database driver: " + cnfe.getLocalizedMessage()); - } - } - - private static Connection getHsqldbConnection(String user, WebgoatContext context) throws ClassNotFoundException, - SQLException - { - String url = context.getDatabaseConnectionString().replaceAll("\\$\\{USER\\}", user); - return DriverManager.getConnection(url, "sa", ""); - } - - /** - * Description of the Method - * - * @param results - * Description of the Parameter - * @param resultsMetaData - * Description of the Parameter - * - * @return Description of the Return Value - * - * @exception IOException - * Description of the Exception - * @exception SQLException - * Description of the Exception - */ - public static MultiPartElement writeTable(ResultSet results, ResultSetMetaData resultsMetaData) throws IOException, - SQLException - { - int numColumns = resultsMetaData.getColumnCount(); - results.beforeFirst(); - - if (results.next()) - { - Table t = new Table(1); // 1 = with border - t.setCellPadding(1); - - TR tr = new TR(); - - for (int i = 1; i < (numColumns + 1); i++) - { - tr.addElement(new TD(new B(resultsMetaData.getColumnName(i)))); - } - - t.addElement(tr); - results.beforeFirst(); - - while (results.next()) - { - TR row = new TR(); - - for (int i = 1; i < (numColumns + 1); i++) - { - String str = results.getString(i); - if (str == null) str = ""; - row.addElement(new TD(str.replaceAll(" ", " "))); - } - - t.addElement(row); - } - - return (t); - } - else - { - return (new B("Query Successful; however no data was returned from this query.")); - } - } - +public class DatabaseUtilities { + + private static Map connections = new HashMap<>(); + private static Map dbBuilt = new HashMap<>(); + + public static Connection getConnection(WebSession s) throws SQLException { + return getConnection(s.getUserName(), s.getWebgoatContext()); + } + + public static synchronized Connection getConnection(String user, WebgoatContext context) throws SQLException { + Connection conn = connections.get(user); + if (conn != null && !conn.isClosed()) { + return conn; + } + conn = makeConnection(user, context); + connections.put(user, conn); + + if (dbBuilt.get(user) == null) { + new CreateDB().makeDB(conn); + dbBuilt.put(user, Boolean.TRUE); + } + + return conn; + } + + public static synchronized void returnConnection(String user) { + try { + Connection connection = connections.get(user); + if (connection == null || connection.isClosed()) return; + + if (connection.getMetaData().getDatabaseProductName().toLowerCase().contains("oracle")) { + connection.close(); + } + } catch (SQLException sqle) { + sqle.printStackTrace(); + } + } + + private static Connection makeConnection(String user, WebgoatContext context) throws SQLException { + try { + Class.forName(context.getDatabaseDriver()); + + if (context.getDatabaseConnectionString().contains("hsqldb")) { + return getHsqldbConnection(user, context); + } + + String userPrefix = context.getDatabaseUser(); + String password = context.getDatabasePassword(); + String url = context.getDatabaseConnectionString(); + return DriverManager.getConnection(url, userPrefix + "_" + user, password); + } catch (ClassNotFoundException cnfe) { + cnfe.printStackTrace(); + throw new SQLException("Couldn't load the database driver: " + cnfe.getLocalizedMessage()); + } + } + + private static Connection getHsqldbConnection(String user, WebgoatContext context) throws SQLException { + String url = context.getDatabaseConnectionString().replace("${USER}", user); + return DriverManager.getConnection(url, "sa", ""); + } + + public static MultiPartElement writeTable(ResultSet results, ResultSetMetaData resultsMetaData) throws IOException, SQLException { + int numColumns = resultsMetaData.getColumnCount(); + results.beforeFirst(); + + if (results.next()) { + Table t = new Table(1); // 1 = with border + t.setCellPadding(1); + + TR tr = new TR(); + + for (int i = 1; i <= numColumns; i++) { + tr.addElement(new TD(new B(resultsMetaData.getColumnName(i)))); + } + + t.addElement(tr); + results.beforeFirst(); + + while (results.next()) { + TR row = new TR(); + + for (int i = 1; i <= numColumns; i++) { + String str = results.getString(i); + row.addElement(new TD((str == null ? "" : str).replace(" ", " "))); + } + + t.addElement(row); + } + + return t; + } else { + return new B("Query Successful; however no data was returned from this query."); + } + } } diff --git a/src/main/resources/WebGoatLabels.properties b/src/main/resources/WebGoatLabels.properties index 890b56eb8..eccdbb671 100644 --- a/src/main/resources/WebGoatLabels.properties +++ b/src/main/resources/WebGoatLabels.properties @@ -222,6 +222,14 @@ BypassHtmlFieldRestrictionsHint1=You must re-enable the disabled form field or m BypassHtmlFieldRestrictionsHint2=You can use WebScarab to intercept requests and make changes. BypassHtmlFieldRestrictionsHint3=Rather than using WebScarab, you could instead use the Web Developer and/or Hackbar Firefox extensions to complete this lesson. +# NewLesson.java +NewLessonTitle=New Lesson +NewLessonDescription=This is a new lesson added to WebGoat. + +# RaduLesson.java +NewLessonTitle=Radu Lesson +NewLessonDescription=This is the Radu lesson added to WebGoat. + diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 000000000..ef3762307 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,18 @@ +# OAuth2 Client Configuration +spring.security.oauth2.client.registration.google.client-id=your-google-client-id +spring.security.oauth2.client.registration.google.client-secret=your-google-client-secret +spring.security.oauth2.client.registration.google.scope=openid,profile,email +spring.security.oauth2.client.registration.google.redirect-uri={baseUrl}/login/oauth2/code/google +spring.security.oauth2.client.registration.google.authorization-grant-type=authorization_code +spring.security.oauth2.client.provider.google.authorization-uri=https://accounts.google.com/o/oauth2/auth +spring.security.oauth2.client.provider.google.token-uri=https://oauth2.googleapis.com/token +spring.security.oauth2.client.provider.google.user-info-uri=https://www.googleapis.com/oauth2/v3/userinfo +spring.security.oauth2.client.provider.google.user-name-attribute=sub + +# HTTPS Configuration +server.port=8443 +server.ssl.enabled=true +server.ssl.key-store=classpath:keystore.p12 +server.ssl.key-store-password=changeit +server.ssl.key-store-type=PKCS12 +server.ssl.key-alias=tomcat \ No newline at end of file diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp index 0db641a6f..1c45d138a 100644 --- a/src/main/webapp/index.jsp +++ b/src/main/webapp/index.jsp @@ -1,3 +1,7 @@ <%@ page session="false" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + diff --git a/src/main/webapp/js/react_components/EmployeeTable.jsx b/src/main/webapp/js/react_components/EmployeeTable.jsx new file mode 100644 index 000000000..0c259b2f4 --- /dev/null +++ b/src/main/webapp/js/react_components/EmployeeTable.jsx @@ -0,0 +1,53 @@ +import React, { useEffect, useState } from 'react'; + +const EmployeeTable = () => { + const [employees, setEmployees] = useState([]); + const [error, setError] = useState(null); + + useEffect(() => { + fetch('/api/employees') + .then(response => { + if (!response.ok) { + throw new Error('Failed to fetch employee data'); + } + return response.json(); + }) + .then(data => setEmployees(data)) + .catch(err => setError(err.message)); + }, []); + + if (error) { + return
Error: {error}
; + } + + if (employees.length === 0) { + return
No Results
; + } + + return ( + + + + + + + + + + + + {employees.map((employee, index) => ( + + + + + + + + ))} + +
UserIDFirst NameLast NameSSNSalary
{employee.userId}{employee.firstName}{employee.lastName}{employee.ssn}{employee.salary}
+ ); +}; + +export default EmployeeTable; \ No newline at end of file diff --git a/src/main/webapp/lessons/newLesson.jsp b/src/main/webapp/lessons/newLesson.jsp new file mode 100644 index 000000000..76cc58048 --- /dev/null +++ b/src/main/webapp/lessons/newLesson.jsp @@ -0,0 +1,11 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + + + + Radu Lesson + + +

Welcome to the Radu Lesson

+

Follow the instructions to complete this lesson.

+ + \ No newline at end of file diff --git a/src/main/webapp/main.jsp b/src/main/webapp/main.jsp index 7e704027d..096be6357 100644 --- a/src/main/webapp/main.jsp +++ b/src/main/webapp/main.jsp @@ -13,6 +13,7 @@ + <%=currentLesson.getTitle()%> @@ -282,6 +283,9 @@ <% out.println(currentLesson.getCredits());%> +
diff --git a/src/main/webapp/server.js b/src/main/webapp/server.js new file mode 100644 index 000000000..200c59ad6 --- /dev/null +++ b/src/main/webapp/server.js @@ -0,0 +1,38 @@ +const express = require('express'); +const fs = require('fs'); +const { DOMParser } = require('xmldom'); +const xpath = require('xpath'); + +const app = express(); +const PORT = 3000; + +// API to fetch employee data +app.get('/api/employees', (req, res) => { + const xmlFilePath = __dirname + '/lessons/Ajax/employees.xml'; + + // Check if the XML file exists + if (!fs.existsSync(xmlFilePath)) { + return res.status(404).json({ error: 'XML file not found' }); + } + + // Read and parse the XML file + const xml = fs.readFileSync(xmlFilePath, 'utf-8'); + const doc = new DOMParser().parseFromString(xml); + const select = xpath.useNamespaces({}); + + // Extract employee data using XPath + const employees = select('/Employees/Employee', doc).map(employee => ({ + userId: select('string(UserID)', employee), + firstName: select('string(FirstName)', employee), + lastName: select('string(LastName)', employee), + ssn: select('string(SSN)', employee), + salary: select('string(Salary)', employee), + })); + + res.json(employees); +}); + +// Start the server +app.listen(PORT, () => { + console.log(`Server is running on http://localhost:${PORT}`); +}); \ No newline at end of file diff --git a/src/test/java/org/owasp/webgoat/service/LessonMenuServiceTest.java b/src/test/java/org/owasp/webgoat/service/LessonMenuServiceTest.java new file mode 100644 index 000000000..27d5c681e --- /dev/null +++ b/src/test/java/org/owasp/webgoat/service/LessonMenuServiceTest.java @@ -0,0 +1,62 @@ +package org.owasp.webgoat.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.owasp.webgoat.lessons.model.LessonMenuItem; +import org.owasp.webgoat.session.Course; +import org.owasp.webgoat.session.WebSession; + +import javax.servlet.http.HttpSession; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +class LessonMenuServiceTest { + + @InjectMocks + private LessonMenuService lessonMenuService; + + @Mock + private HttpSession httpSession; + + @Mock + private WebSession webSession; + + @Mock + private Course course; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void testShowLeftNav() { + // Mocking dependencies + when(httpSession.getAttribute("webSession")).thenReturn(webSession); + when(webSession.getCourse()).thenReturn(course); + + List categories = List.of("Category1", "Category2"); + when(course.getCategories()).thenReturn(categories); + + // Mock lessons for each category + List lessons = List.of("Lesson1", "Lesson2"); + when(webSession.getLessons(anyString())).thenReturn(lessons); + + // Call the method under test + List menu = lessonMenuService.showLeftNav(httpSession); + + // Assertions + assertEquals(2, menu.size()); // Two categories + assertEquals("Category1", menu.get(0).getName()); + assertEquals("Category2", menu.get(1).getName()); + + verify(course, times(1)).getCategories(); + verify(webSession, times(2)).getLessons(anyString()); + } +} \ No newline at end of file