1 | package com.jsql.model.injection.vendor.model; | |
2 | ||
3 | import com.jsql.model.InjectionModel; | |
4 | import com.jsql.model.bean.database.Database; | |
5 | import com.jsql.model.bean.database.Table; | |
6 | import com.jsql.model.injection.strategy.blind.AbstractInjectionBoolean.BooleanMode; | |
7 | import com.jsql.model.injection.vendor.model.yaml.Method; | |
8 | import com.jsql.model.injection.vendor.model.yaml.ModelYaml; | |
9 | import com.jsql.util.LogLevelUtil; | |
10 | import com.jsql.util.StringUtil; | |
11 | import org.apache.commons.codec.binary.Hex; | |
12 | import org.apache.commons.lang3.RandomStringUtils; | |
13 | import org.apache.commons.lang3.StringUtils; | |
14 | import org.apache.logging.log4j.LogManager; | |
15 | import org.apache.logging.log4j.Logger; | |
16 | import org.yaml.snakeyaml.Yaml; | |
17 | ||
18 | import java.net.URLEncoder; | |
19 | import java.nio.charset.StandardCharsets; | |
20 | import java.util.ArrayList; | |
21 | import java.util.Collections; | |
22 | import java.util.List; | |
23 | import java.util.regex.Pattern; | |
24 | ||
25 | import static com.jsql.model.accessible.DataAccess.*; | |
26 | ||
27 | public class VendorYaml implements AbstractVendor { | |
28 | | |
29 | /** | |
30 | * Log4j logger sent to view. | |
31 | */ | |
32 | private static final Logger LOGGER = LogManager.getRootLogger(); | |
33 | ||
34 | /** | |
35 | * SQL characters marking the end of the result of an injection. | |
36 | * Process stops when this schema is encountered: | |
37 | * <pre>SqLix01x03x03x07 | |
38 | */ | |
39 | public static final String LEAD_HEX = "0x53714c69"; | |
40 | public static final String LEAD_PIPE = "Sq'||'Li"; | |
41 | public static final String TRAIL_SQL = "%01%03%03%07"; | |
42 | public static final String TRAIL_HEX = "0x01030307"; | |
43 | ||
44 | /** | |
45 | * SQL character used between each table cells. | |
46 | * Expected schema of multiple table cells : | |
47 | * <pre> | |
48 | * %04[table cell]%05[number of occurrences]%04%06%04[table cell]%05[number of occurrences]%04 | |
49 | */ | |
50 | public static final String SEPARATOR_CELL_SQL = "%06"; | |
51 | public static final String SEPARATOR_CELL_HEX = "0x06"; | |
52 | ||
53 | public static final String ENCLOSE_VALUE_HEX = "0x04"; | |
54 | ||
55 | /** | |
56 | * SQL character used between the table cell and the number of occurrence of the cell text. | |
57 | * Expected schema of a table cell data is | |
58 | * <pre>%04[table cell]%05[number of occurrences]%04 | |
59 | */ | |
60 | public static final String SEPARATOR_QTE_SQL = "%05"; | |
61 | public static final String SEPARATOR_QTE_HEX = "0x05"; | |
62 | ||
63 | /** | |
64 | * SQL character enclosing a table cell returned by injection. | |
65 | * It allows to detect the correct end of a table cell data during parsing. | |
66 | * Expected schema of a table cell data is | |
67 | * <pre>%04[table cell]%05[number of occurrences]%04 | |
68 | */ | |
69 | public static final String ENCLOSE_VALUE_SQL = "%04"; | |
70 | ||
71 | public static final String CALIBRATOR_SQL = "%23"; | |
72 | public static final String CALIBRATOR_HEX = "0x23"; | |
73 | | |
74 | public static final String FORMAT_INDEX = "1337%s7331"; | |
75 | ||
76 | private static final String BOOLEAN_MODE = "${boolean.mode}"; | |
77 | ||
78 | public static final String LIMIT = "${limit}"; | |
79 | private static final String LIMIT_VALUE = "${limit.value}"; | |
80 | ||
81 | private static final String RESULT_RANGE = "${result_range}"; | |
82 | ||
83 | private static final String INDICE_UNIQUE = "${indice_unique}"; | |
84 | ||
85 | private static final String CALIBRATOR = "${calibrator}"; | |
86 | ||
87 | private static final String INDICES = "${indices}"; | |
88 | public static final String INDICE = "${indice}"; | |
89 | public static final String WINDOW_CHAR = "${window.char}"; | |
90 | public static final String BLOCK_MULTIBIT = "${multibit.block}"; | |
91 | ||
92 | public static final String WINDOW = "${window}"; | |
93 | ||
94 | public static final String CAPACITY = "${capacity}"; | |
95 | public static final String DEFAULT_CAPACITY = "65565"; | |
96 | ||
97 | private static final String SLEEP_TIME = "${sleep_time}"; | |
98 | ||
99 | private static final String BIT = "${bit}"; | |
100 | ||
101 | public static final String INJECTION = "${injection}"; | |
102 | ||
103 | public static final String TEST = "${test}"; | |
104 | ||
105 | private static final String FILEPATH = "${filepath}"; | |
106 | private static final String FILEPATH_HEX = "${filepath.hex}"; | |
107 | ||
108 | private static final String BODY_HEX = "${body.hex}"; | |
109 | ||
110 | private static final String FIELDS = "${fields}"; | |
111 | private static final String FIELD = "${field.value}"; | |
112 | ||
113 | private static final String TABLE = "${table}"; | |
114 | private static final String DATABASE = "${database}"; | |
115 | ||
116 | private static final String TABLE_HEX = "${table.hex}"; | |
117 | private static final String DATABASE_HEX = "${database.hex}"; | |
118 | | |
119 | private final ModelYaml modelYaml; | |
120 | | |
121 | private final InjectionModel injectionModel; | |
122 | | |
123 | public VendorYaml(String fileYaml, InjectionModel injectionModel) { | |
124 | | |
125 | this.injectionModel = injectionModel; | |
126 | | |
127 | var yaml = new Yaml(); | |
128 | this.modelYaml = yaml.loadAs( | |
129 | VendorYaml.class.getClassLoader().getResourceAsStream("vendor/"+ fileYaml), | |
130 | ModelYaml.class | |
131 | ); | |
132 | } | |
133 | ||
134 | @Override | |
135 | public String sqlDatabases() { | |
136 | | |
137 | String sqlQuery = this.modelYaml.getResource().getSchema().getDatabase(); | |
138 | | |
139 |
1
1. sqlDatabases : negated conditional → NO_COVERAGE |
if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isDiosStrategy()) { |
140 |
1
1. sqlDatabases : negated conditional → NO_COVERAGE |
if (StringUtils.isNotBlank(this.modelYaml.getResource().getDios().getDatabase())) { |
141 | sqlQuery = this.modelYaml.getResource().getDios().getDatabase(); | |
142 | } else { | |
143 | LOGGER.log( | |
144 | LogLevelUtil.CONSOLE_INFORM, | |
145 | "Strategy [Dios] activated but database query is undefined for [{}], fallback to default", | |
146 |
1
1. lambda$sqlDatabases$0 : replaced return value with null for com/jsql/model/injection/vendor/model/VendorYaml::lambda$sqlDatabases$0 → NO_COVERAGE |
() -> this.injectionModel.getMediatorVendor().getVendor() |
147 | ); | |
148 | } | |
149 |
1
1. sqlDatabases : negated conditional → NO_COVERAGE |
} else if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isZipStrategy()) { |
150 |
1
1. sqlDatabases : negated conditional → NO_COVERAGE |
if (StringUtils.isNotBlank(this.modelYaml.getResource().getZip().getDatabase())) { |
151 | sqlQuery = this.modelYaml.getResource().getZip().getDatabase(); | |
152 | } else { | |
153 | LOGGER.log( | |
154 | LogLevelUtil.CONSOLE_INFORM, | |
155 | "Strategy [Zip] activated but database query is undefined for [{}], fallback to default", | |
156 |
1
1. lambda$sqlDatabases$1 : replaced return value with null for com/jsql/model/injection/vendor/model/VendorYaml::lambda$sqlDatabases$1 → NO_COVERAGE |
() -> this.injectionModel.getMediatorVendor().getVendor() |
157 | ); | |
158 | } | |
159 | } | |
160 | | |
161 |
1
1. sqlDatabases : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlDatabases → NO_COVERAGE |
return sqlQuery; |
162 | } | |
163 | | |
164 | @Override | |
165 | public String sqlTables(Database database) { | |
166 | | |
167 | String sqlQuery = this.modelYaml.getResource().getSchema().getTable(); | |
168 | | |
169 |
1
1. sqlTables : negated conditional → NO_COVERAGE |
if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isDiosStrategy()) { |
170 |
1
1. sqlTables : negated conditional → NO_COVERAGE |
if (StringUtils.isNotBlank(this.modelYaml.getResource().getDios().getTable())) { |
171 | sqlQuery = this.modelYaml.getResource().getDios().getTable(); | |
172 | } else { | |
173 | LOGGER.log( | |
174 | LogLevelUtil.CONSOLE_INFORM, | |
175 | "Strategy [Dios] activated but table query is undefined for [{}], fallback to default", | |
176 |
1
1. lambda$sqlTables$2 : replaced return value with null for com/jsql/model/injection/vendor/model/VendorYaml::lambda$sqlTables$2 → NO_COVERAGE |
() -> this.injectionModel.getMediatorVendor().getVendor() |
177 | ); | |
178 | } | |
179 |
1
1. sqlTables : negated conditional → NO_COVERAGE |
} else if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isZipStrategy()) { |
180 |
1
1. sqlTables : negated conditional → NO_COVERAGE |
if (StringUtils.isNotBlank(this.modelYaml.getResource().getZip().getTable())) { |
181 | sqlQuery = this.modelYaml.getResource().getZip().getTable(); | |
182 | } else { | |
183 | LOGGER.log( | |
184 | LogLevelUtil.CONSOLE_INFORM, | |
185 | "Strategy [Zip] activated but table query is undefined for [{}], fallback to default", | |
186 |
1
1. lambda$sqlTables$3 : replaced return value with null for com/jsql/model/injection/vendor/model/VendorYaml::lambda$sqlTables$3 → NO_COVERAGE |
() -> this.injectionModel.getMediatorVendor().getVendor() |
187 | ); | |
188 | } | |
189 | } | |
190 | | |
191 | String databaseUtf8 = Hex.encodeHexString(database.toString().getBytes(StandardCharsets.UTF_8)); | |
192 | | |
193 |
1
1. sqlTables : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlTables → NO_COVERAGE |
return sqlQuery |
194 | .replace(DATABASE_HEX, databaseUtf8) | |
195 | .replace(DATABASE, database.toString()); | |
196 | } | |
197 | ||
198 | @Override | |
199 | public String sqlColumns(Table table) { | |
200 | | |
201 | String sqlQuery = this.modelYaml.getResource().getSchema().getColumn(); | |
202 | | |
203 |
1
1. sqlColumns : negated conditional → NO_COVERAGE |
if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isDiosStrategy()) { |
204 |
1
1. sqlColumns : negated conditional → NO_COVERAGE |
if (StringUtils.isNotBlank(this.modelYaml.getResource().getDios().getColumn())) { |
205 | sqlQuery = this.modelYaml.getResource().getDios().getColumn(); | |
206 | } else { | |
207 | LOGGER.log( | |
208 | LogLevelUtil.CONSOLE_INFORM, | |
209 | "Strategy [Dios] activated but column query is undefined for [{}], fallback to default", | |
210 |
1
1. lambda$sqlColumns$4 : replaced return value with null for com/jsql/model/injection/vendor/model/VendorYaml::lambda$sqlColumns$4 → NO_COVERAGE |
() -> this.injectionModel.getMediatorVendor().getVendor() |
211 | ); | |
212 | } | |
213 |
1
1. sqlColumns : negated conditional → NO_COVERAGE |
} else if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isZipStrategy()) { |
214 |
1
1. sqlColumns : negated conditional → NO_COVERAGE |
if (StringUtils.isNotBlank(this.modelYaml.getResource().getZip().getColumn())) { |
215 | sqlQuery = this.modelYaml.getResource().getZip().getColumn(); | |
216 | } else { | |
217 | LOGGER.log( | |
218 | LogLevelUtil.CONSOLE_INFORM, | |
219 | "Strategy [Zip] activated but column query is undefined for [{}], fallback to default", | |
220 |
1
1. lambda$sqlColumns$5 : replaced return value with null for com/jsql/model/injection/vendor/model/VendorYaml::lambda$sqlColumns$5 → NO_COVERAGE |
() -> this.injectionModel.getMediatorVendor().getVendor() |
221 | ); | |
222 | } | |
223 | } | |
224 | | |
225 | String databaseUtf8 = Hex.encodeHexString(table.getParent().toString().getBytes(StandardCharsets.UTF_8)); | |
226 | String tableUtf8 = Hex.encodeHexString(table.toString().getBytes(StandardCharsets.UTF_8)); | |
227 | | |
228 |
1
1. sqlColumns : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlColumns → NO_COVERAGE |
return sqlQuery |
229 | .replace(DATABASE_HEX, databaseUtf8) | |
230 | .replace(TABLE_HEX, tableUtf8) | |
231 | .replace(DATABASE, table.getParent().toString()) | |
232 | .replace(TABLE, table.toString()); | |
233 | } | |
234 | ||
235 | @Override | |
236 | public String sqlRows(String[] namesColumns, Database database, Table table) { | |
237 | | |
238 | String sqlField = this.modelYaml.getResource().getSchema().getRow().getFields().getField(); | |
239 | String sqlConcatFields = this.modelYaml.getResource().getSchema().getRow().getFields().getConcat(); | |
240 | String sqlQuery = this.modelYaml.getResource().getSchema().getRow().getQuery(); | |
241 | | |
242 |
1
1. sqlRows : negated conditional → NO_COVERAGE |
if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isDiosStrategy()) { |
243 |
1
1. sqlRows : negated conditional → NO_COVERAGE |
if (StringUtils.isNotBlank(this.modelYaml.getResource().getDios().getDatabase())) { |
244 | ||
245 | sqlField = this.modelYaml.getResource().getDios().getRow().getFields().getField(); | |
246 | sqlConcatFields = this.modelYaml.getResource().getDios().getRow().getFields().getConcat(); | |
247 | sqlQuery = this.modelYaml.getResource().getDios().getRow().getQuery(); | |
248 | | |
249 | } else { | |
250 | LOGGER.log( | |
251 | LogLevelUtil.CONSOLE_INFORM, | |
252 | "Strategy [Dios] activated but row query is undefined for [{}], fallback to default", | |
253 |
1
1. lambda$sqlRows$6 : replaced return value with null for com/jsql/model/injection/vendor/model/VendorYaml::lambda$sqlRows$6 → NO_COVERAGE |
() -> this.injectionModel.getMediatorVendor().getVendor() |
254 | ); | |
255 | } | |
256 |
1
1. sqlRows : negated conditional → NO_COVERAGE |
} else if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isZipStrategy()) { |
257 |
1
1. sqlRows : negated conditional → NO_COVERAGE |
if (StringUtils.isNotBlank(this.modelYaml.getResource().getZip().getDatabase())) { |
258 | ||
259 | sqlField = this.modelYaml.getResource().getZip().getRow().getFields().getField(); | |
260 | sqlConcatFields = this.modelYaml.getResource().getZip().getRow().getFields().getConcat(); | |
261 | sqlQuery = this.modelYaml.getResource().getZip().getRow().getQuery(); | |
262 | | |
263 | } else { | |
264 | LOGGER.log( | |
265 | LogLevelUtil.CONSOLE_INFORM, | |
266 | "Strategy [Zip] activated but row query is undefined for [{}], fallback to default", | |
267 |
1
1. lambda$sqlRows$7 : replaced return value with null for com/jsql/model/injection/vendor/model/VendorYaml::lambda$sqlRows$7 → NO_COVERAGE |
() -> this.injectionModel.getMediatorVendor().getVendor() |
268 | ); | |
269 | } | |
270 | } | |
271 | | |
272 | var matcherSqlField = Pattern.compile("(?s)(.*)"+ Pattern.quote(FIELD) +"(.*)").matcher(sqlField); | |
273 | String leadSqlField = StringUtils.EMPTY; | |
274 | String trailSqlField = StringUtils.EMPTY; | |
275 | | |
276 |
1
1. sqlRows : negated conditional → NO_COVERAGE |
if (matcherSqlField.find()) { |
277 | | |
278 | leadSqlField = matcherSqlField.group(1); | |
279 | trailSqlField = matcherSqlField.group(2); | |
280 | } | |
281 | | |
282 | var namesColumnUtf8 = new String[namesColumns.length]; | |
283 | | |
284 |
2
1. sqlRows : changed conditional boundary → NO_COVERAGE 2. sqlRows : negated conditional → NO_COVERAGE |
for (var i = 0 ; i < namesColumns.length ; i++) { |
285 | | |
286 | namesColumnUtf8[i] = StringUtil.detectUtf8(namesColumns[i]); | |
287 | namesColumnUtf8[i] = URLEncoder.encode(namesColumnUtf8[i], StandardCharsets.UTF_8); | |
288 | } | |
289 | | |
290 | var nameDatabaseUtf8 = StringUtil.detectUtf8(database.toString()); | |
291 | nameDatabaseUtf8 = URLEncoder.encode(nameDatabaseUtf8, StandardCharsets.UTF_8); | |
292 | | |
293 | var nameTableUtf8 = StringUtil.detectUtf8(table.toString()); | |
294 | nameTableUtf8 = URLEncoder.encode(nameTableUtf8, StandardCharsets.UTF_8); | |
295 | | |
296 |
1
1. sqlRows : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlRows → NO_COVERAGE |
return sqlQuery.replace( |
297 | FIELDS, | |
298 | leadSqlField | |
299 | + String.join( | |
300 | trailSqlField + sqlConcatFields + leadSqlField, | |
301 | namesColumnUtf8 | |
302 | ) | |
303 | + trailSqlField | |
304 | ) | |
305 | .replace(DATABASE, nameDatabaseUtf8) | |
306 | .replace(TABLE, nameTableUtf8); | |
307 | } | |
308 | ||
309 | @Override | |
310 | public String sqlFileRead(String filePath) { | |
311 |
1
1. sqlFileRead : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlFileRead → NO_COVERAGE |
return this.modelYaml.getResource().getFile().getRead() |
312 | .replace(FILEPATH_HEX, Hex.encodeHexString(filePath.getBytes(StandardCharsets.UTF_8))) // MySQL | |
313 | .replace(FILEPATH, filePath); // PostgreSQL | |
314 | } | |
315 | ||
316 | @Override | |
317 | public String sqlTextIntoFile(String body, String path) { | |
318 | ||
319 | String visibleIndex = String.format( | |
320 | VendorYaml.FORMAT_INDEX, | |
321 | this.injectionModel.getMediatorStrategy().getSpecificNormal().getVisibleIndex() | |
322 | ); | |
323 | ||
324 |
1
1. sqlTextIntoFile : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlTextIntoFile → NO_COVERAGE |
return this.injectionModel.getIndexesInUrl() |
325 | .replaceAll( | |
326 | visibleIndex, | |
327 | this.modelYaml.getResource().getFile().getWrite() | |
328 | .getBody() | |
329 | .replace( | |
330 | BODY_HEX, | |
331 | Hex.encodeHexString(body.getBytes(StandardCharsets.UTF_8)) | |
332 | ) | |
333 | ) | |
334 | + StringUtils.SPACE | |
335 | + this.modelYaml.getResource().getFile().getWrite() | |
336 | .getPath() | |
337 | .replace(FILEPATH, path); | |
338 | } | |
339 | ||
340 | @Override | |
341 | public String sqlTestBlind(String check, BooleanMode blindMode) { | |
342 | ||
343 | String replacement = getMode(blindMode); | |
344 | ||
345 |
1
1. sqlTestBlind : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlTestBlind → NO_COVERAGE |
return this.modelYaml.getStrategy().getBoolean() |
346 | .getBlind() | |
347 | .replace(BOOLEAN_MODE, replacement) | |
348 | .replace(TEST, check) | |
349 | .trim(); // trim spaces in '${boolean.mode} ${test}' when no mode, not covered by cleanSql() | |
350 | } | |
351 | ||
352 | @Override | |
353 | public String sqlBitTestBlind(String inj, int indexCharacter, int bit, BooleanMode blindMode) { | |
354 | ||
355 | String replacement = getMode(blindMode); | |
356 | ||
357 |
1
1. sqlBitTestBlind : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlBitTestBlind → NO_COVERAGE |
return this.modelYaml.getStrategy().getBoolean() |
358 | .getBlind() | |
359 | .replace(BOOLEAN_MODE, replacement) | |
360 | .replace( | |
361 | TEST, | |
362 | this.modelYaml.getStrategy().getBoolean().getTest().getBit() | |
363 | .replace(INJECTION, inj) | |
364 | .replace(WINDOW_CHAR, Integer.toString(indexCharacter)) | |
365 | .replace(BIT, Integer.toString(bit)) | |
366 | ) | |
367 | .trim(); // trim spaces in '${boolean.mode} ${test}' when no mode, not covered by cleanSql() | |
368 | } | |
369 | ||
370 | @Override | |
371 | public String sqlTimeTest(String check, BooleanMode blindMode) { | |
372 | ||
373 | String replacement = getMode(blindMode); | |
374 |
1
1. sqlTimeTest : negated conditional → NO_COVERAGE |
int countSleepTimeStrategy = this.injectionModel.getMediatorUtils().getPreferencesUtil().isLimitingSleepTimeStrategy() |
375 | ? this.injectionModel.getMediatorUtils().getPreferencesUtil().countSleepTimeStrategy() | |
376 | : 5; | |
377 | ||
378 |
1
1. sqlTimeTest : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlTimeTest → NO_COVERAGE |
return this.modelYaml.getStrategy().getBoolean() |
379 | .getTime() | |
380 | .replace(BOOLEAN_MODE, replacement) | |
381 | .replace(TEST, check) | |
382 | .replace(SLEEP_TIME, Long.toString(countSleepTimeStrategy)) | |
383 | .trim(); // trim spaces in '${boolean.mode} ${test}' when no mode, not covered by cleanSql() | |
384 | } | |
385 | ||
386 | @Override | |
387 | public String sqlBitTestTime(String inj, int indexCharacter, int bit, BooleanMode blindMode) { | |
388 | ||
389 | String replacement = getMode(blindMode); | |
390 |
1
1. sqlBitTestTime : negated conditional → NO_COVERAGE |
int countSleepTimeStrategy = this.injectionModel.getMediatorUtils().getPreferencesUtil().isLimitingSleepTimeStrategy() |
391 | ? this.injectionModel.getMediatorUtils().getPreferencesUtil().countSleepTimeStrategy() | |
392 | : 5; | |
393 | ||
394 |
1
1. sqlBitTestTime : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlBitTestTime → NO_COVERAGE |
return this.modelYaml.getStrategy().getBoolean() |
395 | .getTime() | |
396 | .replace(BOOLEAN_MODE, replacement) | |
397 | .replace( | |
398 | TEST, | |
399 | this.modelYaml.getStrategy().getBoolean().getTest() | |
400 | .getBit() | |
401 | .replace(INJECTION, inj) | |
402 | .replace(WINDOW_CHAR, Integer.toString(indexCharacter)) | |
403 | .replace(BIT, Integer.toString(bit)) | |
404 | ) | |
405 | .replace(SLEEP_TIME, Long.toString(countSleepTimeStrategy)) | |
406 | .trim(); // trim spaces in '${boolean.mode} ${test}' when no mode, not covered by cleanSql() | |
407 | } | |
408 | ||
409 | private String getMode(BooleanMode blindMode) { | |
410 | ||
411 | String replacement; | |
412 | switch (blindMode) { | |
413 | case AND: replacement = this.modelYaml.getStrategy().getBoolean().getModeAnd(); break; | |
414 | case OR: replacement = this.modelYaml.getStrategy().getBoolean().getModeOr(); break; | |
415 | case STACKED: replacement = this.modelYaml.getStrategy().getBoolean().getModeStacked(); break; | |
416 | case NO_MODE: | |
417 | default: replacement = StringUtils.EMPTY; break; | |
418 | } | |
419 | return replacement; | |
420 | } | |
421 | ||
422 | @Override | |
423 | public String sqlBlind(String sqlQuery, String startPosition, boolean isReport) { | |
424 |
1
1. sqlBlind : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlBlind → NO_COVERAGE |
return VendorYaml.replaceTags( |
425 | getSlidingWindow(isReport) | |
426 | .replace(INJECTION, sqlQuery) | |
427 | .replace(WINDOW_CHAR, startPosition) | |
428 | .replace(CAPACITY, DEFAULT_CAPACITY) | |
429 | ); | |
430 | } | |
431 | ||
432 | @Override | |
433 | public String sqlTime(String sqlQuery, String startPosition, boolean isReport) { | |
434 |
1
1. sqlTime : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlTime → NO_COVERAGE |
return VendorYaml.replaceTags( |
435 | getSlidingWindow(isReport) | |
436 | .replace(INJECTION, sqlQuery) | |
437 | .replace(WINDOW_CHAR, startPosition) | |
438 | .replace(CAPACITY, DEFAULT_CAPACITY) | |
439 | ); | |
440 | } | |
441 | ||
442 | @Override | |
443 | public String sqlMultibit(String inj, int indexCharacter, int block){ | |
444 |
1
1. sqlMultibit : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlMultibit → NO_COVERAGE |
return this.modelYaml.getStrategy().getBoolean().getMultibit() |
445 | .replace(INJECTION, inj) | |
446 | .replace(WINDOW_CHAR, Integer.toString(indexCharacter)) | |
447 | .replace(BLOCK_MULTIBIT, Integer.toString(block)); | |
448 | } | |
449 | ||
450 | @Override | |
451 | public String sqlErrorCalibrator(Method errorMethod) { | |
452 |
1
1. sqlErrorCalibrator : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlErrorCalibrator → NO_COVERAGE |
return VendorYaml.replaceTags( |
453 | errorMethod.getQuery() | |
454 | .replace(VendorYaml.WINDOW, this.modelYaml.getStrategy().getConfiguration().getSlidingWindow()) | |
455 | .replace(VendorYaml.INJECTION, this.modelYaml.getStrategy().getConfiguration().getCalibrator()) | |
456 | .replace(VendorYaml.WINDOW_CHAR, "1") | |
457 | .replace(VendorYaml.CAPACITY, Integer.toString(errorMethod.getCapacity())) | |
458 | ); | |
459 | } | |
460 | ||
461 | @Override | |
462 | public String sqlErrorIndice(Method errorMethod) { | |
463 | ||
464 | var indexZeroToFind = "0"; | |
465 | ||
466 |
1
1. sqlErrorIndice : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlErrorIndice → NO_COVERAGE |
return VendorYaml.replaceTags( |
467 | errorMethod.getQuery() | |
468 | .replace(VendorYaml.WINDOW, this.modelYaml.getStrategy().getConfiguration().getSlidingWindow()) | |
469 | .replace(VendorYaml.INJECTION, this.modelYaml.getStrategy().getConfiguration().getFailsafe().replace(INDICE, indexZeroToFind)) | |
470 | .replace(VendorYaml.WINDOW_CHAR, "1") | |
471 | .replace(VendorYaml.CAPACITY, Integer.toString(errorMethod.getCapacity())) | |
472 | ); | |
473 | } | |
474 | ||
475 | @Override | |
476 | public String sqlError(String sqlQuery, String startPosition, int indexMethodError, boolean isReport) { | |
477 |
1
1. sqlError : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlError → NO_COVERAGE |
return VendorYaml.replaceTags( |
478 | this.modelYaml.getStrategy().getError().getMethod().get(indexMethodError).getQuery() | |
479 | .replace(WINDOW, getSlidingWindow(isReport)) | |
480 | .replace(INJECTION, sqlQuery) | |
481 | .replace(WINDOW_CHAR, startPosition) | |
482 | .replace( | |
483 | CAPACITY, | |
484 | Integer.toString( | |
485 | this.modelYaml.getStrategy().getError() | |
486 | .getMethod() | |
487 | .get(indexMethodError) | |
488 | .getCapacity() | |
489 | ) | |
490 | ) | |
491 | ); | |
492 | } | |
493 | ||
494 | @Override | |
495 | public String sqlNormal(String sqlQuery, String startPosition, boolean isReport) { | |
496 |
1
1. sqlNormal : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlNormal → NO_COVERAGE |
return VendorYaml.replaceTags( |
497 | getSlidingWindow(isReport) | |
498 | .replace(INJECTION, sqlQuery) | |
499 | .replace(WINDOW_CHAR, startPosition) | |
500 | .replace(CAPACITY, this.injectionModel.getMediatorStrategy().getNormal().getPerformanceLength()) | |
501 | ); | |
502 | } | |
503 | ||
504 | @Override | |
505 | public String sqlStacked(String sqlQuery, String startPosition, boolean isReport) { | |
506 |
1
1. sqlStacked : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlStacked → NO_COVERAGE |
return this.modelYaml.getStrategy().getStacked().replace( |
507 | WINDOW, | |
508 | VendorYaml.replaceTags( | |
509 | getSlidingWindow(isReport) | |
510 | .replace(INJECTION, sqlQuery) | |
511 | .replace(WINDOW_CHAR, startPosition) | |
512 | .replace(CAPACITY, DEFAULT_CAPACITY) | |
513 | ) | |
514 | ); | |
515 | } | |
516 | ||
517 | @Override | |
518 | public String sqlCapacity(String[] indexes) { | |
519 | ||
520 | String regexIndexes = String.join("|", indexes); | |
521 | String regexVisibleIndexesToFind = String.format(VendorYaml.FORMAT_INDEX, "(%s)"); | |
522 | ||
523 |
1
1. sqlCapacity : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlCapacity → NO_COVERAGE |
return this.injectionModel.getIndexesInUrl().replaceAll( |
524 | String.format(regexVisibleIndexesToFind, regexIndexes), | |
525 | VendorYaml.replaceTags( | |
526 | this.modelYaml.getStrategy().getNormal().getCapacity() | |
527 | .replace(CALIBRATOR, this.modelYaml.getStrategy().getConfiguration().getCalibrator()) | |
528 | .replace(INDICE, "$1") | |
529 | ) | |
530 | ); | |
531 | } | |
532 | ||
533 | @Override | |
534 | public String sqlIndices(Integer nbFields) { | |
535 | | |
536 | String replaceTag = StringUtils.EMPTY; | |
537 | List<String> fields = new ArrayList<>(); | |
538 | | |
539 | var indice = 1; | |
540 | | |
541 |
2
1. sqlIndices : changed conditional boundary → NO_COVERAGE 2. sqlIndices : negated conditional → NO_COVERAGE |
for ( ; indice <= nbFields ; indice++) { |
542 | | |
543 | String field = this.modelYaml.getStrategy().getConfiguration().getFailsafe().replace(INDICE, Integer.toString(indice)); | |
544 | fields.add(field); | |
545 | replaceTag = field; | |
546 | } | |
547 | | |
548 |
1
1. sqlIndices : Changed increment from -1 to 1 → NO_COVERAGE |
indice--; |
549 | | |
550 |
1
1. sqlIndices : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlIndices → NO_COVERAGE |
return this.modelYaml.getStrategy().getNormal() |
551 | .getIndices() | |
552 | .replace( | |
553 | INDICES, | |
554 | String.join(",", fields.toArray(new String[0])) | |
555 | ) | |
556 | .replace(INDICE_UNIQUE, replaceTag) | |
557 | .replace( | |
558 | RESULT_RANGE, | |
559 | String.join(",", Collections.nCopies(indice, "r")) | |
560 | ); | |
561 | } | |
562 | ||
563 | @Override | |
564 | public String sqlLimit(Integer limitSQLResult) { | |
565 | | |
566 | var limitBoundary = 0; | |
567 | | |
568 | try { | |
569 | limitBoundary = Integer.parseInt(this.modelYaml.getStrategy().getConfiguration().getLimitBoundary()); | |
570 | } catch (NumberFormatException e) { | |
571 | LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Incorrect Limit start index, force to 0"); | |
572 | } | |
573 | | |
574 |
1
1. sqlLimit : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlLimit → NO_COVERAGE |
return this.modelYaml.getStrategy().getConfiguration() |
575 | .getLimit() | |
576 |
1
1. sqlLimit : Replaced integer addition with subtraction → NO_COVERAGE |
.replace(LIMIT_VALUE, Integer.toString(limitSQLResult + limitBoundary)); |
577 | } | |
578 | | |
579 | @Override | |
580 | public String fingerprintErrorsAsRegex() { | |
581 |
1
1. fingerprintErrorsAsRegex : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::fingerprintErrorsAsRegex → NO_COVERAGE |
return "(?si)"+ StringUtils.join( |
582 | this.modelYaml.getStrategy().getConfiguration().getFingerprint() | |
583 | .getErrorMessage() | |
584 | .stream() | |
585 |
1
1. lambda$fingerprintErrorsAsRegex$8 : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::lambda$fingerprintErrorsAsRegex$8 → NO_COVERAGE |
.map(m -> ".*"+ m +".*") |
586 | .toArray(), | |
587 | "|" | |
588 | ); | |
589 | } | |
590 | | |
591 | public static String replaceTags(String sqlRequest) { | |
592 |
1
1. replaceTags : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::replaceTags → NO_COVERAGE |
return sqlRequest |
593 | .replace("${enclose_value_sql}", ENCLOSE_VALUE_SQL) | |
594 | .replace("${enclose_value_hex}", ENCLOSE_VALUE_HEX) | |
595 | .replace("${separator_qte_sql}", SEPARATOR_QTE_SQL) | |
596 | .replace("${separator_qte_hex}", SEPARATOR_QTE_HEX) | |
597 | .replace("${separator_cell_sql}", SEPARATOR_CELL_SQL) | |
598 | .replace("${separator_cell_hex}", SEPARATOR_CELL_HEX) | |
599 | .replace("${calibrator_sql}", CALIBRATOR_SQL) | |
600 | .replace("${calibrator_hex}", CALIBRATOR_HEX) | |
601 | .replace("${trail_sql}", TRAIL_SQL) | |
602 | .replace("${trail_hex}", TRAIL_HEX) | |
603 | .replace("${lead}", LEAD) | |
604 | .replace("${lead_hex}", LEAD_HEX) | |
605 | .replace("${lead_pipe}", LEAD_PIPE); | |
606 | } | |
607 | ||
608 | /** | |
609 | * Get payload with sliding window except for vulnerability report | |
610 | */ | |
611 | private String getSlidingWindow(boolean isReport) { | |
612 |
2
1. getSlidingWindow : negated conditional → NO_COVERAGE 2. getSlidingWindow : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::getSlidingWindow → NO_COVERAGE |
return isReport |
613 | ? "(" + INJECTION + ")" | |
614 | : this.modelYaml.getStrategy().getConfiguration().getSlidingWindow(); | |
615 | } | |
616 | | |
617 | | |
618 | // Getter and setter | |
619 | ||
620 | @Override | |
621 | public String sqlBooleanBlind() { | |
622 |
1
1. sqlBooleanBlind : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlBooleanBlind → NO_COVERAGE |
return this.modelYaml.getStrategy().getBoolean().getBlind(); |
623 | } | |
624 | ||
625 | @Override | |
626 | public String sqlBooleanTime() { | |
627 |
1
1. sqlBooleanTime : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlBooleanTime → NO_COVERAGE |
return this.modelYaml.getStrategy().getBoolean().getTime(); |
628 | } | |
629 | ||
630 | @Override | |
631 | public String sqlInfos() { | |
632 |
1
1. sqlInfos : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlInfos → NO_COVERAGE |
return this.modelYaml.getResource().getInfo(); |
633 | } | |
634 | ||
635 | @Override | |
636 | public String sqlPrivilegeTest() { | |
637 |
1
1. sqlPrivilegeTest : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlPrivilegeTest → NO_COVERAGE |
return this.modelYaml.getResource().getFile().getPrivilege(); |
638 | } | |
639 | ||
640 | @Override | |
641 | public List<String> getFalsy() { | |
642 |
1
1. getFalsy : replaced return value with Collections.emptyList for com/jsql/model/injection/vendor/model/VendorYaml::getFalsy → NO_COVERAGE |
return this.modelYaml.getStrategy().getBoolean().getTest().getFalsy(); |
643 | } | |
644 | ||
645 | @Override | |
646 | public List<String> getTruthy() { | |
647 |
1
1. getTruthy : replaced return value with Collections.emptyList for com/jsql/model/injection/vendor/model/VendorYaml::getTruthy → NO_COVERAGE |
return this.modelYaml.getStrategy().getBoolean().getTest().getTruthy(); |
648 | } | |
649 | ||
650 | @Override | |
651 | public String sqlTestBooleanInitialization() { | |
652 |
1
1. sqlTestBooleanInitialization : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlTestBooleanInitialization → NO_COVERAGE |
return this.modelYaml.getStrategy().getBoolean().getTest().getInitialization(); |
653 | } | |
654 | ||
655 | @Override | |
656 | public String sqlOrderBy() { | |
657 |
1
1. sqlOrderBy : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::sqlOrderBy → NO_COVERAGE |
return this.modelYaml.getStrategy().getNormal().getOrderBy(); |
658 | } | |
659 | | |
660 | @Override | |
661 | public String endingComment() { | |
662 |
1
1. endingComment : negated conditional → NO_COVERAGE |
if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isUrlRandomSuffixDisabled()) { |
663 |
1
1. endingComment : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::endingComment → NO_COVERAGE |
return this.modelYaml.getStrategy().getConfiguration().getEndingComment(); |
664 | } else { | |
665 |
1
1. endingComment : replaced return value with "" for com/jsql/model/injection/vendor/model/VendorYaml::endingComment → NO_COVERAGE |
return this.modelYaml.getStrategy().getConfiguration().getEndingComment() |
666 | // Allows Boolean match fingerprinting on host errors | |
667 | + RandomStringUtils.randomAlphanumeric(4); | |
668 | } | |
669 | } | |
670 | ||
671 | @Override | |
672 | public ModelYaml getModelYaml() { | |
673 |
1
1. getModelYaml : replaced return value with null for com/jsql/model/injection/vendor/model/VendorYaml::getModelYaml → KILLED |
return this.modelYaml; |
674 | } | |
675 | } | |
Mutations | ||
139 |
1.1 |
|
140 |
1.1 |
|
146 |
1.1 |
|
149 |
1.1 |
|
150 |
1.1 |
|
156 |
1.1 |
|
161 |
1.1 |
|
169 |
1.1 |
|
170 |
1.1 |
|
176 |
1.1 |
|
179 |
1.1 |
|
180 |
1.1 |
|
186 |
1.1 |
|
193 |
1.1 |
|
203 |
1.1 |
|
204 |
1.1 |
|
210 |
1.1 |
|
213 |
1.1 |
|
214 |
1.1 |
|
220 |
1.1 |
|
228 |
1.1 |
|
242 |
1.1 |
|
243 |
1.1 |
|
253 |
1.1 |
|
256 |
1.1 |
|
257 |
1.1 |
|
267 |
1.1 |
|
276 |
1.1 |
|
284 |
1.1 2.2 |
|
296 |
1.1 |
|
311 |
1.1 |
|
324 |
1.1 |
|
345 |
1.1 |
|
357 |
1.1 |
|
374 |
1.1 |
|
378 |
1.1 |
|
390 |
1.1 |
|
394 |
1.1 |
|
424 |
1.1 |
|
434 |
1.1 |
|
444 |
1.1 |
|
452 |
1.1 |
|
466 |
1.1 |
|
477 |
1.1 |
|
496 |
1.1 |
|
506 |
1.1 |
|
523 |
1.1 |
|
541 |
1.1 2.2 |
|
548 |
1.1 |
|
550 |
1.1 |
|
574 |
1.1 |
|
576 |
1.1 |
|
581 |
1.1 |
|
585 |
1.1 |
|
592 |
1.1 |
|
612 |
1.1 2.2 |
|
622 |
1.1 |
|
627 |
1.1 |
|
632 |
1.1 |
|
637 |
1.1 |
|
642 |
1.1 |
|
647 |
1.1 |
|
652 |
1.1 |
|
657 |
1.1 |
|
662 |
1.1 |
|
663 |
1.1 |
|
665 |
1.1 |
|
673 |
1.1 |