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

Mutations

44

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

70

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

82

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

87

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

90

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

107

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_11]
negated conditional → KILLED

116

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

118

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

124

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

128

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

129

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

131

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

139

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

144

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

149

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

154

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

159

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

164

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

169

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

174

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

179

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

184

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

189

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

194

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

201

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

210

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

215

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

220

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

225

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

230

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

235

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

240

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

245

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

250

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

255

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

260

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

265

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