From 41c083bc3d7e58c4f7352b646ea986ca7b4e4c95 Mon Sep 17 00:00:00 2001 From: Brendan Early Date: Mon, 22 Dec 2025 13:48:36 -0600 Subject: [PATCH] SuspectTransform: when detecting arithmetic evaluation, do not allow results to be preceded by a decimal point or surrounded by any other digits --- src/burp/SuspectTransform.java | 44 +++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/burp/SuspectTransform.java b/src/burp/SuspectTransform.java index 30fd82f..b7a93eb 100644 --- a/src/burp/SuspectTransform.java +++ b/src/burp/SuspectTransform.java @@ -123,7 +123,9 @@ public List doActiveScan(IHttpRequestResponse basePair, IScannerInse boolean matched = false; for (String e : expect) { - if (attackResponse.contains(e) && !initialResponse.contains(e)) { + boolean attackContains = containsExpectedValue(attackResponse, e); + boolean initialContains = containsExpectedValue(initialResponse, e); + if (attackContains && !initialContains) { matched = true; if (attempt == confirmCount - 1) { issues.add(new CustomScanIssue( @@ -174,5 +176,45 @@ private interface Check { Pair> apply(String base); } + private boolean containsExpectedValue(String body, String expected) { + if (body == null || expected == null) { + return false; + } + + if (expected.chars().allMatch(Character::isDigit)) { + return containsIsolatedNumber(body, expected); + } + + return body.contains(expected); + } + + private boolean containsIsolatedNumber(String body, String number) { + if (body == null || number == null || number.isEmpty()) { + return false; + } + + int index = -1; + while ((index = body.indexOf(number, index + 1)) != -1) { + if (hasValidNumberBoundaries(body, index, number.length())) { + return true; + } + } + + return false; + } + + private boolean hasValidNumberBoundaries(String body, int startIndex, int length) { + // Numbers may not be preceded by another digit or a decimal point + int prefixIndex = startIndex - 1; + boolean validPrefix = prefixIndex < 0 + || (!Character.isDigit(body.charAt(prefixIndex)) && body.charAt(prefixIndex) != '.'); + + // Numbers must not be terminated with another digit + int suffixIndex = startIndex + length; + boolean validSuffix = suffixIndex >= body.length() || !Character.isDigit(body.charAt(suffixIndex)); + + return validPrefix && validSuffix; + } + // Other utility methods like safeBytesToString, request, debugMsg, etc. should be implemented as needed. }