Integration test support

This commit is contained in:
René Zubcevic 2019-07-25 10:49:25 +02:00 committed by Nanne Baars
parent ae674b9297
commit ffbc808e26
7 changed files with 554 additions and 1 deletions

View File

@ -139,7 +139,17 @@
<artifactId>secure-passwords</artifactId> <artifactId>secure-passwords</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
<!--uncommment below to run/include lesson template in WebGoat Build--> <!--uncommment below to run/include lesson template in WebGoat Build-->
<!--<dependency>--> <!--<dependency>-->
<!--<groupId>org.owasp.webgoat.lesson</groupId>--> <!--<groupId>org.owasp.webgoat.lesson</groupId>-->

View File

@ -0,0 +1,133 @@
package org.owasp.webgoat;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.HashMap;
import java.util.Map;
import io.restassured.http.ContentType;
public class General_TestHelper extends TestHelper {
public void httpBasics(String webgoatURL, String cookie) {
startLesson(cookie, webgoatURL, "HttpBasics");
Map<String, Object> params = new HashMap<>();
params.clear();
params.put("person", "goatuser");
checkAssignment(cookie, webgoatURL+"/WebGoat/HttpBasics/attack1", params, true);
params.clear();
params.put("answer", "POST");
params.put("magic_answer", "33");
params.put("magic_num", "4");
checkAssignment(cookie, webgoatURL+"/WebGoat/HttpBasics/attack2", params, false);
params.clear();
params.put("answer", "POST");
params.put("magic_answer", "33");
params.put("magic_num", "33");
checkAssignment(cookie, webgoatURL+"/WebGoat/HttpBasics/attack2", params, true);
checkResults(cookie, webgoatURL, "/HttpBasics/");
}
public void httpProxies(String webgoatURL, String cookie) {
startLesson(cookie, webgoatURL, "HttpProxies");
assertThat(given()
.when().config(restConfig).cookie("JSESSIONID", cookie).header("x-request-intercepted", "true")
.contentType(ContentType.JSON).log().all()
.get(webgoatURL + "/WebGoat/HttpProxies/intercept-request?changeMe=Requests are tampered easily").then()
.log().all().statusCode(200).extract().path("lessonCompleted"), is(true));
checkResults(cookie, webgoatURL, "/HttpProxies/");
}
public void cia(String webgoatURL, String cookie) {
startLesson(cookie, webgoatURL, "CIA");
Map<String, Object> params = new HashMap<>();
params.clear();
params.put("question_0_solution", "Solution 3: By stealing a database where names and emails are stored and uploading it to a website.");
params.put("question_1_solution", "Solution 1: By changing the names and emails of one or more users stored in a database.");
params.put("question_2_solution", "Solution 4: By launching a denial of service attack on the servers.");
params.put("question_3_solution", "Solution 2: The systems security is compromised even if only one goal is harmed.");
checkAssignment(cookie, webgoatURL+"/WebGoat/cia/quiz", params, true);
checkResults(cookie, webgoatURL, "/cia/");
}
public void securePasswords(String webgoatURL, String cookie) {
startLesson(cookie, webgoatURL, "SecurePasswords");
Map<String, Object> params = new HashMap<>();
params.clear();
params.put("password", "ajnaeliclm^&&@kjn.");
checkAssignment(cookie, webgoatURL+"/WebGoat/SecurePasswords/assignment", params, true);
checkResults(cookie, webgoatURL, "SecurePasswords/");
startLesson(cookie, webgoatURL, "AuthBypass");
params.clear();
params.put("secQuestion2", "John");
params.put("secQuestion3", "Main");
params.put("jsEnabled", "1");
params.put("verifyMethod", "SEC_QUESTIONS");
params.put("userId", "12309746");
checkAssignment(cookie, webgoatURL + "/WebGoat/auth-bypass/verify-account", params, true);
checkResults(cookie, webgoatURL, "/auth-bypass/");
startLesson(cookie, webgoatURL, "HttpProxies");
assertThat(given().when().config(restConfig).cookie("JSESSIONID", cookie).header("x-request-intercepted", "true")
.contentType(ContentType.JSON).log().all()
.get(webgoatURL + "/WebGoat/HttpProxies/intercept-request?changeMe=Requests are tampered easily").then()
.log().all().statusCode(200).extract().path("lessonCompleted"), is(true));
checkResults(cookie, webgoatURL, "/HttpProxies/");
}
public void chrome(String webgoatURL, String cookie) {
startLesson(cookie, webgoatURL, "ChromeDevTools");
Map<String, Object> params = new HashMap<>();
params.clear();
params.put("param1", "42");
params.put("param2", "24");
String result =
given()
.when()
.config(restConfig)
.cookie("JSESSIONID", cookie)
.header("webgoat-requested-by","dom-xss-vuln")
.header("X-Requested-With", "XMLHttpRequest")
.formParams(params)
.post(webgoatURL+"/WebGoat/CrossSiteScripting/phone-home-xss")
.then()
//.log().all()
.statusCode(200)
.extract().path("output");
String secretNumber = result.substring("phoneHome Response is ".length());
params.clear();
params.put("successMessage", secretNumber);
checkAssignment(cookie, webgoatURL+"/WebGoat/ChromeDevTools/dummy", params, true);
params.clear();
params.put("number", "24");
params.put("network_num", "24");
checkAssignment(cookie, webgoatURL+"/WebGoat/ChromeDevTools/network", params, true);
checkResults(cookie, webgoatURL, "/ChromeDevTools/");
}
}

