Skip to content

Commit 32ff5ad

Browse files
Java: Added CompiledExpression sink for MVEL injections
1 parent c6c4c2c commit 32ff5ad

File tree

6 files changed

+57
-14
lines changed

6 files changed

+57
-14
lines changed

java/ql/src/experimental/Security/CWE/CWE-094/MvelInjectionLib.qll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ class MvelEvaluationSink extends DataFlow::ExprNode {
3636
m instanceof ExecutableStatementEvaluationMethod and
3737
(ma = asExpr() or ma.getQualifier() = asExpr())
3838
)
39+
or
40+
exists(MethodAccess ma, Method m | m = ma.getMethod() |
41+
m instanceof CompiledExpressionEvaluationMethod and
42+
(ma = asExpr() or ma.getQualifier() = asExpr())
43+
)
3944
}
4045
}
4146

@@ -118,6 +123,16 @@ class ExecutableStatementEvaluationMethod extends Method {
118123
}
119124
}
120125

126+
/**
127+
* Methods in `CompiledExpression` that trigger evaluating a MVEL expression.
128+
*/
129+
class CompiledExpressionEvaluationMethod extends Method {
130+
CompiledExpressionEvaluationMethod() {
131+
getDeclaringType() instanceof CompiledExpression and
132+
hasName("getDirectValue")
133+
}
134+
}
135+
121136
class MVEL extends RefType {
122137
MVEL() { hasQualifiedName("org.mvel2", "MVEL") }
123138
}
@@ -129,3 +144,7 @@ class ExpressionCompiler extends RefType {
129144
class ExecutableStatement extends RefType {
130145
ExecutableStatement() { hasQualifiedName("org.mvel2.compiler", "ExecutableStatement") }
131146
}
147+
148+
class CompiledExpression extends RefType {
149+
CompiledExpression() { hasQualifiedName("org.mvel2.compiler", "CompiledExpression") }
150+
}
Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
edges
2-
| MvelInjection.java:13:27:13:49 | getInputStream(...) : InputStream | MvelInjection.java:17:17:17:21 | input |
3-
| MvelInjection.java:22:27:22:49 | getInputStream(...) : InputStream | MvelInjection.java:27:30:27:39 | expression |
4-
| MvelInjection.java:32:27:32:49 | getInputStream(...) : InputStream | MvelInjection.java:38:7:38:15 | statement |
2+
| MvelInjection.java:14:27:14:49 | getInputStream(...) : InputStream | MvelInjection.java:18:17:18:21 | input |
3+
| MvelInjection.java:23:27:23:49 | getInputStream(...) : InputStream | MvelInjection.java:28:30:28:39 | expression |
4+
| MvelInjection.java:33:27:33:49 | getInputStream(...) : InputStream | MvelInjection.java:39:7:39:15 | statement |
5+
| MvelInjection.java:44:27:44:49 | getInputStream(...) : InputStream | MvelInjection.java:50:7:50:16 | expression |
56
nodes
6-
| MvelInjection.java:13:27:13:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
7-
| MvelInjection.java:17:17:17:21 | input | semmle.label | input |
8-
| MvelInjection.java:22:27:22:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
9-
| MvelInjection.java:27:30:27:39 | expression | semmle.label | expression |
10-
| MvelInjection.java:32:27:32:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
11-
| MvelInjection.java:38:7:38:15 | statement | semmle.label | statement |
7+
| MvelInjection.java:14:27:14:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
8+
| MvelInjection.java:18:17:18:21 | input | semmle.label | input |
9+
| MvelInjection.java:23:27:23:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
10+
| MvelInjection.java:28:30:28:39 | expression | semmle.label | expression |
11+
| MvelInjection.java:33:27:33:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
12+
| MvelInjection.java:39:7:39:15 | statement | semmle.label | statement |
13+
| MvelInjection.java:44:27:44:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
14+
| MvelInjection.java:50:7:50:16 | expression | semmle.label | expression |
1215
#select
13-
| MvelInjection.java:17:17:17:21 | input | MvelInjection.java:13:27:13:49 | getInputStream(...) : InputStream | MvelInjection.java:17:17:17:21 | input | MVEL injection from $@. | MvelInjection.java:13:27:13:49 | getInputStream(...) | this user input |
14-
| MvelInjection.java:27:30:27:39 | expression | MvelInjection.java:22:27:22:49 | getInputStream(...) : InputStream | MvelInjection.java:27:30:27:39 | expression | MVEL injection from $@. | MvelInjection.java:22:27:22:49 | getInputStream(...) | this user input |
15-
| MvelInjection.java:38:7:38:15 | statement | MvelInjection.java:32:27:32:49 | getInputStream(...) : InputStream | MvelInjection.java:38:7:38:15 | statement | MVEL injection from $@. | MvelInjection.java:32:27:32:49 | getInputStream(...) | this user input |
16+
| MvelInjection.java:18:17:18:21 | input | MvelInjection.java:14:27:14:49 | getInputStream(...) : InputStream | MvelInjection.java:18:17:18:21 | input | MVEL injection from $@. | MvelInjection.java:14:27:14:49 | getInputStream(...) | this user input |
17+
| MvelInjection.java:28:30:28:39 | expression | MvelInjection.java:23:27:23:49 | getInputStream(...) : InputStream | MvelInjection.java:28:30:28:39 | expression | MVEL injection from $@. | MvelInjection.java:23:27:23:49 | getInputStream(...) | this user input |
18+
| MvelInjection.java:39:7:39:15 | statement | MvelInjection.java:33:27:33:49 | getInputStream(...) : InputStream | MvelInjection.java:39:7:39:15 | statement | MVEL injection from $@. | MvelInjection.java:33:27:33:49 | getInputStream(...) | this user input |
19+
| MvelInjection.java:50:7:50:16 | expression | MvelInjection.java:44:27:44:49 | getInputStream(...) : InputStream | MvelInjection.java:50:7:50:16 | expression | MVEL injection from $@. | MvelInjection.java:44:27:44:49 | getInputStream(...) | this user input |

java/ql/test/experimental/Security/CWE/CWE-094/MvelInjection.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.Serializable;
44
import java.net.Socket;
55
import org.mvel2.MVEL;
6+
import org.mvel2.compiler.CompiledExpression;
67
import org.mvel2.compiler.ExecutableStatement;
78
import org.mvel2.compiler.ExpressionCompiler;
89
import org.mvel2.integration.impl.ImmutableDefaultFactory;
@@ -38,4 +39,15 @@ public static void testWithExpressionCompiler(Socket socket) throws IOException
3839
statement.getValue(new Object(), new ImmutableDefaultFactory());
3940
}
4041
}
42+
43+
public static void testWithCompiledExpressionGetDirectValue(Socket socket) throws IOException {
44+
try (InputStream in = socket.getInputStream()) {
45+
byte[] bytes = new byte[1024];
46+
int n = in.read(bytes);
47+
String input = new String(bytes, 0, n);
48+
ExpressionCompiler compiler = new ExpressionCompiler(input);
49+
CompiledExpression expression = compiler.compile();
50+
expression.getDirectValue(new Object(), new ImmutableDefaultFactory());
51+
}
52+
}
4153
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.mvel2.compiler;
2+
3+
import org.mvel2.integration.VariableResolverFactory;
4+
5+
public class CompiledExpression implements ExecutableStatement {
6+
public Object getDirectValue(Object staticContext, VariableResolverFactory factory) { return null; }
7+
public Object getValue(Object staticContext, VariableResolverFactory factory) { return null; }
8+
}

java/ql/test/stubs/mvel2-2.4.7/org/mvel2/compiler/ExecutableStatement.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
import org.mvel2.integration.VariableResolverFactory;
44

55
public interface ExecutableStatement {
6-
public Object getValue(Object staticContext, VariableResolverFactory factory);
6+
public Object getValue(Object staticContext, VariableResolverFactory factory);
77
}

java/ql/test/stubs/mvel2-2.4.7/org/mvel2/compiler/ExpressionCompiler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
public class ExpressionCompiler {
44
public ExpressionCompiler(String expression) {}
5-
public ExecutableStatement compile() { return null; }
5+
public CompiledExpression compile() { return null; }
66
}

0 commit comments

Comments
 (0)