Skip to content

Commit 39bb3b0

Browse files
committed
Add some warnings for misusing SQL injection protection (btk5h#4)
1 parent cef0c4c commit 39bb3b0

File tree

2 files changed

+54
-9
lines changed

2 files changed

+54
-9
lines changed

src/main/java/com/btk5h/skriptdb/skript/EffExecuteStatement.java

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@
3434
/**
3535
* Executes a statement on a database and optionally stores the result in a variable. Expressions
3636
* embedded in the query will be escaped to avoid SQL injection.
37-
*
37+
* <p>
3838
* If a single variable, such as `{test}`, is passed, the variable will be set to the number of
3939
* affected rows.
40-
*
40+
* <p>
4141
* If a list variable, such as `{test::*}`, is passed, the query result will be mapped to the list
4242
* variable in the form `{test::<column name>::<row number>}`
4343
*
@@ -145,16 +145,41 @@ private PreparedStatement createStatement(Event e, Connection conn) throws SQLEx
145145
StringBuilder sb = new StringBuilder();
146146
List<Object> parameters = new ArrayList<>();
147147
Object[] objects = SkriptUtil.getTemplateString(((VariableString) query));
148-
for (Object o : objects) {
148+
for (int i = 0; i < objects.length; i++) {
149+
Object o = objects[i];
149150
if (o instanceof String) {
150151
sb.append(o);
151152
} else {
152153
Expression<?> expr = SkriptUtil.getExpressionFromInfo(o);
154+
155+
String before = getString(objects, i - 1);
156+
String after = getString(objects, i + 1);
157+
boolean standaloneString = false;
158+
159+
if (before != null && after != null) {
160+
if (before.endsWith("'") && after.endsWith("'")) {
161+
standaloneString = true;
162+
}
163+
}
164+
165+
Object expressionValue = expr.getSingle(e);
166+
153167
if (expr instanceof ExprUnsafe) {
154-
sb.append(expr.getSingle(e));
168+
sb.append(expressionValue);
169+
170+
if (standaloneString && expressionValue instanceof String) {
171+
String rawExpression = ((ExprUnsafe) expr).getRawExpression();
172+
Skript.warning(
173+
String.format("Unsafe may have been used unnecessarily. Try replacing 'unsafe %1$s' with %1$s",
174+
rawExpression));
175+
}
155176
} else {
156-
parameters.add(expr.getSingle(e));
177+
parameters.add(expressionValue);
157178
sb.append('?');
179+
180+
if (standaloneString) {
181+
Skript.warning("Do not surround expressions with quotes!");
182+
}
158183
}
159184
}
160185
}
@@ -168,6 +193,20 @@ private PreparedStatement createStatement(Event e, Connection conn) throws SQLEx
168193
return stmt;
169194
}
170195

196+
private String getString(Object[] objects, int index) {
197+
if (index < 0 || index >= objects.length) {
198+
return null;
199+
}
200+
201+
Object object = objects[index];
202+
203+
if (object instanceof String) {
204+
return (String) object;
205+
}
206+
207+
return null;
208+
}
209+
171210
private void setVariable(Event e, String name, Object obj) {
172211
Variables.setVariable(name.toLowerCase(Locale.ENGLISH), obj, e, isLocal);
173212
}

src/main/java/com/btk5h/skriptdb/skript/ExprUnsafe.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,16 @@ public class ExprUnsafe extends SimpleExpression<String> {
2525
"unsafe %string%");
2626
}
2727

28-
private Expression<String> str;
28+
private Expression<String> stringExpression;
29+
private String rawExpression;
30+
31+
public String getRawExpression() {
32+
return rawExpression;
33+
}
2934

3035
@Override
3136
protected String[] get(Event e) {
32-
return str.getArray(e);
37+
return stringExpression.getArray(e);
3338
}
3439

3540
@Override
@@ -44,14 +49,15 @@ public Class<? extends String> getReturnType() {
4449

4550
@Override
4651
public String toString(Event e, boolean debug) {
47-
return "unsafe " + str.toString(e, debug);
52+
return "unsafe " + stringExpression.toString(e, debug);
4853
}
4954

5055
@SuppressWarnings("unchecked")
5156
@Override
5257
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed,
5358
SkriptParser.ParseResult parseResult) {
54-
str = (Expression<String>) exprs[0];
59+
stringExpression = (Expression<String>) exprs[0];
60+
rawExpression = parseResult.expr.substring("unsafe".length()).trim();
5561
return true;
5662
}
5763
}

0 commit comments

Comments
 (0)