diff --git a/pom.xml b/pom.xml index b5ad9015d..3259ca38a 100644 --- a/pom.xml +++ b/pom.xml @@ -238,7 +238,7 @@ org.projectlombok lombok - 1.18.36 + 1.18.46 provided true diff --git a/src/main/java/org/owasp/webgoat/lessons/htmltampering/HtmlTamperingTask.java b/src/main/java/org/owasp/webgoat/lessons/htmltampering/HtmlTamperingTask.java index 3552883f4..bc59322db 100644 --- a/src/main/java/org/owasp/webgoat/lessons/htmltampering/HtmlTamperingTask.java +++ b/src/main/java/org/owasp/webgoat/lessons/htmltampering/HtmlTamperingTask.java @@ -19,12 +19,36 @@ @AssignmentHints({"hint1", "hint2", "hint3"}) public class HtmlTamperingTask implements AssignmentEndpoint { + // The unit price is authoritative server-side state (e.g. a catalog/database lookup in a + // real application). It must never be derived from client-supplied input. + private static final double UNIT_PRICE = 2999.99; + private static final double ROUNDING_TOLERANCE = 0.01; + @PostMapping("/HtmlTampering/task") @ResponseBody public AttackResult completed(@RequestParam String QTY, @RequestParam String Total) { - if (Float.parseFloat(QTY) * 2999.99 > Float.parseFloat(Total) + 1) { - return success(this).feedback("html-tampering.tamper.success").build(); + final double quantity; + final double submittedTotal; + try { + quantity = Double.parseDouble(QTY); + submittedTotal = Double.parseDouble(Total); + } catch (NumberFormatException e) { + return failed(this).feedback("html-tampering.tamper.failure").build(); + } + + if (quantity <= 0) { + return failed(this).feedback("html-tampering.tamper.failure").build(); } - return failed(this).feedback("html-tampering.tamper.failure").build(); + + // Recompute the total from the trusted, server-side unit price instead of trusting the + // "Total" value the client sent along with the request. Any mismatch means the price shown + // to the checkout endpoint was tampered with (e.g. edited in the HTML/hidden field before + // submit) and must be rejected rather than honored. + double serverCalculatedTotal = quantity * UNIT_PRICE; + if (Math.abs(serverCalculatedTotal - submittedTotal) > ROUNDING_TOLERANCE) { + return failed(this).feedback("html-tampering.tamper.failure").build(); + } + + return success(this).feedback("html-tampering.tamper.success").build(); } }