Changed layout of the html tampering lesson and fixed some JavaScript issues. Added a small mitigation page.

Moved the lessons concerning client side validation to client side category
This commit is contained in:
Nanne Baars 2017-06-13 03:22:19 +02:00
parent 09d8fef50e
commit b048988d2f
11 changed files with 165 additions and 87 deletions

View File

@ -52,7 +52,7 @@ public enum Category {
INSECURE_CONFIGURATION("Insecure Configuration", new Integer(1400)), INSECURE_CONFIGURATION("Insecure Configuration", new Integer(1400)),
INSECURE_STORAGE("Insecure Storage", new Integer(1500)), INSECURE_STORAGE("Insecure Storage", new Integer(1500)),
MALICIOUS_EXECUTION("Malicious Execution", new Integer(1600)), MALICIOUS_EXECUTION("Malicious Execution", new Integer(1600)),
PARAMETER_TAMPERING("Parameter Tampering", new Integer(1700)), CLIENT_SIDE("Client side", new Integer(1700)),
SESSION_MANAGEMENT("Session Management Flaws", new Integer(1800)), SESSION_MANAGEMENT("Session Management Flaws", new Integer(1800)),
WEB_SERVICES("Web Services", new Integer(1900)), WEB_SERVICES("Web Services", new Integer(1900)),
VULNERABLE_COMPONENTS("Vulnerable Components - A9", new Integer(1950)), VULNERABLE_COMPONENTS("Vulnerable Components - A9", new Integer(1950)),

View File

@ -38,7 +38,7 @@ import java.util.List;
public class BypassRestrictions extends NewLesson { public class BypassRestrictions extends NewLesson {
@Override @Override
public Category getDefaultCategory() { public Category getDefaultCategory() {
return Category.PARAMETER_TAMPERING; return Category.CLIENT_SIDE;
} }
@Override @Override

View File

@ -39,7 +39,7 @@ public class ClientSideFiltering extends NewLesson {
@Override @Override
public Category getDefaultCategory() { public Category getDefaultCategory() {
return Category.AJAX_SECURITY; return Category.CLIENT_SIDE;
} }
@Override @Override

View File

@ -38,7 +38,7 @@ import java.util.List;
public class HtmlTampering extends NewLesson { public class HtmlTampering extends NewLesson {
@Override @Override
public Category getDefaultCategory() { public Category getDefaultCategory() {
return Category.PARAMETER_TAMPERING; return Category.CLIENT_SIDE;
} }
@Override @Override

View File

@ -1,6 +1,7 @@
package org.owasp.webgoat.plugin; package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath; import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult; import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -8,7 +9,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException; import java.io.IOException;
/** /**
@ -45,6 +45,7 @@ import java.io.IOException;
* @created October 28, 2003 * @created October 28, 2003
*/ */
@AssignmentPath("/HtmlTampering/task") @AssignmentPath("/HtmlTampering/task")
@AssignmentHints({ "hint1", "hint2", "hint3"})
public class HtmlTamperingTask extends AssignmentEndpoint { public class HtmlTamperingTask extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST) @RequestMapping(method = RequestMethod.POST)

View File

@ -3,9 +3,6 @@
<html xmlns:th="http://www.thymeleaf.org"> <html xmlns:th="http://www.thymeleaf.org">
<div class="lesson-page-wrapper"> <div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:HtmlTampering_Intro.adoc"></div> <div class="adoc-content" th:replace="doc:HtmlTampering_Intro.adoc"></div>
</div> </div>
@ -14,78 +11,139 @@
<div class="adoc-content" th:replace="doc:HtmlTampering_Task.adoc"></div> <div class="adoc-content" th:replace="doc:HtmlTampering_Task.adoc"></div>
<div class="attack-container"> <div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div> <div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" name="task" <form class="attack-form" accept-charset="UNKNOWN" id="task" name="task"
method="POST" method="POST"
action="/WebGoat/HtmlTampering/task" action="/WebGoat/HtmlTampering/task"
enctype="application/json;charset=UTF-8"> enctype="application/json;charset=UTF-8">
<script> <script>
let regex=/^2999.99$/ var regex = /^2999.99$/;
let price = 2999.99 var price = 2999.99;
document.getElementById("total").innerHTML = '$' + price.toString() document.getElementById("total").innerHTML = '$' + price.toString();
document.task.Total.value = price * document.task.QTY.value var total = price * document.task.QTY.value;
document.getElementById("total").innerHTML = '$' + total;
document.getElementById("subtotal").innerHTML = '$' + total;
document.getElementById("totalAmount").innerHTML = '$' + total;
$('#task').submit(function() { $('#remove').click(function () {
if (!regex.test(price.toString())) { document.getElementById("QTY").value = 1;
alert('Data tampering is disallowed') update();
price = 2999.99 });
return false
} $("#QTY").on('change keydown paste input blur', function () {
else { update();
return true });
}
})
function update() { function update() {
let total = price * document.task.QTY.value price = $('#price').text();
document.getElementById("total").innerHTML = total.toString() if (!regex.test(price.toString())) {
document.task.Total.value = total alert('Data tampering is disallowed');
document.getElementById("price").innerHTML = 2999.99;
update();
}
var total = price * document.task.QTY.value;
$('#total').text('$' + total.toFixed(2));
$('#subtotal').text('$' + total.toFixed(2));
$('#totalAmount').text('$' + total.toFixed(2));
$('#Total').val(total.toFixed(2));
} }
</script> </script>
<center> <div class="container-fluid">
<h1>Shopping Cart </h1> <div class="row">
</center> <div class="col-sm-12 col-md-10 col-md-offset-1">
<br /> <table class="table table-hover">
<table align="center" cellspacing="0" width="90%" border="1" cellpadding="2"> <thead>
<tr>
<th>Product</th>
<th>Quantity</th>
<th class="text-center">Price</th>
<th class="text-center">Total</th>
<th> </th>
</tr>
</thead>
<tbody> <tbody>
<tr> <tr>
<th width="80%">Shopping Cart Items To Buy Now</th> <td class="col-sm-8 col-md-6">
<th width="10%">Price</th> <div class="media">
<th width="3%">Quantity</th> <a class="thumbnail pull-left" href="#"> <img class="media-object"
<th width="7%">Total</th> th:src="@{/images/samsung.jpg}"
style="width: 72px; height: 72px;"></img>
</a>
<div class="media-body">
<h4 class="media-heading"><a href="#">55'' M5510 White Full HD Smart TV</a>
</h4>
<h5 class="media-heading"> by <a href="#">Samsung</a></h5>
<span>Status: </span><span
class="text-success"><strong>In Stock</strong></span>
</div>
</div>
</td>
<td>
<input size="2" value="1" name="QTY" type="TEXT" id="QTY"/>
</td>
<td class="col-sm-1 col-md-1 text-center"><strong><span
id="price">2999.99</span></strong></td>
<td class="col-sm-1 col-md-1 text-center"><strong><span
id="total">$2999.99</span></strong></td>
<td class="col-sm-1 col-md-1">
<button type="submit" id="remove" class="btn btn-danger">
<span class="glyphicon glyphicon-remove" onclick="clear()"></span> Remove
</button>
</td>
</tr> </tr>
<tr> <tr>
<td>56 inch HDTV (model KTV-551)</td> <td>  </td>
<td align="right">2999.99</td> <td>  </td>
<td align="right"> <td>  </td>
<input size="6" value="1" name="QTY" type="TEXT" id="QTY"/> <td><h5>Subtotal</h5></td>
<td class="text-right"><h5><strong><span id="subtotal">$2999.99</span></strong></h5>
</td> </td>
<td id="total"></td> </tr>
<tr>
<td>  </td>
<td>  </td>
<td>  </td>
<td><h5>Shipping costs</h5></td>
<td class="text-right"><h5><strong>$0.00</strong></h5>
</td>
</tr>
<tr>
<td>  </td>
<td>  </td>
<td>  </td>
<td><h3>Total</h3></td>
<td class="text-right"><h3><strong><span id="totalAmount">$2999.99</span></strong></h3>
</td>
</tr>
<tr>
<td>  </td>
<td>  </td>
<td>  </td>
<td>
<button type="button" class="btn btn-default">
<span class="glyphicon glyphicon-shopping-cart"></span> Continue Shopping
</button>
</td>
<td>
<div id="checkout">
<button type="submit" class="btn btn-success">
Checkout <span class="glyphicon glyphicon-play"></span>
</button>
</div>
</td>
<input id="Total" name="Total" type="HIDDEN" value="2999.99"/>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<br /> </div>
<table align="center" cellspacing="0" width="90%" border="0" cellpadding="2"> </div>
<tbody> </div>
<tr>
<td>The total charged to your credit card:</td>
<td>$2999,99</td>
<td>
<input name="UPDATE" type="button" value="UpdateCart" onclick="update()"/>
</td>
<td>
<input value="Purchase" name="SUBMIT" type="submit" />
</td>
</tr>
</tbody>
</table>
<input name="Total" type="HIDDEN" value="2999.99" />
<br />
</form> </form>
<br></br> <br/><br/>
<div class="attack-feedback"></div> <div class="attack-feedback"></div>
<div class="attack-output"></div> <div class="attack-output"></div>
</div> </div>
</div> </div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:HtmlTampering_Mitigation.adoc"></div>
</div>
</html> </html>

View File

@ -3,3 +3,7 @@ html-tampering.title=HTML tampering
html-tampering.tamper.success=Well done, you just bought a TV at a discount html-tampering.tamper.success=Well done, you just bought a TV at a discount
html-tampering.tamper.failure=This is too expensive... You need to buy at a cheaper cost! html-tampering.tamper.failure=This is too expensive... You need to buy at a cheaper cost!
hint1=Try to change the number of items and see what is happening
hint2=Is the price part of the HTML request?
hint3=Intercept the request and manipulate the price before submitting it.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -2,6 +2,7 @@
== Concept == Concept
Browsers generally offer many options of editing the displayed content. Developers Browsers generally offer many options of editing the displayed content. Developers
therefore must be aware that the values sent by the user may have been tampered with. therefore must be aware that the values sent by the user may have been tampered with.
== Goals == Goals
* The user should have a basic understanding of HTML * The user should have a basic understanding of HTML
* The user will be able to exploit editing front end of website * The user will be able to exploit editing front end of website

View File

@ -0,0 +1,14 @@
=== Mitigation
In this simple example you noticed that the price is calculated server side and send to the server. The server
accepted the input as a given and did not calculate the price again. One of the mitigations in this case is to look up
the price of the television in your database and calculate the total price again.
In a real application you should never rely on client side validation it is important to verify all the input
send by the client. Always remember: **NEVER TRUST INPUT SEND BY A CLIENT.**
''''
==== References
https://www.owasp.org/index.php/Input_Validation_Cheat_Sheet

View File

@ -1,2 +1,2 @@
=== Try it yourself === Try it yourself
This is an internet store. Try to buy TV-s for a lower price. In an online store you ordered a new TV, try to buy one or more TVs for a lower price.