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_STORAGE("Insecure Storage", new Integer(1500)),
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)),
WEB_SERVICES("Web Services", new Integer(1900)),
VULNERABLE_COMPONENTS("Vulnerable Components - A9", new Integer(1950)),

View File

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

View File

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

View File

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

View File

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

View File

@ -2,90 +2,148 @@
<html xmlns:th="http://www.thymeleaf.org">
<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>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:HtmlTampering_Intro.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- stripped down without extra comments -->
<div class="adoc-content" th:replace="doc:HtmlTampering_Task.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" name="task"
method="POST"
action="/WebGoat/HtmlTampering/task"
enctype="application/json;charset=UTF-8">
<script>
let regex=/^2999.99$/
let price = 2999.99
document.getElementById("total").innerHTML = '$' + price.toString()
document.task.Total.value = price * document.task.QTY.value
<div class="lesson-page-wrapper">
<!-- stripped down without extra comments -->
<div class="adoc-content" th:replace="doc:HtmlTampering_Task.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" id="task" name="task"
method="POST"
action="/WebGoat/HtmlTampering/task"
enctype="application/json;charset=UTF-8">
<script>
var regex = /^2999.99$/;
var price = 2999.99;
document.getElementById("total").innerHTML = '$' + price.toString();
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() {
if (!regex.test(price.toString())) {
alert('Data tampering is disallowed')
price = 2999.99
return false
}
else {
return true
}
})
$('#remove').click(function () {
document.getElementById("QTY").value = 1;
update();
});
function update() {
let total = price * document.task.QTY.value
document.getElementById("total").innerHTML = total.toString()
document.task.Total.value = total
$("#QTY").on('change keydown paste input blur', function () {
update();
});
function update() {
price = $('#price').text();
if (!regex.test(price.toString())) {
alert('Data tampering is disallowed');
document.getElementById("price").innerHTML = 2999.99;
update();
}
</script>
<center>
<h1>Shopping Cart </h1>
</center>
<br />
<table align="center" cellspacing="0" width="90%" border="1" cellpadding="2">
<tbody>
<tr>
<th width="80%">Shopping Cart Items To Buy Now</th>
<th width="10%">Price</th>
<th width="3%">Quantity</th>
<th width="7%">Total</th>
</tr>
<tr>
<td>56 inch HDTV (model KTV-551)</td>
<td align="right">2999.99</td>
<td align="right">
<input size="6" value="1" name="QTY" type="TEXT" id="QTY"/>
</td>
<td id="total"></td>
</tr>
</tbody>
</table>
<br />
<table align="center" cellspacing="0" width="90%" border="0" cellpadding="2">
<tbody>
<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>
<br></br>
<div class="attack-feedback"></div>
<div class="attack-output"></div>
</div>
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>
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-10 col-md-offset-1">
<table class="table table-hover">
<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>
<tr>
<td class="col-sm-8 col-md-6">
<div class="media">
<a class="thumbnail pull-left" href="#"> <img class="media-object"
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>
<td>  </td>
<td>  </td>
<td>  </td>
<td><h5>Subtotal</h5></td>
<td class="text-right"><h5><strong><span id="subtotal">$2999.99</span></strong></h5>
</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>
</tbody>
</table>
</div>
</div>
</div>
</form>
<br/><br/>
<div class="attack-feedback"></div>
<div class="attack-output"></div>
</div>
</div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:HtmlTampering_Mitigation.adoc"></div>
</div>
</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.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
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.
== Goals
* The user should have a basic understanding of HTML
* 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
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.