Java: Added CompiledAccExpression sink for MVEL injections

This commit is contained in:
Artem Smotrakov
2020-04-24 23:17:52 +02:00
parent 32ff5ad496
commit 12e0234d40
5 changed files with 83 additions and 24 deletions

View File

@@ -17,7 +17,8 @@ class MvelInjectionConfig extends TaintTracking::Configuration {
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
expressionCompilationStep(node1, node2) or
createExpressionCompilerStep(node1, node2) or
expressionCompilerCompileStep(node1, node2)
expressionCompilerCompileStep(node1, node2) or
createCompiledAccExpressionStep(node1, node2)
}
}
@@ -33,12 +34,11 @@ class MvelEvaluationSink extends DataFlow::ExprNode {
)
or
exists(MethodAccess ma, Method m | m = ma.getMethod() |
m instanceof ExecutableStatementEvaluationMethod and
(ma = asExpr() or ma.getQualifier() = asExpr())
)
or
exists(MethodAccess ma, Method m | m = ma.getMethod() |
m instanceof CompiledExpressionEvaluationMethod and
(
m instanceof ExecutableStatementEvaluationMethod or
m instanceof CompiledExpressionEvaluationMethod or
m instanceof CompiledAccExpressionEvaluationMethod
) and
(ma = asExpr() or ma.getQualifier() = asExpr())
)
}
@@ -69,6 +69,22 @@ predicate createExpressionCompilerStep(DataFlow::Node node1, DataFlow::Node node
)
}
/**
* Holds if `node1` to `node2` is a dataflow step creates `CompiledAccExpression`,
* i.e. `new CompiledAccExpression(tainted, ...)`.
*/
predicate createCompiledAccExpressionStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(ConstructorCall cc |
cc.getConstructedType() instanceof CompiledAccExpression and
(cc = node2.asExpr() or cc.getQualifier() = node2.asExpr()) and
cc.getArgument(0) = node1.asExpr()
)
}
predicate test() {
exists(ConstructorCall cc | cc.getConstructedType() instanceof CompiledAccExpression)
}
/**
* Holds if `node1` to `node2` is a dataflow step that compiles a MVEL expression
* by calling `ExpressionCompiler.compile()`.
@@ -133,6 +149,16 @@ class CompiledExpressionEvaluationMethod extends Method {
}
}
/**
* Methods in `CompiledAccExpression` that trigger evaluating a MVEL expression.
*/
class CompiledAccExpressionEvaluationMethod extends Method {
CompiledAccExpressionEvaluationMethod() {
getDeclaringType() instanceof CompiledAccExpression and
hasName("getValue")
}
}
class MVEL extends RefType {
MVEL() { hasQualifiedName("org.mvel2", "MVEL") }
}
@@ -146,5 +172,9 @@ class ExecutableStatement extends RefType {
}
class CompiledExpression extends RefType {
CompiledExpression() { hasQualifiedName("org.mvel2.compiler", "CompiledExpression") }
CompiledExpression() { hasQualifiedName("org.mvel2.compiler", "CompiledExpression") }
}
class CompiledAccExpression extends RefType {
CompiledAccExpression() { hasQualifiedName("org.mvel2.compiler", "CompiledAccExpression") }
}

View File

