Add two more assignments for SQL injection where only filtering is applied.
This commit is contained in:
parent
122cc323f2
commit
407e19638f
@ -227,14 +227,9 @@ public abstract class IntegrationTest {
|
||||
.extract().path("lessonCompleted"), CoreMatchers.is(expectedResult));
|
||||
}
|
||||
|
||||
//TODO is prefix useful? not every lesson endpoint needs to start with a certain prefix (they are only required to be in the same package)
|
||||
public void checkResults(String prefix) {
|
||||
Assert.assertThat(RestAssured.given()
|
||||
.when()
|
||||
.relaxedHTTPSValidation()
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.get(url("service/lessonoverview.mvc"))
|
||||
.then()
|
||||
.statusCode(200).extract().jsonPath().getList("solved"), CoreMatchers.everyItem(CoreMatchers.is(true)));
|
||||
checkResults();
|
||||
|
||||
Assert.assertThat(RestAssured.given()
|
||||
.when()
|
||||
@ -246,6 +241,16 @@ public abstract class IntegrationTest {
|
||||
|
||||
}
|
||||
|
||||
public void checkResults() {
|
||||
Assert.assertThat(RestAssured.given()
|
||||
.when()
|
||||
.relaxedHTTPSValidation()
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.get(url("service/lessonoverview.mvc"))
|
||||
.then()
|
||||
.statusCode(200).extract().jsonPath().getList("solved"), CoreMatchers.everyItem(CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
public void checkAssignment(String url, ContentType contentType, String body, boolean expectedResult) {
|
||||
Assert.assertThat(
|
||||
RestAssured.given()
|
||||
|
@ -38,6 +38,14 @@ public class SqlInjectionMitigationTest extends IntegrationTest {
|
||||
"}");
|
||||
checkAssignment(url("/WebGoat/SqlInjectionMitigations/attack10b"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("userid_sql_only_input_validation", "Smith';SELECT/**/*/**/from/**/user_system_data;--");
|
||||
checkAssignment(url("/WebGoat/SqlOnlyInputValidation/attack"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("userid_sql_only_input_validation_on_keywords", "Smith';SESELECTLECT/**/*/**/FRFROMOM/**/user_system_data;--");
|
||||
checkAssignment(url("/WebGoat/SqlOnlyInputValidationOnKeywords/attack"), params, true);
|
||||
|
||||
RestAssured.given()
|
||||
.when().relaxedHTTPSValidation().cookie("JSESSIONID", getWebGoatCookie())
|
||||
.contentType(ContentType.JSON)
|
||||
@ -57,7 +65,6 @@ public class SqlInjectionMitigationTest extends IntegrationTest {
|
||||
params.put("ip", "104.130.219.202");
|
||||
checkAssignment(url("/WebGoat/SqlInjectionMitigations/attack12a"), params, true);
|
||||
|
||||
checkResults("/SqlInjectionMitigations/");
|
||||
|
||||
checkResults();
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public class SqlInjectionLesson6a extends AssignmentEndpoint {
|
||||
// The answer: Smith' union select userid,user_name, password,cookie,cookie, cookie,userid from user_system_data --
|
||||
}
|
||||
|
||||
protected AttackResult injectableQuery(String accountName) {
|
||||
public AttackResult injectableQuery(String accountName) {
|
||||
String query = "";
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
boolean usedUnion = true;
|
||||
|
@ -38,13 +38,13 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
@RestController
|
||||
@AssignmentHints(value = {"SqlStringInjectionHint-mitigation-12a-1", "SqlStringInjectionHint-mitigation-12a-2", "SqlStringInjectionHint-mitigation-12a-3", "SqlStringInjectionHint-mitigation-12a-4"})
|
||||
@AssignmentHints(value = {"SqlStringInjectionHint-mitigation-13-1", "SqlStringInjectionHint-mitigation-13-2", "SqlStringInjectionHint-mitigation-13-3", "SqlStringInjectionHint-mitigation-13-4"})
|
||||
@Slf4j
|
||||
public class SqlInjectionLesson12a extends AssignmentEndpoint {
|
||||
public class SqlInjectionLesson13 extends AssignmentEndpoint {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionLesson12a(DataSource dataSource) {
|
||||
public SqlInjectionLesson13(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
@ -0,0 +1,56 @@
|
||||
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.sql_injection.mitigation;
|
||||
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.owasp.webgoat.sql_injection.advanced.SqlInjectionLesson6a;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
|
||||
@RestController
|
||||
@AssignmentHints(value = {"SqlOnlyInputValidation-1", "SqlOnlyInputValidation-2", "SqlOnlyInputValidation-3"})
|
||||
public class SqlOnlyInputValidation extends AssignmentEndpoint {
|
||||
|
||||
private final SqlInjectionLesson6a lesson6a;
|
||||
|
||||
public SqlOnlyInputValidation(SqlInjectionLesson6a lesson6a) {
|
||||
this.lesson6a = lesson6a;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlOnlyInputValidation/attack")
|
||||
@ResponseBody
|
||||
public AttackResult attack(@RequestParam("userid_sql_only_input_validation") String userId) {
|
||||
if (userId.contains(" ")) {
|
||||
return failed(this).feedback("SqlOnlyInputValidation-failed").build();
|
||||
}
|
||||
AttackResult attackResult = lesson6a.injectableQuery(userId);
|
||||
return new AttackResult(attackResult.isLessonCompleted(), attackResult.getFeedback(), attackResult.getOutput(), getClass().getSimpleName());
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.sql_injection.mitigation;
|
||||
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.owasp.webgoat.sql_injection.advanced.SqlInjectionLesson6a;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
|
||||
@RestController
|
||||
@AssignmentHints(value = {"SqlOnlyInputValidationOnKeywords-1", "SqlOnlyInputValidationOnKeywords-2", "SqlOnlyInputValidationOnKeywords-3"})
|
||||
public class SqlOnlyInputValidationOnKeywords extends AssignmentEndpoint {
|
||||
|
||||
private final SqlInjectionLesson6a lesson6a;
|
||||
|
||||
public SqlOnlyInputValidationOnKeywords(SqlInjectionLesson6a lesson6a) {
|
||||
this.lesson6a = lesson6a;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlOnlyInputValidationOnKeywords/attack")
|
||||
@ResponseBody
|
||||
public AttackResult attack(@RequestParam("userid_sql_only_input_validation_on_keywords") String userId) {
|
||||
userId = userId.toUpperCase().replace("FROM", "").replace("SELECT", "");
|
||||
if (userId.contains(" ")) {
|
||||
return failed(this).feedback("SqlOnlyInputValidationOnKeywords-failed").build();
|
||||
}
|
||||
AttackResult attackResult = lesson6a.injectableQuery(userId);
|
||||
return new AttackResult(attackResult.isLessonCompleted(), attackResult.getFeedback(), attackResult.getOutput(), getClass().getSimpleName());
|
||||
}
|
||||
}
|
@ -66,14 +66,60 @@
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:SqlInjection_content12.adoc"></div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:SqlInjection_content12a.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlOnlyInputValidation/attack"
|
||||
enctype="application/json;charset=UTF-8">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td><input name="userid_sql_only_input_validation" value="" type="TEXT"/></td>
|
||||
<td><input
|
||||
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:SqlInjection_content12b.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlOnlyInputValidationOnKeywords/attack"
|
||||
enctype="application/json;charset=UTF-8">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td><input name="userid_sql_only_input_validation_on_keywords" value="" type="TEXT"/></td>
|
||||
<td><input
|
||||
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:SqlInjection_content13.adoc"></div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:SqlInjection_order_by.adoc"></div>
|
||||
<script th:src="@{/lesson_js/assignment12.js}" language="JavaScript"></script>
|
||||
<script th:src="@{/lesson_js/assignment13.js}" language="JavaScript"></script>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
@ -145,7 +191,7 @@
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:SqlInjection_content13.adoc"></div>
|
||||
<div class="adoc-content" th:replace="doc:SqlInjection_content14.adoc"></div>
|
||||
</div>
|
||||
|
||||
</html>
|
||||
|
@ -93,12 +93,22 @@ SqlStringInjectionHint-mitigation-10b-3=The wildcard symbol '?' in a prepared st
|
||||
SqlStringInjectionHint-mitigation-10b-4=Make sure to execute your statement.
|
||||
SqlStringInjectionHint-mitigation-10b-5=View the previous lesson to check back on how you can build set up a connection.
|
||||
|
||||
SqlStringInjectionHint-mitigation-12a-1=Try sorting and look at the request
|
||||
SqlStringInjectionHint-mitigation-12a-2=Intercept the request and try to specify a different order by
|
||||
SqlStringInjectionHint-mitigation-12a-3=Use for example "(case when (true) then hostname else id end)" in the order by and see what happens
|
||||
SqlStringInjectionHint-mitigation-12a-4=Use for example "(case when (true) then hostname else id end)" in the order by and see what happens
|
||||
SqlStringInjectionHint-mitigation-13-1=Try sorting and look at the request
|
||||
SqlStringInjectionHint-mitigation-13-2=Intercept the request and try to specify a different order by
|
||||
SqlStringInjectionHint-mitigation-13-3=Use for example "(case when (true) then hostname else id end)" in the order by and see what happens
|
||||
SqlStringInjectionHint-mitigation-13-4=Use for example "(case when (true) then hostname else id end)" in the order by and see what happens
|
||||
|
||||
SqlInjectionChallengeHint1=The table name is randomized at each start of WebGoat, try to figure out the name first.
|
||||
SqlInjectionChallengeHint2=Find the field which is vulnerable to SQL injection use that to change the password.
|
||||
SqlInjectionChallengeHint3=Change the password through an UPDATE Statement.
|
||||
SqlInjectionChallengeHint4=The vulnerable field is the username field of the register form.
|
||||
|
||||
SqlOnlyInputValidation-failed=Using spaces is not allowed!
|
||||
SqlOnlyInputValidation-1=Spaces are rejected, try to find a way around this restriction
|
||||
SqlOnlyInputValidation-2=Try to use a comment in the query
|
||||
SqlOnlyInputValidation-3=WebGoat uses HSQLDB as a database can you use one of them to make skip the filtering?
|
||||
|
||||
SqlOnlyInputValidationOnKeywords-failed=Use of spaces and/or SQL keywords are not allowed!
|
||||
SqlOnlyInputValidationOnKeywords-1=Spaces are and SQL keywords are rejected, try to find a way around this restriction
|
||||
SqlOnlyInputValidationOnKeywords-2=Try to use a comment in the query
|
||||
SqlOnlyInputValidationOnKeywords-3=WebGoat uses HSQLDB as a database can you use one of them to make skip the filtering?
|
||||
|
@ -1,47 +1,11 @@
|
||||
== Order by clause
|
||||
== Input validation alone is not enough!!
|
||||
|
||||
Question: Does a prepared statement always prevent against an SQL injection?
|
||||
Answer: No it does not
|
||||
You need to do both use parametrized queries and validate the input received from the user. On StackOverflow you will
|
||||
see alot of answers stating that input validation is enough. *However* it only takes you so far before you know it
|
||||
the validation is broken and you have an SQL injection in your application.
|
||||
|
||||
Let us take a look at the following statement:
|
||||
A nice read why it is not enough can be found https://twitter.com/marcan42/status/1238004834806067200?s=21
|
||||
|
||||
----
|
||||
SELECT * FROM users ORDER BY lastname;
|
||||
----
|
||||
Let's repeat one of the previous assignments, the developer fixed the possible SQL injection with filtering, can you
|
||||
spot the weakness in this approach?
|
||||
|
||||
If we look at the specification of the SQL grammar the definition is as follows:
|
||||
|
||||
----
|
||||
SELECT ...
|
||||
FROM tableList
|
||||
[WHERE Expression]
|
||||
[ORDER BY orderExpression [, ...]]
|
||||
|
||||
orderExpression:
|
||||
{ columnNr | columnAlias | selectExpression }
|
||||
[ASC | DESC]
|
||||
|
||||
selectExpression:
|
||||
{ Expression | COUNT(*) | {
|
||||
COUNT | MIN | MAX | SUM | AVG | SOME | EVERY |
|
||||
VAR_POP | VAR_SAMP | STDDEV_POP | STDDEV_SAMP
|
||||
} ([ALL | DISTINCT][2]] Expression) } [[AS] label]
|
||||
|
||||
Based on HSQLDB
|
||||
----
|
||||
|
||||
This means an `orderExpression` can be a `selectExpression` which can be a function as well, so for example with
|
||||
a `case` statement we might be able to ask the database some questions, like:
|
||||
|
||||
----
|
||||
SELECT * FROM users ORDER BY (CASE WHEN (TRUE) THEN lastname ELSE firstname)
|
||||
----
|
||||
|
||||
So we can substitute any kind of boolean operation in the `when(....)` part. The statement will just work because
|
||||
it is a valid query whether you use a prepared statement or not an order by clause can by definition contain a
|
||||
expression.
|
||||
|
||||
=== Mitigation
|
||||
|
||||
If you need to provide a sorting column in your web application you should implement a whitelist to validate the value
|
||||
of the `order by` statement it should always be limited to something like 'firstname' or 'lastname'.
|
||||
|
@ -0,0 +1,7 @@
|
||||
== Input validation alone is not enough!!
|
||||
|
||||
So the last attempt to validate if the query did not contain any spaces failed, the development team went further
|
||||
into the direction of only performing input validation, can you find out where it went wrong this time?
|
||||
|
||||
|
||||
|
@ -1,14 +1,47 @@
|
||||
== Least Privilege
|
||||
== Order by clause
|
||||
|
||||
=== Connect with a minimum set of privileges
|
||||
* The application should connect to the database with different credentials for every trust distinction
|
||||
* Applications rarely need delete rights to a table or database
|
||||
Question: Does a prepared statement always prevent against an SQL injection?
|
||||
Answer: No it does not
|
||||
|
||||
=== Database accounts should limit schema access
|
||||
Let us take a look at the following statement:
|
||||
|
||||
=== Define database accounts for read and read/write access
|
||||
----
|
||||
SELECT * FROM users ORDER BY lastname;
|
||||
----
|
||||
|
||||
=== Multiple connection pools based on access
|
||||
* Use read only access for the authentication query
|
||||
* Use read/write access for the data modification queries
|
||||
* Use execute for access to stored procedure calls
|
||||
If we look at the specification of the SQL grammar the definition is as follows:
|
||||
|
||||
----
|
||||
SELECT ...
|
||||
FROM tableList
|
||||
[WHERE Expression]
|
||||
[ORDER BY orderExpression [, ...]]
|
||||
|
||||
orderExpression:
|
||||
{ columnNr | columnAlias | selectExpression }
|
||||
[ASC | DESC]
|
||||
|
||||
selectExpression:
|
||||
{ Expression | COUNT(*) | {
|
||||
COUNT | MIN | MAX | SUM | AVG | SOME | EVERY |
|
||||
VAR_POP | VAR_SAMP | STDDEV_POP | STDDEV_SAMP
|
||||
} ([ALL | DISTINCT][2]] Expression) } [[AS] label]
|
||||
|
||||
Based on HSQLDB
|
||||
----
|
||||
|
||||
This means an `orderExpression` can be a `selectExpression` which can be a function as well, so for example with
|
||||
a `case` statement we might be able to ask the database some questions, like:
|
||||
|
||||
----
|
||||
SELECT * FROM users ORDER BY (CASE WHEN (TRUE) THEN lastname ELSE firstname)
|
||||
----
|
||||
|
||||
So we can substitute any kind of boolean operation in the `when(....)` part. The statement will just work because
|
||||
it is a valid query whether you use a prepared statement or not an order by clause can by definition contain a
|
||||
expression.
|
||||
|
||||
=== Mitigation
|
||||
|
||||
If you need to provide a sorting column in your web application you should implement a whitelist to validate the value
|
||||
of the `order by` statement it should always be limited to something like 'firstname' or 'lastname'.
|
||||
|
@ -0,0 +1,14 @@
|
||||
== Least Privilege
|
||||
|
||||
=== Connect with a minimum set of privileges
|
||||
* The application should connect to the database with different credentials for every trust distinction
|
||||
* Applications rarely need delete rights to a table or database
|
||||
|
||||
=== Database accounts should limit schema access
|
||||
|
||||
=== Define database accounts for read and read/write access
|
||||
|
||||
=== Multiple connection pools based on access
|
||||
* Use read only access for the authentication query
|
||||
* Use read/write access for the data modification queries
|
||||
* Use execute for access to stored procedure calls
|
@ -15,7 +15,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
* @since 5/21/17.
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class SqlInjectionLesson12aTest extends SqlLessonTest {
|
||||
public class SqlInjectionLesson13Test extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void knownAccountShouldDisplayData() throws Exception {
|
@ -0,0 +1,34 @@
|
||||
package org.owasp.webgoat.sql_injection.mitigation;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class SqlOnlyInputValidationOnKeywordsTest extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void solve() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlOnlyInputValidationOnKeywords/attack")
|
||||
.param("userid_sql_only_input_validation_on_keywords", "Smith';SESELECTLECT/**/*/**/FRFROMOM/**/user_system_data;--"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", containsString("passW0rD")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsForbiddenSqlKeyword() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlOnlyInputValidationOnKeywords/attack")
|
||||
.param("userid_sql_only_input_validation_on_keywords", "Smith';SELECT/**/*/**/from/**/user_system_data;--"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.output", containsString("unexpected token: *<br> Your query was: SELECT * FROM user_data WHERE last_name = 'SMITH';\\\\\\/**\\\\\\/*\\\\\\/**\\\\\\/\\\\\\/**\\\\\\/USER_SYSTEM_DATA;--'")));
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package org.owasp.webgoat.sql_injection.mitigation;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class SqlOnlyInputValidationTest extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void solve() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlOnlyInputValidation/attack")
|
||||
.param("userid_sql_only_input_validation", "Smith';SELECT/**/*/**/from/**/user_system_data;--"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", containsString("passW0rD")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsSpace() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlOnlyInputValidation/attack")
|
||||
.param("userid_sql_only_input_validation", "Smith' ;SELECT from user_system_data;--"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", containsString("Using spaces is not allowed!")));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user