| 1 | package com.jsql.model.suspendable; | |
| 2 | ||
| 3 | import com.jsql.model.InjectionModel; | |
| 4 | import com.jsql.model.exception.JSqlException; | |
| 5 | import com.jsql.model.exception.StoppedByUserSlidingException; | |
| 6 | import com.jsql.model.injection.vendor.model.VendorYaml; | |
| 7 | import com.jsql.model.suspendable.callable.CallablePageSource; | |
| 8 | import com.jsql.util.LogLevelUtil; | |
| 9 | import org.apache.commons.lang3.StringUtils; | |
| 10 | import org.apache.logging.log4j.LogManager; | |
| 11 | import org.apache.logging.log4j.Logger; | |
| 12 | ||
| 13 | import java.util.concurrent.CompletionService; | |
| 14 | import java.util.concurrent.ExecutionException; | |
| 15 | import java.util.concurrent.ExecutorCompletionService; | |
| 16 | import java.util.concurrent.ExecutorService; | |
| 17 | import java.util.regex.Pattern; | |
| 18 | ||
| 19 | /** | |
| 20 | * Runnable class, search the correct number of fields in the SQL query. | |
| 21 | * Concurrent search with stop capability | |
| 22 | */ | |
| 23 | public class SuspendableGetIndexes extends AbstractSuspendable { | |
| 24 | | |
| 25 | private static final Logger LOGGER = LogManager.getRootLogger(); | |
| 26 | | |
| 27 | public SuspendableGetIndexes(InjectionModel injectionModel) { | |
| 28 | super(injectionModel); | |
| 29 | } | |
| 30 | ||
| 31 | @Override | |
| 32 | public String run(Object... args) throws JSqlException { | |
| 33 | // Concurrent search | |
| 34 | ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableGetIndexes"); | |
| 35 | CompletionService<CallablePageSource> taskCompletionService = new ExecutorCompletionService<>(taskExecutor); | |
| 36 | ||
| 37 | String initialQuery = StringUtils.EMPTY; | |
| 38 | int nbIndex; | |
| 39 | | |
| 40 |
1
1. run : negated conditional → NO_COVERAGE |
int countUnionIndex = this.injectionModel.getMediatorUtils().getPreferencesUtil().isLimitingUnionIndex() |
| 41 | ? this.injectionModel.getMediatorUtils().getPreferencesUtil().countUnionIndex() | |
| 42 | : 50; | |
| 43 | ||
| 44 | // SQL fields are built like 1337[index]7330+1 | |
| 45 | // 7330+1 allows to exclude false positive when page contains injection URL | |
| 46 | // Search if the source contains 1337[index]7331 | |
| 47 |
2
1. run : negated conditional → NO_COVERAGE 2. run : changed conditional boundary → NO_COVERAGE |
for (nbIndex = 1 ; nbIndex <= countUnionIndex ; nbIndex++) { |
| 48 | taskCompletionService.submit( | |
| 49 | new CallablePageSource( | |
| 50 | this.injectionModel.getMediatorVendor().getVendor().instance().sqlIndices(nbIndex), | |
| 51 | this.injectionModel, | |
| 52 | "union#" + nbIndex, | |
| 53 | nbIndex | |
| 54 | ) | |
| 55 | ); | |
| 56 | } | |
| 57 | | |
| 58 | nbIndex = 1; | |
| 59 | try { | |
| 60 |
2
1. run : changed conditional boundary → NO_COVERAGE 2. run : negated conditional → NO_COVERAGE |
while (nbIndex <= countUnionIndex) { |
| 61 |
1
1. run : negated conditional → NO_COVERAGE |
if (this.isSuspended()) { |
| 62 | throw new StoppedByUserSlidingException(); | |
| 63 | } | |
| 64 | CallablePageSource currentCallable = taskCompletionService.take().get(); | |
| 65 |
1
1. run : Changed increment from 1 to -1 → NO_COVERAGE |
nbIndex++; |
| 66 | // Found a correct mark 1337[index]7331 in the source | |
| 67 | String regexAllIndexes = String.format(VendorYaml.FORMAT_INDEX, "\\d+"); | |
| 68 |
1
1. run : negated conditional → NO_COVERAGE |
if (Pattern.compile("(?s).*"+ regexAllIndexes +".*").matcher(currentCallable.getContent()).matches()) { |
| 69 | | |
| 70 |
1
1. run : removed call to com/jsql/model/injection/strategy/StrategyUnion::setNbIndexesFound → NO_COVERAGE |
this.injectionModel.getMediatorStrategy().getSpecificUnion().setNbIndexesFound(currentCallable.getNbIndex()); |
| 71 |
1
1. run : removed call to com/jsql/model/injection/strategy/StrategyUnion::setSourceIndexesFound → NO_COVERAGE |
this.injectionModel.getMediatorStrategy().getSpecificUnion().setSourceIndexesFound(currentCallable.getContent()); |
| 72 | initialQuery = currentCallable.getQuery().replace("0%2b1", "1"); | |
| 73 | | |
| 74 |
1
1. run : negated conditional → NO_COVERAGE |
if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isPerfIndexDisabled()) { |
| 75 | String regexIndexesExceptFirst = String.format(VendorYaml.FORMAT_INDEX, "(?!17331)\\d+"); | |
| 76 | initialQuery = initialQuery.replaceAll(regexIndexesExceptFirst, "1"); | |
| 77 | LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Calibrating indexes disabled, forcing to index [1]"); | |
| 78 | } | |
| 79 | LOGGER.log( | |
| 80 | LogLevelUtil.CONSOLE_INFORM, | |
| 81 | "Strategy [Union] triggered by [{}]", | |
| 82 |
1
1. lambda$run$0 : replaced return value with null for com/jsql/model/suspendable/SuspendableGetIndexes::lambda$run$0 → NO_COVERAGE |
() -> currentCallable.getQuery().trim() |
| 83 | .replaceAll("1337(\\d*)7330%2b1", "$1") | |
| 84 | .replaceAll("\\s+", StringUtils.SPACE) | |
| 85 | ); | |
| 86 | break; | |
| 87 | } | |
| 88 | } | |
| 89 |
1
1. run : removed call to com/jsql/util/ThreadUtil::shutdown → NO_COVERAGE |
this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor); |
| 90 | } catch (InterruptedException e) { | |
| 91 | LOGGER.log(LogLevelUtil.IGNORE, e, e); | |
| 92 |
1
1. run : removed call to java/lang/Thread::interrupt → NO_COVERAGE |
Thread.currentThread().interrupt(); |
| 93 | } catch (ExecutionException e) { | |
| 94 | LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e); | |
| 95 | } | |
| 96 |
1
1. run : replaced return value with "" for com/jsql/model/suspendable/SuspendableGetIndexes::run → NO_COVERAGE |
return initialQuery; |
| 97 | } | |
| 98 | } | |
Mutations | ||
| 40 |
1.1 |
|
| 47 |
1.1 2.2 |
|
| 60 |
1.1 2.2 |
|
| 61 |
1.1 |
|
| 65 |
1.1 |
|
| 68 |
1.1 |
|
| 70 |
1.1 |
|
| 71 |
1.1 |
|
| 74 |
1.1 |
|
| 82 |
1.1 |
|
| 89 |
1.1 |
|
| 92 |
1.1 |
|
| 96 |
1.1 |