TamperingUtil.java

1
package com.jsql.util;
2
3
import com.jsql.util.tampering.TamperingType;
4
import org.apache.commons.lang3.StringUtils;
5
import org.apache.logging.log4j.LogManager;
6
import org.apache.logging.log4j.Logger;
7
8
import javax.script.Invocable;
9
import javax.script.ScriptEngine;
10
import javax.script.ScriptEngineManager;
11
import javax.script.ScriptException;
12
import java.util.regex.Pattern;
13
14
public class TamperingUtil {
15
16
    private static final Logger LOGGER = LogManager.getRootLogger();
17
18
    public static final String TAG_OPENED = "<tampering>";
19
    public static final String TAG_CLOSED = "</tampering>";
20
21
    private boolean isBase64 = false;
22
    private boolean isVersionComment = false;
23
    private boolean isFunctionComment = false;
24
    private boolean isEqualToLike = false;
25
    private boolean isRandomCase = false;
26
    private boolean isHexToChar = false;
27
    private boolean isStringToChar = false;
28
    private boolean isQuoteToUtf8 = false;
29
    private boolean isCharToEncoding = false;
30
    private boolean isEval = false;
31
    private boolean isSpaceToMultilineComment = false;
32
    private boolean isSpaceToDashComment = false;
33
    private boolean isSpaceToSharpComment = false;
34
35
    private String customTamper = null;
36
37
    private static final ScriptEngineManager SCRIPT_ENGINE_MANAGER = new ScriptEngineManager();
38
39
    private static String eval(String sqlQuery, String jsTampering) {
40
        Object resultSqlTampered;
41
        try {
42 1 1. eval : negated conditional → KILLED
            if (StringUtils.isEmpty(jsTampering)) {
43
                throw new ScriptException("Tampering context is empty");
44
            }
45
46
            ScriptEngine nashornEngine = TamperingUtil.SCRIPT_ENGINE_MANAGER.getEngineByName("nashorn");
47
            nashornEngine.eval(jsTampering);
48
49
            var nashornInvocable = (Invocable) nashornEngine;
50
            resultSqlTampered = nashornInvocable.invokeFunction("tampering", sqlQuery);
51
52
        } catch (ScriptException e) {
53
            LOGGER.log(
54
                LogLevelUtil.CONSOLE_ERROR,
55
                String.format("Tampering context contains errors: %s", e.getMessage()),
56
                e
57
            );
58
            resultSqlTampered = sqlQuery;
59
        } catch (NoSuchMethodException e) {
60
            LOGGER.log(
61
                LogLevelUtil.CONSOLE_ERROR,
62
                String.format("Tampering context is not properly defined: %s", e.getMessage()),
63
                e
64
            );
65
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Minimal tampering context is: var tampering = function(sql) {return sql}");
66
            resultSqlTampered = sqlQuery;
67
        }
68 1 1. eval : replaced return value with "" for com/jsql/util/TamperingUtil::eval → KILLED
        return resultSqlTampered.toString();
69
    }
70
71
    public String tamper(String sqlQueryDefault) {
72
        String lead;
73
        String sqlQuery;
74
        String trail;
75
76
        // Transform only SQL query without HTTP parameters and syntax changed, like p=1'+[sql]
77
        String regexToMatchTamperTags = String.format("(?s)(.*%s)(.*)(%s.*)", TamperingUtil.TAG_OPENED, TamperingUtil.TAG_CLOSED);
78
        var matcherSql = Pattern.compile(regexToMatchTamperTags).matcher(sqlQueryDefault);
79
80 1 1. tamper : negated conditional → KILLED
        if (matcherSql.find()) {
81
            lead = matcherSql.group(1);
82
            sqlQuery = matcherSql.group(2);
83
            trail = matcherSql.group(3);
84
        } else {
85 1 1. tamper : replaced return value with "" for com/jsql/util/TamperingUtil::tamper → NO_COVERAGE
            return sqlQueryDefault;
86
        }
87
88 1 1. tamper : negated conditional → KILLED
        if (this.isEval) {
89
            sqlQuery = TamperingUtil.eval(sqlQuery, this.customTamper);
90
        }
91
92
        sqlQuery = this.transform(sqlQuery, this.isHexToChar, TamperingType.HEX_TO_CHAR);
93
        sqlQuery = this.transform(sqlQuery, this.isStringToChar, TamperingType.STRING_TO_CHAR);
94
        sqlQuery = this.transform(sqlQuery, this.isFunctionComment, TamperingType.COMMENT_TO_METHOD_SIGNATURE);
95
        sqlQuery = this.transform(sqlQuery, this.isVersionComment, TamperingType.VERSIONED_COMMENT_TO_METHOD_SIGNATURE);
96
        sqlQuery = this.transform(sqlQuery, this.isRandomCase, TamperingType.RANDOM_CASE);
97
        sqlQuery = this.transform(sqlQuery, this.isEqualToLike, TamperingType.EQUAL_TO_LIKE);
98
99
        sqlQuery = lead + sqlQuery + trail;
100
101
        String regexToRemoveTamperTags = String.format("(?i)%s|%s", TamperingUtil.TAG_OPENED, TamperingUtil.TAG_CLOSED);
102
        sqlQuery = sqlQuery.replaceAll(regexToRemoveTamperTags, StringUtils.EMPTY);
103
104
        // Empty when checking character insertion
105 1 1. tamper : negated conditional → KILLED
        if (StringUtils.isEmpty(sqlQuery)) {
106
            return StringUtils.EMPTY;
107
        }
108
109
        // Transform all query, SQL and HTTP
110
111
        // Dependency to: EQUAL_TO_LIKE
112 1 1. tamper : negated conditional → KILLED
        if (this.isSpaceToDashComment) {
113
            sqlQuery = TamperingUtil.eval(sqlQuery, TamperingType.SPACE_TO_DASH_COMMENT.instance().getJavascript());
114 1 1. tamper : negated conditional → KILLED
        } else if (this.isSpaceToMultilineComment) {
115
            sqlQuery = TamperingUtil.eval(sqlQuery, TamperingType.SPACE_TO_MULTILINE_COMMENT.instance().getJavascript());
116 1 1. tamper : negated conditional → KILLED
        } else if (this.isSpaceToSharpComment) {
117
            sqlQuery = TamperingUtil.eval(sqlQuery, TamperingType.SPACE_TO_SHARP_COMMENT.instance().getJavascript());
118
        }
119
120
        sqlQuery = this.transform(sqlQuery, this.isBase64, TamperingType.BASE64);
121
        sqlQuery = this.transform(sqlQuery, this.isCharToEncoding, TamperingType.CHAR_TO_ENCODING);
122
        sqlQuery = this.transform(sqlQuery, this.isQuoteToUtf8, TamperingType.QUOTE_TO_UTF8);  // char insertion included
123 1 1. tamper : replaced return value with "" for com/jsql/util/TamperingUtil::tamper → KILLED
        return sqlQuery;
124
    }
125
126
    private String transform(String sqlQuery, boolean shouldApply, TamperingType tamperingType) {
127 1 1. transform : negated conditional → KILLED
        if (shouldApply) {
128 1 1. transform : replaced return value with "" for com/jsql/util/TamperingUtil::transform → KILLED
            return TamperingUtil.eval(sqlQuery, tamperingType.instance().getJavascript());
129
        }
130 1 1. transform : replaced return value with "" for com/jsql/util/TamperingUtil::transform → KILLED
        return sqlQuery;
131
    }
132
133
134
    // Builder
135
136
    public TamperingUtil withBase64() {
137
        this.isBase64 = true;
138 1 1. withBase64 : replaced return value with null for com/jsql/util/TamperingUtil::withBase64 → SURVIVED
        return this;
139
    }
140
141
    public TamperingUtil withVersionComment() {
142
        this.isVersionComment = true;
143 1 1. withVersionComment : replaced return value with null for com/jsql/util/TamperingUtil::withVersionComment → KILLED
        return this;
144
    }
145
146
    public TamperingUtil withFunctionComment() {
147
        this.isFunctionComment = true;
148 1 1. withFunctionComment : replaced return value with null for com/jsql/util/TamperingUtil::withFunctionComment → KILLED
        return this;
149
    }
150
151
    public TamperingUtil withEqualToLike() {
152
        this.isEqualToLike = true;
153 1 1. withEqualToLike : replaced return value with null for com/jsql/util/TamperingUtil::withEqualToLike → SURVIVED
        return this;
154
    }
155
156
    public TamperingUtil withRandomCase() {
157
        this.isRandomCase = true;
158 1 1. withRandomCase : replaced return value with null for com/jsql/util/TamperingUtil::withRandomCase → SURVIVED
        return this;
159
    }
160
161
    public TamperingUtil withHexToChar() {
162
        this.isHexToChar = true;
163 1 1. withHexToChar : replaced return value with null for com/jsql/util/TamperingUtil::withHexToChar → SURVIVED
        return this;
164
    }
165
166
    public TamperingUtil withStringToChar() {
167
        this.isStringToChar = true;
168 1 1. withStringToChar : replaced return value with null for com/jsql/util/TamperingUtil::withStringToChar → SURVIVED
        return this;
169
    }
170
171
    public TamperingUtil withQuoteToUtf8() {
172
        this.isQuoteToUtf8 = true;
173 1 1. withQuoteToUtf8 : replaced return value with null for com/jsql/util/TamperingUtil::withQuoteToUtf8 → SURVIVED
        return this;
174
    }
175
176
    public TamperingUtil withCharToEncoding() {
177
        this.isCharToEncoding = true;
178 1 1. withCharToEncoding : replaced return value with null for com/jsql/util/TamperingUtil::withCharToEncoding → SURVIVED
        return this;
179
    }
180
181
    public TamperingUtil withEval() {
182
        this.isEval = true;
183 1 1. withEval : replaced return value with null for com/jsql/util/TamperingUtil::withEval → SURVIVED
        return this;
184
    }
185
186
    public TamperingUtil withSpaceToMultilineComment() {
187
        this.isSpaceToMultilineComment = true;
188 1 1. withSpaceToMultilineComment : replaced return value with null for com/jsql/util/TamperingUtil::withSpaceToMultilineComment → SURVIVED
        return this;
189
    }
190
191
    public TamperingUtil withSpaceToDashComment() {
192
        this.isSpaceToDashComment = true;
193 1 1. withSpaceToDashComment : replaced return value with null for com/jsql/util/TamperingUtil::withSpaceToDashComment → SURVIVED
        return this;
194
    }
195
196
    public TamperingUtil withSpaceToSharpComment() {
197
        this.isSpaceToSharpComment = true;
198 1 1. withSpaceToSharpComment : replaced return value with null for com/jsql/util/TamperingUtil::withSpaceToSharpComment → SURVIVED
        return this;
199
    }
200
201
    
202
    // Getter and setter
203
204
    public String getCustomTamper() {
205 1 1. getCustomTamper : replaced return value with "" for com/jsql/util/TamperingUtil::getCustomTamper → NO_COVERAGE
        return this.customTamper;
206
    }
207
208
    public void setCustomTamper(String customTamper) {
209
        this.customTamper = customTamper;
210
    }
211
212
    public TamperingUtil withBase64(boolean selected) {
213
        this.isBase64 = selected;
214 1 1. withBase64 : replaced return value with null for com/jsql/util/TamperingUtil::withBase64 → NO_COVERAGE
        return this;
215
    }
216
217
    public TamperingUtil withEqualToLike(boolean selected) {
218
        this.isEqualToLike = selected;
219 1 1. withEqualToLike : replaced return value with null for com/jsql/util/TamperingUtil::withEqualToLike → NO_COVERAGE
        return this;
220
    }
221
222
    public TamperingUtil withEval(boolean selected) {
223
        this.isEval = selected;
224 1 1. withEval : replaced return value with null for com/jsql/util/TamperingUtil::withEval → NO_COVERAGE
        return this;
225
    }
226
227
    public TamperingUtil withFunctionComment(boolean selected) {
228
        this.isFunctionComment = selected;
229 1 1. withFunctionComment : replaced return value with null for com/jsql/util/TamperingUtil::withFunctionComment → NO_COVERAGE
        return this;
230
    }
231
232
    public TamperingUtil withHexToChar(boolean selected) {
233
        this.isHexToChar = selected;
234 1 1. withHexToChar : replaced return value with null for com/jsql/util/TamperingUtil::withHexToChar → NO_COVERAGE
        return this;
235
    }
236
237
    public TamperingUtil withQuoteToUtf8(boolean selected) {
238
        this.isQuoteToUtf8 = selected;
239 1 1. withQuoteToUtf8 : replaced return value with null for com/jsql/util/TamperingUtil::withQuoteToUtf8 → NO_COVERAGE
        return this;
240
    }
241
242
    public TamperingUtil withCharToEncoding(boolean selected) {
243
        this.isCharToEncoding = selected;
244 1 1. withCharToEncoding : replaced return value with null for com/jsql/util/TamperingUtil::withCharToEncoding → NO_COVERAGE
        return this;
245
    }
246
247
    public TamperingUtil withRandomCase(boolean selected) {
248
        this.isRandomCase = selected;
249 1 1. withRandomCase : replaced return value with null for com/jsql/util/TamperingUtil::withRandomCase → NO_COVERAGE
        return this;
250
    }
251
252
    public TamperingUtil withSpaceToDashComment(boolean selected) {
253
        this.isSpaceToDashComment = selected;
254 1 1. withSpaceToDashComment : replaced return value with null for com/jsql/util/TamperingUtil::withSpaceToDashComment → NO_COVERAGE
        return this;
255
    }
256
257
    public TamperingUtil withSpaceToMultilineComment(boolean selected) {
258
        this.isSpaceToMultilineComment = selected;
259 1 1. withSpaceToMultilineComment : replaced return value with null for com/jsql/util/TamperingUtil::withSpaceToMultilineComment → NO_COVERAGE
        return this;
260
    }
261
262
    public TamperingUtil withSpaceToSharpComment(boolean selected) {
263
        this.isSpaceToSharpComment = selected;
264 1 1. withSpaceToSharpComment : replaced return value with null for com/jsql/util/TamperingUtil::withSpaceToSharpComment → NO_COVERAGE
        return this;
265
    }
266
267
    public TamperingUtil withStringToChar(boolean selected) {
268
        this.isStringToChar = selected;
269 1 1. withStringToChar : replaced return value with null for com/jsql/util/TamperingUtil::withStringToChar → NO_COVERAGE
        return this;
270
    }
271
272
    public TamperingUtil withVersionComment(boolean selected) {
273
        this.isVersionComment = selected;
274 1 1. withVersionComment : replaced return value with null for com/jsql/util/TamperingUtil::withVersionComment → NO_COVERAGE
        return this;
275
    }
276
}

