InjectionVendor.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.patch.Diff;
6
import com.jsql.model.injection.vendor.model.Vendor;
7
import com.jsql.model.injection.vendor.model.VendorYaml;
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.ArrayList;
14
import java.util.Collection;
15
import java.util.List;
16
import java.util.concurrent.ExecutionException;
17
import java.util.concurrent.ExecutorService;
18
import java.util.concurrent.Future;
19
20
public class InjectionVendor {
21
22
    /**
23
     * Log4j logger sent to view.
24
     */
25
    private static final Logger LOGGER = LogManager.getRootLogger();
26
27
    // Source code of the FALSE web page (eg. ?id=-123456789)
28
    private String blankFalseMark;
29
30
    private List<Diff> constantTrueMark = new ArrayList<>();
31
32
    protected final InjectionModel injectionModel;
33
34
    private final List<String> falsy;
35
36
    public InjectionVendor(InjectionModel injectionModel, String vendorSpecificWithMode, Vendor vendor) {
37
38
        this.injectionModel = injectionModel;
39
40
        List<String> truthy = this.injectionModel.getMediatorVendor().getVendor().instance().getTruthy();
41
        this.falsy = this.injectionModel.getMediatorVendor().getVendor().instance().getFalsy();
42
        
43
        // No blind
44 2 1. <init> : negated conditional → NO_COVERAGE
2. <init> : negated conditional → NO_COVERAGE
        if (truthy.isEmpty() || this.injectionModel.isStoppedByUser()) {
45
            return;
46
        }
47
        
48
        // Call the SQL request which must be FALSE (usually ?id=-123456879)
49
        this.blankFalseMark = this.callUrl(
50
            StringUtils.EMPTY,
51
            "vendor:" + vendor
52
        );
53
54
        // Concurrent calls to the FALSE statements,
55
        // it will use inject() from the model
56
        ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableVendorTagTrue");
57
        Collection<CallableVendor> listCallableTagTrue = new ArrayList<>();
58
        
59
        for (String urlTest: truthy) {
60
            listCallableTagTrue.add(
61
                new CallableVendor(
62
                    vendorSpecificWithMode.replace(VendorYaml.TEST, urlTest),
63
                    this,
64
                    "vendor#true"
65
                )
66
            );
67
        }
68
        
69
        // Delete junk from the results of FALSE statements,
70
        // keep only opcodes found in each and every FALSE pages.
71
        // Allow the user to stop the loop
72
        try {
73
            List<Future<CallableVendor>> listTagTrue = taskExecutor.invokeAll(listCallableTagTrue);
74 1 1. <init> : removed call to com/jsql/util/ThreadUtil::shutdown → NO_COVERAGE
            this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
75
            
76 2 1. <init> : negated conditional → NO_COVERAGE
2. <init> : changed conditional boundary → NO_COVERAGE
            for (var i = 1 ; i < listTagTrue.size() ; i++) {
77
                
78 1 1. <init> : negated conditional → NO_COVERAGE
                if (this.injectionModel.isStoppedByUser()) {
79
                    return;
80
                }
81
82 1 1. <init> : negated conditional → NO_COVERAGE
                if (this.constantTrueMark.isEmpty()) {
83
                    this.constantTrueMark = listTagTrue.get(i).get().getOpcodes();
84
                } else {
85
                    this.constantTrueMark.retainAll(listTagTrue.get(i).get().getOpcodes());
86
                }
87
            }
88
        } catch (ExecutionException e) {
89
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
90
        } catch (InterruptedException e) {
91
            
92
            LOGGER.log(LogLevelUtil.IGNORE, e, e);
93 1 1. <init> : removed call to java/lang/Thread::interrupt → NO_COVERAGE
            Thread.currentThread().interrupt();
94
        }
95
        
96 1 1. <init> : removed call to com/jsql/model/injection/strategy/blind/InjectionVendor::initializeFalseMarks → NO_COVERAGE
        this.initializeFalseMarks(vendorSpecificWithMode);
97
    }
98
    
99
    private void initializeFalseMarks(String vendorSpecificWithMode) {
100
        
101
        // Concurrent calls to the TRUE statements,
102
        // it will use inject() from the model.
103
        ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableVendorTagFalse");
104
        Collection<CallableVendor> listCallableTagFalse = new ArrayList<>();
105
        
106
        for (String urlTest: this.falsy) {
107
            listCallableTagFalse.add(
108
                new CallableVendor(
109
                    vendorSpecificWithMode.replace(VendorYaml.TEST, urlTest),
110
                    this,
111
                    "vendor#false"
112
                )
113
            );
114
        }
115
        
116
        // Remove TRUE opcodes in the FALSE opcodes, because
117
        // a significant FALSE statement shouldn't contain any TRUE opcode.
118
        // Allow the user to stop the loop.
119
        try {
120
            List<Future<CallableVendor>> listTagFalse = taskExecutor.invokeAll(listCallableTagFalse);
121 1 1. initializeFalseMarks : removed call to com/jsql/util/ThreadUtil::shutdown → NO_COVERAGE
            this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
122
        
123
            for (Future<CallableVendor> falseTag: listTagFalse) {
124
                
125 1 1. initializeFalseMarks : negated conditional → NO_COVERAGE
                if (this.injectionModel.isStoppedByUser()) {
126
                    return;
127
                }
128
129
                this.constantTrueMark.removeAll(falseTag.get().getOpcodes());
130
            }
131
        } catch (ExecutionException e) {
132
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
133
        } catch (InterruptedException e) {
134
135
            LOGGER.log(LogLevelUtil.IGNORE, e, e);
136 1 1. initializeFalseMarks : removed call to java/lang/Thread::interrupt → NO_COVERAGE
            Thread.currentThread().interrupt();
137
        }
138
    }
139
140
    public boolean isInjectable(String vendorSpecificWithMode) throws StoppedByUserSlidingException {
141
        
142 1 1. isInjectable : negated conditional → NO_COVERAGE
        if (this.injectionModel.isStoppedByUser()) {
143
            throw new StoppedByUserSlidingException();
144
        }
145
146
        var blindTest = new CallableVendor(
147
            vendorSpecificWithMode.replace(VendorYaml.TEST, this.injectionModel.getMediatorVendor().getVendor().instance().sqlTestBooleanInitialization()),
148
            this,
149
            "vendor#confirm"
150
        );
151
        
152
        try {
153
            blindTest.call();
154
        } catch (Exception e) {
155
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
156
        }
157
158 3 1. isInjectable : negated conditional → NO_COVERAGE
2. isInjectable : replaced boolean return with true for com/jsql/model/injection/strategy/blind/InjectionVendor::isInjectable → NO_COVERAGE
3. isInjectable : negated conditional → NO_COVERAGE
        return blindTest.isTrue() && !this.constantTrueMark.isEmpty();
159
    }
160
    
161
    public String callUrl(String urlString, String metadataInjectionProcess) {
162 1 1. callUrl : replaced return value with "" for com/jsql/model/injection/strategy/blind/InjectionVendor::callUrl → NO_COVERAGE
        return this.injectionModel.injectWithoutIndex(urlString, metadataInjectionProcess);
163
    }
164
165
    public String callUrl(String urlString, String metadataInjectionProcess, AbstractCallableBoolean<?> callableBoolean) {
166 1 1. callUrl : replaced return value with "" for com/jsql/model/injection/strategy/blind/InjectionVendor::callUrl → NO_COVERAGE
        return this.injectionModel.injectWithoutIndex(urlString, metadataInjectionProcess, callableBoolean);
167
    }
168
169
170
    // Getter
171
172
    public String getBlankFalseMark() {
173 1 1. getBlankFalseMark : replaced return value with "" for com/jsql/model/injection/strategy/blind/InjectionVendor::getBlankFalseMark → NO_COVERAGE
        return this.blankFalseMark;
174
    }
175
    
176
    public List<Diff> getConstantTrueMark() {
177 1 1. getConstantTrueMark : replaced return value with Collections.emptyList for com/jsql/model/injection/strategy/blind/InjectionVendor::getConstantTrueMark → NO_COVERAGE
        return this.constantTrueMark;
178
    }
179
}

Mutations

44

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

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

74

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

76

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

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

78

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

82

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

93

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

96

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

121

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

125

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

136

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

142

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

158

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

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

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

162

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

166

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

173

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

177

1.1
Location : getConstantTrueMark
Killed by : none
replaced return value with Collections.emptyList for com/jsql/model/injection/strategy/blind/InjectionVendor::getConstantTrueMark → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.16.1