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

Mutations

41

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

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

70

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

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

73

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

76

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

86

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

89

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

112

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

114

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

123

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

128

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

143

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

147

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

151

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

158

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

162

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