Mutations

42

1.1
Location : eval
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_13]
negated conditional → KILLED

68

1.1
Location : eval
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_13]
replaced return value with "" for com/jsql/util/TamperingUtil::eval → KILLED

80

1.1
Location : tamper
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_14]
negated conditional → KILLED

85

1.1
Location : tamper
Killed by : none
replaced return value with "" for com/jsql/util/TamperingUtil::tamper → NO_COVERAGE

88

1.1
Location : tamper
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_15]
negated conditional → KILLED

105

1.1
Location : tamper
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_14]
negated conditional → KILLED

112

1.1
Location : tamper
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_13]
negated conditional → KILLED

114

1.1
Location : tamper
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_13]
negated conditional → KILLED

116

1.1
Location : tamper
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_13]
negated conditional → KILLED

123

1.1
Location : tamper
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_14]
replaced return value with "" for com/jsql/util/TamperingUtil::tamper → KILLED

127

1.1
Location : transform
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_14]
negated conditional → KILLED

128

1.1
Location : transform
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_7]
replaced return value with "" for com/jsql/util/TamperingUtil::transform → KILLED

130

1.1
Location : transform
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_14]
replaced return value with "" for com/jsql/util/TamperingUtil::transform → KILLED

138

1.1
Location : withBase64
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withBase64 → SURVIVED
Covering tests

