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

Mutations

44

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

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

68

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

72

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

76

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

87

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

90

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

116

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

120

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

124

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

135

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

141

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

155

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

173

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

178

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.16.1