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 2.2 |
|
74 |
1.1 |
|
76 |
1.1 2.2 |
|
78 |
1.1 |
|
82 |
1.1 |
|
93 |
1.1 |
|
96 |
1.1 |
|
121 |
1.1 |
|
125 |
1.1 |
|
136 |
1.1 |
|
142 |
1.1 |
|
158 |
1.1 2.2 3.3 |
|
162 |
1.1 |
|
166 |
1.1 |
|
173 |
1.1 |
|
177 |
1.1 |