143

1.1
Location : withVersionComment
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_9]
replaced return value with null for com/jsql/util/TamperingUtil::withVersionComment → KILLED

148

1.1
Location : withFunctionComment
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_10]
replaced return value with null for com/jsql/util/TamperingUtil::withFunctionComment → KILLED

153

1.1
Location : withEqualToLike
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withEqualToLike → SURVIVED
Covering tests

158

1.1
Location : withRandomCase
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withRandomCase → SURVIVED
Covering tests

163

1.1
Location : withHexToChar
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withHexToChar → SURVIVED
Covering tests

168

1.1
Location : withStringToChar
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withStringToChar → SURVIVED
Covering tests

173

1.1
Location : withQuoteToUtf8
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withQuoteToUtf8 → SURVIVED
Covering tests

178

1.1
Location : withCharToEncoding
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withCharToEncoding → SURVIVED
Covering tests

183

1.1
Location : withEval
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withEval → SURVIVED
Covering tests

188

1.1
Location : withSpaceToMultilineComment
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withSpaceToMultilineComment → SURVIVED
Covering tests

193

1.1
Location : withSpaceToDashComment
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withSpaceToDashComment → SURVIVED
Covering tests

198

1.1
Location : withSpaceToSharpComment
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withSpaceToSharpComment → SURVIVED
Covering tests