@@ -1,19 +1,23 @@
edges
| MvelInjection.java:14:27:14:49 | getInputStream(...) : InputStream | MvelInjection.java:18:17:18:21 | input |
| MvelInjection.java:23:27:23:49 | getInputStream(...) : InputStream | MvelInjection.java:28:30:28:39 | expression |
| MvelInjection.java:33:27:33:49 | getInputStream(...) : InputStream | MvelInjection.java:39:7:39:15 | statement |
| MvelInjection.java:44:27:44:49 | getInputStream(...) : InputStream | MvelInjection.java:50:7:50:16 | expression |
| MvelInjection.java:16:27:16:49 | getInputStream(...) : InputStream | MvelInjection.java:20:17:20:21 | input |
| MvelInjection.java:25:27:25:49 | getInputStream(...) : InputStream | MvelInjection.java:30:30:30:39 | expression |
| MvelInjection.java:35:27:35:49 | getInputStream(...) : InputStream | MvelInjection.java:41:7:41:15 | statement |
| MvelInjection.java:46:27:46:49 | getInputStream(...) : InputStream | MvelInjection.java:52:7:52:16 | expression |
| MvelInjection.java:57:27:57:49 | getInputStream(...) : InputStream | MvelInjection.java:62:7:62:16 | expression |
nodes
| MvelInjection.java:14:27:14:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| MvelInjection.java:18:17:18:21 | input | semmle.label | input |
| MvelInjection.java:23:27:23:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| MvelInjection.java:28:30:28:39 | expression | semmle.label | expression |
| MvelInjection.java:33:27:33:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| MvelInjection.java:39:7:39:15 | statement | semmle.label | statement |
| MvelInjection.java:44:27:44:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| MvelInjection.java:50:7:50:16 | expression | semmle.label | expression |
| MvelInjection.java:16:27:16:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| MvelInjection.java:20:17:20:21 | input | semmle.label | input |
| MvelInjection.java:25:27:25:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| MvelInjection.java:30:30:30:39 | expression | semmle.label | expression |
| MvelInjection.java:35:27:35:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| MvelInjection.java:41:7:41:15 | statement | semmle.label | statement |
| MvelInjection.java:46:27:46:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| MvelInjection.java:52:7:52:16 | expression | semmle.label | expression |
| MvelInjection.java:57:27:57:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| MvelInjection.java:62:7:62:16 | expression | semmle.label | expression |
#select
| 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 |
| 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 |
| 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 |
| 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 |
| MvelInjection.java:20:17:20:21 | input | MvelInjection.java:16:27:16:49 | getInputStream(...) : InputStream | MvelInjection.java:20:17:20:21 | input | MVEL injection from $@. | MvelInjection.java:16:27:16:49 | getInputStream(...) | this user input |
| MvelInjection.java:30:30:30:39 | expression | MvelInjection.java:25:27:25:49 | getInputStream(...) : InputStream | MvelInjection.java:30:30:30:39 | expression | MVEL injection from $@. | MvelInjection.java:25:27:25:49 | getInputStream(...) | this user input |
| MvelInjection.java:41:7:41:15 | statement | MvelInjection.java:35:27:35:49 | getInputStream(...) : InputStream | MvelInjection.java:41:7:41:15 | statement | MVEL injection from $@. | MvelInjection.java:35:27:35:49 | getInputStream(...) | this user input |
| MvelInjection.java:52:7:52:16 | expression | MvelInjection.java:46:27:46:49 | getInputStream(...) : InputStream | MvelInjection.java:52:7:52:16 | expression | MVEL injection from $@. | MvelInjection.java:46:27:46:49 | getInputStream(...) | this user input |
| MvelInjection.java:62:7:62:16 | expression | MvelInjection.java:57:27:57:49 | getInputStream(...) : InputStream | MvelInjection.java:62:7:62:16 | expression | MVEL injection from $@. | MvelInjection.java:57:27:57:49 | getInputStream(...) | this user input |

View File

@@ -3,6 +3,8 @@ import java.io.InputStream;
import java.io.Serializable;
import java.net.Socket;
import org.mvel2.MVEL;
import org.mvel2.ParserContext;
import org.mvel2.compiler.CompiledAccExpression;
import org.mvel2.compiler.CompiledExpression;
import org.mvel2.compiler.ExecutableStatement;
import org.mvel2.compiler.ExpressionCompiler;
@@ -50,4 +52,14 @@ public class MvelInjection {
expression.getDirectValue(new Object(), new ImmutableDefaultFactory());
}
}
public static void testCompiledAccExpressionGetValue(Socket socket) throws IOException {
try (InputStream in = socket.getInputStream()) {
byte[] bytes = new byte[1024];
int n = in.read(bytes);
String input = new String(bytes, 0, n);
CompiledAccExpression expression = new CompiledAccExpression(input.toCharArray(), Object.class, new ParserContext());
expression.getValue(new Object(), new ImmutableDefaultFactory());
}
}
}

View File

@@ -0,0 +1,3 @@
package org.mvel2;
public class ParserContext {}

View File

@@ -0,0 +1,10 @@
package org.mvel2.compiler;
import org.mvel2.ParserContext;
import org.mvel2.integration.VariableResolverFactory;
public class CompiledAccExpression implements ExecutableStatement {
public CompiledAccExpression(char[] expression, Class ingressType, ParserContext context) {}
public Object getValue(Object staticContext, VariableResolverFactory factory) { return null; }
public Object getValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory) { return null; }
}