View File

@ -0,0 +1,36 @@
package org.owasp.webgoat;
import java.util.HashMap;
import java.util.Map;
public class SqlInjectionAdvanced_TestHelper extends TestHelper {
public void runTests(String webgoatURL, String cookie) {
startLesson(cookie, webgoatURL, "SqlInjectionAdvanced");
Map<String, Object> params = new HashMap<>();
params.clear();
params.put("userid_6a", "'; SELECT * FROM user_system_data;--");
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionAdvanced/attack6a", params, true);
params.clear();
params.put("userid_6a", "Smith' union select userid,user_name, user_name,user_name,password,cookie,userid from user_system_data --");
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionAdvanced/attack6a", params, true);
params.clear();
params.put("userid_6b", "passW0rD");
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionAdvanced/attack6b", params, true);
params.clear();
params.put("question_0_solution", "Solution 4: A statement has got values instead of a prepared statement");
params.put("question_1_solution", "Solution 3: ?");
params.put("question_2_solution", "Solution 2: Prepared statements are compiled once by the database management system waiting for input and are pre-compiled this way.");
params.put("question_3_solution", "Solution 3: Placeholders can prevent that the users input gets attached to the SQL query resulting in a seperation of code and data.");
params.put("question_4_solution", "Solution 4: The database registers 'Robert' ); DROP TABLE Students;--'.");
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionAdvanced/quiz", params, true);
//checkResults(cookie, webgoatURL, "/SqlInjectionAdvanced/");
}
}

View File

@ -0,0 +1,37 @@
package org.owasp.webgoat;
import java.util.HashMap;
import java.util.Map;
public class SqlInjectionMitigation_TestHelper extends TestHelper {
public void runTests(String webgoatURL, String cookie) {
startLesson(cookie, webgoatURL, "SqlInjectionMitigations");
Map<String, Object> params = new HashMap<>();
params.clear();
params.put("field1", "getConnection");
params.put("field2", "PreparedStatement prep");
params.put("field3", "prepareStatement");
params.put("field4", "?");
params.put("field5", "?");
params.put("field6", "prep.setString(1,\"\")");
params.put("field7", "prep.setString(2,\\\"\\\")");
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionMitigations/attack10a", params, true);
params.put("editor", "try {\r\n" +
" Connection conn = DriverManager.getConnection(DBURL,DBUSER,DBPW);\r\n" +
" PreparedStatement prep = conn.prepareStatement(\"select id from users where name = ?\");\r\n" +
" prep.setString(1,\"me\");\r\n" +
" prep.execute();\r\n" +
" System.out.println(conn); //should output 'null'\r\n" +
"} catch (Exception e) {\r\n" +
" System.out.println(\"Oops. Something went wrong!\");\r\n" +
"}");
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionMitigations/attack10b", params, true);
//checkResults(cookie, webgoatURL, "/SqlInjectionMitigations/");
}
}

View File