205

1.1
Location : getCustomTamper
Killed by : none
replaced return value with "" for com/jsql/util/TamperingUtil::getCustomTamper → NO_COVERAGE

214

1.1
Location : withBase64
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withBase64 → NO_COVERAGE

219

1.1
Location : withEqualToLike
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withEqualToLike → NO_COVERAGE

224

1.1
Location : withEval
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withEval → NO_COVERAGE

229

1.1
Location : withFunctionComment
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withFunctionComment → NO_COVERAGE

234

1.1
Location : withHexToChar
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withHexToChar → NO_COVERAGE

239

1.1
Location : withQuoteToUtf8
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withQuoteToUtf8 → NO_COVERAGE

244

1.1
Location : withCharToEncoding
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withCharToEncoding → NO_COVERAGE

249

1.1
Location : withRandomCase
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withRandomCase → NO_COVERAGE

254

1.1
Location : withSpaceToDashComment
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withSpaceToDashComment → NO_COVERAGE

259

1.1
Location : withSpaceToMultilineComment
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withSpaceToMultilineComment → NO_COVERAGE

264

1.1
Location : withSpaceToSharpComment
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withSpaceToSharpComment → NO_COVERAGE

269

1.1
Location : withStringToChar
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withStringToChar → NO_COVERAGE

274

1.1
Location : withVersionComment
Killed by : none
replaced return value with null for com/jsql/util/TamperingUtil::withVersionComment → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.22.0