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

Mutations

46

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

76

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

89

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

96

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

99

1.1
Location : tamper
Killed by : TamperingUtilSpock.[engine:spock]/[spec:TamperingUtilSpock]/[feature:$spock_feature_0_14]
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_12]
negated conditional → KILLED

125

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

127

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

134

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

139

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

140

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

143

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

151

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

156

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

161

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

166

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

171

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

176

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

181

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

186

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

191

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

196

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

201

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

206

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

213

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

222

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

227

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

232

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

237

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

242

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

247

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

252

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

257

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

262

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

267

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

272

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

277

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