InjectionTime.java

1
package com.jsql.model.injection.strategy.blind;
2
3
import com.jsql.model.InjectionModel;
4
import com.jsql.model.exception.StoppedByUserSlidingException;
5
import com.jsql.model.injection.strategy.blind.callable.CallableTime;
6
import com.jsql.util.LogLevelUtil;
7
import org.apache.logging.log4j.LogManager;
8
import org.apache.logging.log4j.Logger;
9
10
import java.util.ArrayList;
11
import java.util.Collection;
12
import java.util.List;
13
import java.util.concurrent.ExecutionException;
14
import java.util.concurrent.ExecutorService;
15
import java.util.concurrent.Future;
16
17
/**
18
 * Time attack using parallel threads.
19
 * Waiting time in seconds, response time exceeded means query is false.
20
 * Noting that sleep() functions will add up for each line from request.
21
 * A sleep time of 5 will be executed only if the SELECT returns exactly one line.
22
 */
23
public class InjectionTime extends AbstractInjectionMonobit<CallableTime> {
24
25
    /**
26
     * Log4j logger sent to view.
27
     */
28
    private static final Logger LOGGER = LogManager.getRootLogger();
29
30
    /**
31
     *  Time based works by default, many tests will change it to false if it isn't confirmed.
32
     */
33
    private boolean isTimeInjectable = true;
34
35
    /**
36
     * Create time attack initialization.
37
     * If every false requests are under 5 seconds and every true are below 5 seconds,
38
     * then time attack is confirmed.
39
     */
40
    public InjectionTime(InjectionModel injectionModel, BlindOperator blindOperator) {
41
        super(injectionModel, blindOperator);
42
        
43
        // No blind
44 2 1. <init> : negated conditional → NO_COVERAGE
2. <init> : negated conditional → NO_COVERAGE
        if (this.falsyBit.isEmpty() || this.injectionModel.isStoppedByUser()) {
45
            return;
46
        }
47
48
        // Concurrent calls to the FALSE statements,
49
        // it will use inject() from the model
50
        ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableGetTimeTagFalse");
51
        Collection<CallableTime> callablesFalseTest = new ArrayList<>();
52
        for (String falseTest: this.falsyBit) {
53
            callablesFalseTest.add(new CallableTime(
54
                falseTest,
55
                injectionModel,
56
                this,
57
                    blindOperator,
58
                "time#falsy"
59
            ));
60
        }
61
        
62
        // If one FALSE query makes less than X seconds,
63
        // then the test is a failure => exit
64
        // Allow the user to stop the loop
65
        try {
66
            List<Future<CallableTime>> futuresFalseTest = taskExecutor.invokeAll(callablesFalseTest);
67 1 1. <init> : removed call to com/jsql/util/ThreadUtil::shutdown → NO_COVERAGE
            this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
68
            for (Future<CallableTime> futureFalseTest: futuresFalseTest) {
69 1 1. <init> : negated conditional → NO_COVERAGE
                if (this.injectionModel.isStoppedByUser()) {
70
                    return;
71
                }
72 1 1. <init> : negated conditional → NO_COVERAGE
                if (futureFalseTest.get().isTrue()) {
73
                    this.isTimeInjectable = false;
74
                    return;
75
                }
76
            }
77
        } catch (ExecutionException e) {
78
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
79
        } catch (InterruptedException e) {
80
            LOGGER.log(LogLevelUtil.IGNORE, e, e);
81 1 1. <init> : removed call to java/lang/Thread::interrupt → NO_COVERAGE
            Thread.currentThread().interrupt();
82
        }
83
        
84 1 1. <init> : removed call to com/jsql/model/injection/strategy/blind/InjectionTime::checkTrueTests → NO_COVERAGE
        this.checkTrueTests(blindOperator);
85
    }
86
87
    private void checkTrueTests(BlindOperator blindOperator) {
88
        // Concurrent calls to the TRUE statements,
89
        // it will use inject() from the model
90
        ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableGetTimeTagTrue");
91
        Collection<CallableTime> callablesTrueTest = new ArrayList<>();
92
        for (String trueTest: this.truthyBit) {
93
            callablesTrueTest.add(new CallableTime(
94
                trueTest,
95
                this.injectionModel,
96
                this,
97
                    blindOperator,
98
                "time#truthy"
99
            ));
100
        }
101
102
        // If one TRUE query makes more than X seconds,
103
        // then the test is a failure => exit.
104
        // Allow the user to stop the loop
105
        try {
106
            List<Future<CallableTime>> futuresTrueTest = taskExecutor.invokeAll(callablesTrueTest);
107 1 1. checkTrueTests : removed call to com/jsql/util/ThreadUtil::shutdown → NO_COVERAGE
            this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
108
            for (Future<CallableTime> futureTrueTest: futuresTrueTest) {
109 1 1. checkTrueTests : negated conditional → NO_COVERAGE
                if (this.injectionModel.isStoppedByUser()) {
110
                    return;
111
                }
112 1 1. checkTrueTests : negated conditional → NO_COVERAGE
                if (!futureTrueTest.get().isTrue()) {
113
                    this.isTimeInjectable = false;
114
                    return;
115
                }
116
            }
117
        } catch (ExecutionException e) {
118
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
119
        } catch (InterruptedException e) {
120
            LOGGER.log(LogLevelUtil.IGNORE, e, e);
121 1 1. checkTrueTests : removed call to java/lang/Thread::interrupt → NO_COVERAGE
            Thread.currentThread().interrupt();
122
        }
123
    }
124
125
    @Override
126
    public CallableTime getCallableBitTest(String sqlQuery, int indexChar, int bit) {
127 1 1. getCallableBitTest : replaced return value with null for com/jsql/model/injection/strategy/blind/InjectionTime::getCallableBitTest → NO_COVERAGE
        return new CallableTime(
128
            sqlQuery,
129
            indexChar,
130
            bit,
131
            this.injectionModel,
132
            this,
133
            this.blindOperator,
134
            "bit#" + indexChar + "~" + bit
135
        );
136
    }
137
138
    @Override
139
    public boolean isInjectable() throws StoppedByUserSlidingException {
140 1 1. isInjectable : negated conditional → NO_COVERAGE
        if (this.injectionModel.isStoppedByUser()) {
141
            throw new StoppedByUserSlidingException();
142
        }
143
        var timeTest = new CallableTime(
144
            this.injectionModel.getMediatorVendor().getVendor().instance().sqlBlindConfirm(),
145
            this.injectionModel,
146
            this,
147
            this.blindOperator,
148
            "time#confirm"
149
        );
150
        try {
151
            timeTest.call();
152
        } catch (Exception e) {
153
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
154
        }
155 3 1. isInjectable : replaced boolean return with true for com/jsql/model/injection/strategy/blind/InjectionTime::isInjectable → NO_COVERAGE
2. isInjectable : negated conditional → NO_COVERAGE
3. isInjectable : negated conditional → NO_COVERAGE
        return this.isTimeInjectable && timeTest.isTrue();
156
    }
157
158
    public int getSleepTime() {
159 2 1. getSleepTime : replaced int return with 0 for com/jsql/model/injection/strategy/blind/InjectionTime::getSleepTime → NO_COVERAGE
2. getSleepTime : negated conditional → NO_COVERAGE
        return this.injectionModel.getMediatorUtils().getPreferencesUtil().isLimitingSleepTimeStrategy()
160
            ? this.injectionModel.getMediatorUtils().getPreferencesUtil().countSleepTimeStrategy()
161
            : 5;
162
    }
163
164
    @Override
165
    public String getInfoMessage() {
166 1 1. getInfoMessage : replaced return value with "" for com/jsql/model/injection/strategy/blind/InjectionTime::getInfoMessage → NO_COVERAGE
        return "- Strategy Time: query True when delays for "+ this.getSleepTime() +"s\n\n";
167
    }
168
}

