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

Mutations

45

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

77

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

80

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

90

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

93

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

116

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

118

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

127

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

132

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

147

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

151

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

155

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

162

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

166

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