@ -0,0 +1,80 @@
package org.owasp.webgoat;
import java.util.HashMap;
import java.util.Map;
public class SqlInjection_TestHelper extends TestHelper {
private static final String sql_2 = "select department from employees where last_name='Franco'";
private static final String sql_3 = "update employees set department='Sales' where last_name='Barnett'";
private static final String sql_4_drop = "alter table employees drop column phone";
private static final String sql_4_add = "alter table employees add column phone varchar(20)";
private static final String sql_5 = "grant alter table to UnauthorizedUser";
private static final String sql_9_account = " ' ";
private static final String sql_9_operator = "or";
private static final String sql_9_injection = "'1'='1";
private static final String sql_10_login_count = "2";
private static final String sql_10_userid = "1 or 1=1";
private static final String sql_11_a = "Smith' or '1' = '1";
private static final String sql_11_b = "3SL99A' or '1'='1";
private static final String sql_12_a = "Smith";
private static final String sql_12_b = "3SL99A' ; update employees set salary= '100000' where last_name='Smith";
private static final String sql_13 = "%update% '; drop table access_log ; --'";
public void runTests(String webgoatURL, String cookie) {
startLesson(cookie, webgoatURL, "SqlInjection");
Map<String, Object> params = new HashMap<>();
params.clear();
params.put("query", sql_2);
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack2", params, true);
params.clear();
params.put("query", sql_3);
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack3", params, true);
params.clear();
params.put("query", sql_4_drop);
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack4", params, false);
params.clear();
params.put("query", sql_4_add);
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack4", params, true);
params.clear();
params.put("query", sql_5);
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack5", params, true);
params.clear();
params.put("operator", sql_9_operator);
params.put("account", sql_9_account);
params.put("injection", sql_9_injection);
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/assignment5a", params, true);
params.clear();
params.put("login_count", sql_10_login_count);
params.put("userid", sql_10_userid);
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/assignment5b", params, true);
params.clear();
params.put("name", sql_11_a);
params.put("auth_tan", sql_11_b);
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack8", params, true);
params.clear();
params.put("name", sql_12_a);
params.put("auth_tan", sql_12_b);
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack9", params, true);
params.clear();
params.put("action_string", sql_13);
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack10", params, true);
checkResults(cookie, webgoatURL, "/SqlInjection/");
}
}

View File

@ -0,0 +1,95 @@
package org.owasp.webgoat;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.everyItem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertThat;
import java.util.Map;
import io.restassured.config.RestAssuredConfig;
import io.restassured.config.SSLConfig;
public class TestHelper {
//This also allows to test the application with HTTPS when outside testing option is used
protected RestAssuredConfig restConfig = RestAssuredConfig.newConfig().sslConfig(new SSLConfig().relaxedHTTPSValidation());
/**
* At start of a lesson. The .lesson.lesson is visited and the lesson is reset.
* @param cookie
* @param url
* @param lessonName
*/
public void startLesson(String cookie, String url, String lessonName) {
given()
.when()
.config(restConfig)
.cookie("JSESSIONID", cookie)
.get(url+"/WebGoat/"+lessonName+".lesson.lesson")
.then()
.statusCode(200);
given()
.when()
.config(restConfig)
.cookie("JSESSIONID", cookie)
.get(url+"/WebGoat/service/restartlesson.mvc")
.then()
.statusCode(200);
}
/**
* Helper method for most common type of test.
* POST with parameters.
* Checks for 200 and lessonCompleted as indicated by expectedResult
* @param webgoatCookie
* @param url
* @param params
* @param expectedResult
*/
public void checkAssignment(String webgoatCookie, String url, Map<String, ?> params, boolean expectedResult) {
assertThat(
given()
.when()
.config(restConfig)
.cookie("JSESSIONID", webgoatCookie)
.formParams(params)
.post(url)
.then()
//.log().all()
.statusCode(200)
.extract().path("lessonCompleted"), is(expectedResult));
}
/**
* Helper method at the end of a lesson.
* Check if all path paramters are correct for the progress.
* Check if all are solved.
* @param webgoatCookie
* @param webgoatURL
* @param prefix
*/
public void checkResults(String webgoatCookie, String webgoatURL, String prefix) {
assertThat(given()
.when()
.config(restConfig)
.cookie("JSESSIONID", webgoatCookie)
.get(webgoatURL+"/WebGoat/service/lessonoverview.mvc")
.then()
//.log().all()
.statusCode(200).extract().jsonPath().getList("solved"),everyItem(is(true)));
assertThat(given()
.when()
.config(restConfig)
.cookie("JSESSIONID", webgoatCookie)
.get(webgoatURL+"/WebGoat/service/lessonoverview.mvc")
.then()
//.log().all()
.statusCode(200).extract().jsonPath().getList("assignment.path"),everyItem(startsWith(prefix)));
}
}