Mutations

44

1.1
Location : <init>
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : <init>
Killed by : none
negated conditional → NO_COVERAGE

67

1.1
Location : <init>
Killed by : none
removed call to com/jsql/util/ThreadUtil::shutdown → NO_COVERAGE

69

1.1
Location : <init>
Killed by : none
negated conditional → NO_COVERAGE

72

1.1
Location : <init>
Killed by : none
negated conditional → NO_COVERAGE

81

1.1
Location : <init>
Killed by : none
removed call to java/lang/Thread::interrupt → NO_COVERAGE

84

1.1
Location : <init>
Killed by : none
removed call to com/jsql/model/injection/strategy/blind/InjectionTime::checkTrueTests → NO_COVERAGE

107

1.1
Location : checkTrueTests
Killed by : none
removed call to com/jsql/util/ThreadUtil::shutdown → NO_COVERAGE

109

1.1
Location : checkTrueTests
Killed by : none
negated conditional → NO_COVERAGE

112

1.1
Location : checkTrueTests
Killed by : none
negated conditional → NO_COVERAGE

121

1.1
Location : checkTrueTests
Killed by : none
removed call to java/lang/Thread::interrupt → NO_COVERAGE

127

1.1
Location : getCallableBitTest
Killed by : none
replaced return value with null for com/jsql/model/injection/strategy/blind/InjectionTime::getCallableBitTest → NO_COVERAGE

140

1.1
Location : isInjectable
Killed by : none
negated conditional → NO_COVERAGE

155

1.1
Location : isInjectable
Killed by : none
replaced boolean return with true for com/jsql/model/injection/strategy/blind/InjectionTime::isInjectable → NO_COVERAGE

2.2
Location : isInjectable
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : isInjectable
Killed by : none
negated conditional → NO_COVERAGE

159

1.1
Location : getSleepTime
Killed by : none
replaced int return with 0 for com/jsql/model/injection/strategy/blind/InjectionTime::getSleepTime → NO_COVERAGE

2.2
Location : getSleepTime
Killed by : none
negated conditional → NO_COVERAGE

166

1.1
Location : getInfoMessage
Killed by : none
replaced return value with "" for com/jsql/model/injection/strategy/blind/InjectionTime::getInfoMessage → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.19.1