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

Mutations

42

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

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

71

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

73

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

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

74

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

77

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/InjectionVendor::initFalseMarks → NO_COVERAGE

113

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

115

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

124

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

129

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

144

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

148

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

152

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

159

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

163

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