Add two more assignments for SQL injection where only filtering is applied.
This commit is contained in:
@ -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.
|
||||
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
|
Reference in New Issue
Block a user