View File

@ -0,0 +1,162 @@
package org.owasp.webgoat;
import static io.restassured.RestAssured.given;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes=WebGoat.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@EnableAutoConfiguration
public class WebGoatIntegrationTest extends TestHelper {
/*
* Unique port for http server. Database port is not yet overruled. But this is
* not a problem for the integration test.
*/
@LocalServerPort
int randomServerPort;
private General_TestHelper generalTestHelper = new General_TestHelper();
private SqlInjection_TestHelper sqlInjectionHelper = new SqlInjection_TestHelper();
private SqlInjectionAdvanced_TestHelper sqlInjectionAdvancedHelper = new SqlInjectionAdvanced_TestHelper();
private SqlInjectionMitigation_TestHelper sqlInjectionMitigationHelper = new SqlInjectionMitigation_TestHelper();
String webgoatURL = System.getProperty("WEBGOAT_URL","");
String webgoatUser = System.getProperty("WEBGOAT_USER","");
String webgoatPassword = System.getProperty("WEBGOAT_PASSWORD","password");
String cookie = "";
@Before
public void init() {
/*
* If no system properties are set, the test runs against the random port
* of the webgoat application that starts with this test.
* If set you can use it to test an oustide running application. If testing
* against outside running applications, the tests that require WebWolf can be tested as well.
*/
//TODO add support for testing the lessons that require WebWolf as well.
if (webgoatURL.equals("")) {
webgoatURL = "http://127.0.0.1:"+randomServerPort;
}
/*
* If not defined a random user will be registered and used in the test.
* If you run against an outside application and want to visually see the results,
* you can set a username.
*/
if (webgoatUser.equals("")) {
webgoatUser = "tester"+Math.round(Math.random()*1000);
}
//check if user exists
String location = given()
.when()
.config(restConfig)
.formParam("username", webgoatUser)
.formParam("password", "password")
.post(webgoatURL+"/WebGoat/login")
.then()
//.log().all()
.cookie("JSESSIONID")
.statusCode(302)
.extract().header("Location");
//register when not existing, otherwise log in and save the cookie
if (location.endsWith("error")) {
cookie = given()
.when()
.config(restConfig)
.formParam("username", webgoatUser)
.formParam("password", "password")
.formParam("matchingPassword", "password")
.formParam("agree", "agree")
.post(webgoatURL+"/WebGoat/register.mvc")
.then()
.cookie("JSESSIONID")
.statusCode(302)
.extract()
.cookie("JSESSIONID");
} else {
cookie = given()
.when()
.config(restConfig)
.formParam("username", webgoatUser)
.formParam("password", "password")
.post(webgoatURL+"/WebGoat/login")
.then()
//.log().all()
.cookie("JSESSIONID")
.statusCode(302)
.extract().cookie("JSESSIONID");
}
}
@Test
public void testGeneral_HttpBasics() {
generalTestHelper.httpBasics(webgoatURL, cookie);
}
@Test
public void testGeneral_HttpProxies() {
generalTestHelper.httpProxies(webgoatURL, cookie);
}
@Test
public void testGeneral_CIA() {
generalTestHelper.cia(webgoatURL, cookie);
}
@Test
public void testGeneral_Chrome() {
generalTestHelper.chrome(webgoatURL, cookie);
}
@Test
public void testSecurePassords() {
generalTestHelper.securePasswords(webgoatURL, cookie);
}
@Test
public void testSQLInjection() {
sqlInjectionHelper.runTests(webgoatURL, cookie);
}
@Test
public void testSQLInjectionAdvanced() {
sqlInjectionAdvancedHelper.runTests(webgoatURL, cookie);
}
@Test
public void testSQLInjectionMitigation() {
sqlInjectionMitigationHelper.runTests(webgoatURL, cookie);
}
}