зеркало из https://github.com/github/codeql.git
Merge pull request #3329 from artem-smotrakov/mvel-injection
Java: Add a query for MVEL injections
This commit is contained in:
Коммит
8513c6981c
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
MVEL is an expression language based on Java-syntax.
|
||||
The language offers many features
|
||||
including invocation of methods available in the JVM.
|
||||
If a MVEL expression is built using attacker-controlled data,
|
||||
and then evaluated, then it may allow the attacker to run arbitrary code.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Including user input in a MVEL expression should be avoided.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
The following example uses untrusted data to build a MVEL expression
|
||||
and then runs it in the default powerfull context.
|
||||
</p>
|
||||
<sample src="UnsafeMvelExpressionEvaluation.java" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
MVEL Documentation:
|
||||
<a href="http://mvel.documentnode.com/">Language Guide for 2.0</a>.
|
||||
</li>
|
||||
<li>
|
||||
OWASP:
|
||||
<a href="https://owasp.org/www-community/vulnerabilities/Expression_Language_Injection">Expression Language Injection</a>.
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* @name Expression language injection (MVEL)
|
||||
* @description Evaluation of a user-controlled MVEL expression
|
||||
* may lead to remote code execution.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/mvel-expression-injection
|
||||
* @tags security
|
||||
* external/cwe/cwe-094
|
||||
*/
|
||||
|
||||
import java
|
||||
import MvelInjectionLib
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, MvelInjectionConfig conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "MVEL injection from $@.", source.getNode(), "this user input"
|
|
@ -0,0 +1,367 @@
|
|||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for unsafe user input
|
||||
* that is used to construct and evaluate a MVEL expression.
|
||||
*/
|
||||
class MvelInjectionConfig extends TaintTracking::Configuration {
|
||||
MvelInjectionConfig() { this = "MvelInjectionConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof MvelEvaluationSink }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
expressionCompilationStep(node1, node2) or
|
||||
createExpressionCompilerStep(node1, node2) or
|
||||
expressionCompilerCompileStep(node1, node2) or
|
||||
createCompiledAccExpressionStep(node1, node2) or
|
||||
scriptCompileStep(node1, node2) or
|
||||
createMvelCompiledScriptStep(node1, node2) or
|
||||
templateCompileStep(node1, node2) or
|
||||
createTemplateCompilerStep(node1, node2)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A sink for EL injection vulnerabilities via MVEL,
|
||||
* i.e. methods that run evaluation of a MVEL expression.
|
||||
*/
|
||||
class MvelEvaluationSink extends DataFlow::ExprNode {
|
||||
MvelEvaluationSink() {
|
||||
exists(StaticMethodAccess ma, Method m | m = ma.getMethod() |
|
||||
(
|
||||
m instanceof MvelEvalMethod or
|
||||
m instanceof TemplateRuntimeEvaluationMethod
|
||||
) and
|
||||
ma.getArgument(0) = asExpr()
|
||||
)
|
||||
or
|
||||
exists(MethodAccess ma, Method m | m = ma.getMethod() |
|
||||
m instanceof MvelScriptEngineEvaluationMethod and
|
||||
ma.getArgument(0) = asExpr()
|
||||
)
|
||||
or
|
||||
exists(MethodAccess ma, Method m | m = ma.getMethod() |
|
||||
(
|
||||
m instanceof ExecutableStatementEvaluationMethod or
|
||||
m instanceof CompiledExpressionEvaluationMethod or
|
||||
m instanceof CompiledAccExpressionEvaluationMethod or
|
||||
m instanceof AccessorEvaluationMethod or
|
||||
m instanceof CompiledScriptEvaluationMethod or
|
||||
m instanceof MvelCompiledScriptEvaluationMethod
|
||||
) and
|
||||
ma.getQualifier() = asExpr()
|
||||
)
|
||||
or
|
||||
exists(StaticMethodAccess ma, Method m | m = ma.getMethod() |
|
||||
m instanceof MvelRuntimeEvaluationMethod and
|
||||
ma.getArgument(1) = asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node1` to `node2` is a dataflow step that compiles a MVEL expression
|
||||
* by callilng `MVEL.compileExpression(tainted)`.
|
||||
*/
|
||||
predicate expressionCompilationStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(StaticMethodAccess ma, Method m | ma.getMethod() = m |
|
||||
m.getDeclaringType() instanceof MVEL and
|
||||
m.hasName("compileExpression") and
|
||||
ma.getAnArgument() = node1.asExpr() and
|
||||
node2.asExpr() = ma
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node1` to `node2` is a dataflow step creates `ExpressionCompiler`,
|
||||
* i.e. `new ExpressionCompiler(tainted)`.
|
||||
*/
|
||||
predicate createExpressionCompilerStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(ConstructorCall cc |
|
||||
cc.getConstructedType() instanceof ExpressionCompiler and
|
||||
cc = node2.asExpr() and
|
||||
cc.getArgument(0) = node1.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() and
|
||||
cc.getArgument(0) = node1.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node1` to `node2` is a dataflow step that compiles a MVEL expression
|
||||
* by calling `ExpressionCompiler.compile()`.
|
||||
*/
|
||||
predicate expressionCompilerCompileStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
||||
m.getDeclaringType() instanceof ExpressionCompiler and
|
||||
m.hasName("compile") and
|
||||
ma = node2.asExpr() and
|
||||
ma.getQualifier() = node1.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node1` to `node2` is a dataflow step that compiles a script via `MvelScriptEngine`,
|
||||
* i.e. `engine.compile(tainted)` or `engine.compiledScript(tainted)`.
|
||||
*/
|
||||
predicate scriptCompileStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
||||
m instanceof MvelScriptEngineCompilationMethod and
|
||||
ma = node2.asExpr() and
|
||||
ma.getArgument(0) = node1.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node1` to `node2` is a dataflow step creates `MvelCompiledScript`,
|
||||
* i.e. `new MvelCompiledScript(engine, tainted)`.
|
||||
*/
|
||||
predicate createMvelCompiledScriptStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(ConstructorCall cc |
|
||||
cc.getConstructedType() instanceof MvelCompiledScript and
|
||||
cc = node2.asExpr() and
|
||||
cc.getArgument(1) = node1.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node1` to `node2` is a dataflow step creates `TemplateCompiler`,
|
||||
* i.e. `new TemplateCompiler(tainted)`.
|
||||
*/
|
||||
predicate createTemplateCompilerStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(ConstructorCall cc |
|
||||
cc.getConstructedType() instanceof TemplateCompiler and
|
||||
cc = node2.asExpr() and
|
||||
cc.getArgument(0) = node1.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node1` to `node2` is a dataflow step that compiles a script via `TemplateCompiler`,
|
||||
* i.e. `compiler.compile()` or `TemplateCompiler.compileTemplate(tainted)`.
|
||||
*/
|
||||
predicate templateCompileStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
||||
m instanceof TemplateCompilerCompileMethod and
|
||||
ma.getQualifier() = node1.asExpr() and
|
||||
ma = node2.asExpr()
|
||||
)
|
||||
or
|
||||
exists(StaticMethodAccess ma, Method m | ma.getMethod() = m |
|
||||
m instanceof TemplateCompilerCompileTemplateMethod and
|
||||
ma = node2.asExpr() and
|
||||
ma.getArgument(0) = node1.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods in the MVEL class that evaluate a MVEL expression.
|
||||
*/
|
||||
class MvelEvalMethod extends Method {
|
||||
MvelEvalMethod() {
|
||||
getDeclaringType() instanceof MVEL and
|
||||
(
|
||||
hasName("eval") or
|
||||
hasName("executeExpression") or
|
||||
hasName("evalToBoolean") or
|
||||
hasName("evalToString") or
|
||||
hasName("executeAllExpression") or
|
||||
hasName("executeSetExpression")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods in `MVEL` class that compile a MVEL expression.
|
||||
*/
|
||||
class MvelCompileExpressionMethod extends Method {
|
||||
MvelCompileExpressionMethod() {
|
||||
getDeclaringType() instanceof MVEL and
|
||||
(
|
||||
hasName("compileExpression") or
|
||||
hasName("compileGetExpression") or
|
||||
hasName("compileSetExpression")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods in `ExecutableStatement` that evaluate a MVEL expression.
|
||||
*/
|
||||
class ExecutableStatementEvaluationMethod extends Method {
|
||||
ExecutableStatementEvaluationMethod() {
|
||||
getDeclaringType() instanceof ExecutableStatement and
|
||||
hasName("getValue")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods in `CompiledExpression` that evaluate a MVEL expression.
|
||||
*/
|
||||
class CompiledExpressionEvaluationMethod extends Method {
|
||||
CompiledExpressionEvaluationMethod() {
|
||||
getDeclaringType() instanceof CompiledExpression and
|
||||
hasName("getDirectValue")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods in `CompiledAccExpression` that evaluate a MVEL expression.
|
||||
*/
|
||||
class CompiledAccExpressionEvaluationMethod extends Method {
|
||||
CompiledAccExpressionEvaluationMethod() {
|
||||
getDeclaringType() instanceof CompiledAccExpression and
|
||||
hasName("getValue")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods in `Accessor` that evaluate a MVEL expression.
|
||||
*/
|
||||
class AccessorEvaluationMethod extends Method {
|
||||
AccessorEvaluationMethod() {
|
||||
getDeclaringType() instanceof Accessor and
|
||||
hasName("getValue")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods in `MvelScriptEngine` that evaluate a MVEL expression.
|
||||
*/
|
||||
class MvelScriptEngineEvaluationMethod extends Method {
|
||||
MvelScriptEngineEvaluationMethod() {
|
||||
getDeclaringType() instanceof MvelScriptEngine and
|
||||
(hasName("eval") or hasName("evaluate"))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods in `MvelScriptEngine` that compile a MVEL expression.
|
||||
*/
|
||||
class MvelScriptEngineCompilationMethod extends Method {
|
||||
MvelScriptEngineCompilationMethod() {
|
||||
getDeclaringType() instanceof MvelScriptEngine and
|
||||
(hasName("compile") or hasName("compiledScript"))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods in `CompiledScript` that evaluate a MVEL expression.
|
||||
*/
|
||||
class CompiledScriptEvaluationMethod extends Method {
|
||||
CompiledScriptEvaluationMethod() {
|
||||
getDeclaringType() instanceof CompiledScript and
|
||||
hasName("eval")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods in `TemplateRuntime` that evaluate a MVEL template.
|
||||
*/
|
||||
class TemplateRuntimeEvaluationMethod extends Method {
|
||||
TemplateRuntimeEvaluationMethod() {
|
||||
getDeclaringType() instanceof TemplateRuntime and
|
||||
(hasName("eval") or hasName("execute"))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `TemplateCompiler.compile()` method compiles a MVEL template.
|
||||
*/
|
||||
class TemplateCompilerCompileMethod extends Method {
|
||||
TemplateCompilerCompileMethod() {
|
||||
getDeclaringType() instanceof TemplateCompiler and
|
||||
hasName("compile")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `TemplateCompiler.compileTemplate(tainted)` static method compiles a MVEL template.
|
||||
*/
|
||||
class TemplateCompilerCompileTemplateMethod extends Method {
|
||||
TemplateCompilerCompileTemplateMethod() {
|
||||
getDeclaringType() instanceof TemplateCompiler and
|
||||
hasName("compileTemplate")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods in `MvelCompiledScript` that evaluate a MVEL expression.
|
||||
*/
|
||||
class MvelCompiledScriptEvaluationMethod extends Method {
|
||||
MvelCompiledScriptEvaluationMethod() {
|
||||
getDeclaringType() instanceof MvelCompiledScript and
|
||||
hasName("eval")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods in `MVELRuntime` that evaluate a MVEL expression.
|
||||
*/
|
||||
class MvelRuntimeEvaluationMethod extends Method {
|
||||
MvelRuntimeEvaluationMethod() {
|
||||
getDeclaringType() instanceof MVELRuntime and
|
||||
hasName("execute")
|
||||
}
|
||||
}
|
||||
|
||||
class MVEL extends RefType {
|
||||
MVEL() { hasQualifiedName("org.mvel2", "MVEL") }
|
||||
}
|
||||
|
||||
class ExpressionCompiler extends RefType {
|
||||
ExpressionCompiler() { hasQualifiedName("org.mvel2.compiler", "ExpressionCompiler") }
|
||||
}
|
||||
|
||||
class ExecutableStatement extends RefType {
|
||||
ExecutableStatement() { hasQualifiedName("org.mvel2.compiler", "ExecutableStatement") }
|
||||
}
|
||||
|
||||
class CompiledExpression extends RefType {
|
||||
CompiledExpression() { hasQualifiedName("org.mvel2.compiler", "CompiledExpression") }
|
||||
}
|
||||
|
||||
class CompiledAccExpression extends RefType {
|
||||
CompiledAccExpression() { hasQualifiedName("org.mvel2.compiler", "CompiledAccExpression") }
|
||||
}
|
||||
|
||||
class Accessor extends RefType {
|
||||
Accessor() { hasQualifiedName("org.mvel2.compiler", "Accessor") }
|
||||
}
|
||||
|
||||
class CompiledScript extends RefType {
|
||||
CompiledScript() { hasQualifiedName("javax.script", "CompiledScript") }
|
||||
}
|
||||
|
||||
class MvelScriptEngine extends RefType {
|
||||
MvelScriptEngine() { hasQualifiedName("org.mvel2.jsr223", "MvelScriptEngine") }
|
||||
}
|
||||
|
||||
class MvelCompiledScript extends RefType {
|
||||
MvelCompiledScript() { hasQualifiedName("org.mvel2.jsr223", "MvelCompiledScript") }
|
||||
}
|
||||
|
||||
class TemplateRuntime extends RefType {
|
||||
TemplateRuntime() { hasQualifiedName("org.mvel2.templates", "TemplateRuntime") }
|
||||
}
|
||||
|
||||
class TemplateCompiler extends RefType {
|
||||
TemplateCompiler() { hasQualifiedName("org.mvel2.templates", "TemplateCompiler") }
|
||||
}
|
||||
|
||||
class MVELRuntime extends RefType {
|
||||
MVELRuntime() { hasQualifiedName("org.mvel2", "MVELRuntime") }
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
public void evaluate(Socket socket) throws IOException {
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(socket.getInputStream()))) {
|
||||
|
||||
String expression = reader.readLine();
|
||||
MVEL.eval(expression);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
edges
|
||||
| MvelInjection.java:29:54:29:65 | read(...) : String | MvelInjection.java:30:28:30:37 | expression |
|
||||
| MvelInjection.java:34:58:34:69 | read(...) : String | MvelInjection.java:36:5:36:13 | statement |
|
||||
| MvelInjection.java:34:58:34:69 | read(...) : String | MvelInjection.java:37:5:37:13 | statement |
|
||||
| MvelInjection.java:41:58:41:69 | read(...) : String | MvelInjection.java:43:5:43:14 | expression |
|
||||
| MvelInjection.java:48:7:48:18 | read(...) : String | MvelInjection.java:49:5:49:14 | expression |
|
||||
| MvelInjection.java:53:20:53:31 | read(...) : String | MvelInjection.java:57:5:57:18 | compiledScript |
|
||||
| MvelInjection.java:53:20:53:31 | read(...) : String | MvelInjection.java:60:21:60:26 | script |
|
||||
| MvelInjection.java:65:58:65:69 | read(...) : String | MvelInjection.java:68:5:68:10 | script |
|
||||
| MvelInjection.java:77:40:77:51 | read(...) : String | MvelInjection.java:77:7:77:52 | compileTemplate(...) |
|
||||
| MvelInjection.java:81:54:81:65 | read(...) : String | MvelInjection.java:82:29:82:46 | compile(...) |
|
||||
| MvelInjection.java:86:58:86:69 | read(...) : String | MvelInjection.java:88:32:88:41 | expression |
|
||||
| MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:95:14:95:36 | new String(...) : String |
|
||||
| MvelInjection.java:95:14:95:36 | new String(...) : String | MvelInjection.java:25:15:25:26 | read(...) |
|
||||
| MvelInjection.java:95:14:95:36 | new String(...) : String | MvelInjection.java:29:54:29:65 | read(...) : String |
|
||||
| MvelInjection.java:95:14:95:36 | new String(...) : String | MvelInjection.java:34:58:34:69 | read(...) : String |
|
||||
| MvelInjection.java:95:14:95:36 | new String(...) : String | MvelInjection.java:41:58:41:69 | read(...) : String |
|
||||
| MvelInjection.java:95:14:95:36 | new String(...) : String | MvelInjection.java:48:7:48:18 | read(...) : String |
|
||||
| MvelInjection.java:95:14:95:36 | new String(...) : String | MvelInjection.java:53:20:53:31 | read(...) : String |
|
||||
| MvelInjection.java:95:14:95:36 | new String(...) : String | MvelInjection.java:65:58:65:69 | read(...) : String |
|
||||
| MvelInjection.java:95:14:95:36 | new String(...) : String | MvelInjection.java:72:26:72:37 | read(...) |
|
||||
| MvelInjection.java:95:14:95:36 | new String(...) : String | MvelInjection.java:77:40:77:51 | read(...) : String |
|
||||
| MvelInjection.java:95:14:95:36 | new String(...) : String | MvelInjection.java:81:54:81:65 | read(...) : String |
|
||||
| MvelInjection.java:95:14:95:36 | new String(...) : String | MvelInjection.java:86:58:86:69 | read(...) : String |
|
||||
nodes
|
||||
| MvelInjection.java:25:15:25:26 | read(...) | semmle.label | read(...) |
|
||||
| MvelInjection.java:29:54:29:65 | read(...) : String | semmle.label | read(...) : String |
|
||||
| MvelInjection.java:30:28:30:37 | expression | semmle.label | expression |
|
||||
| MvelInjection.java:34:58:34:69 | read(...) : String | semmle.label | read(...) : String |
|
||||
| MvelInjection.java:36:5:36:13 | statement | semmle.label | statement |
|
||||
| MvelInjection.java:37:5:37:13 | statement | semmle.label | statement |
|
||||
| MvelInjection.java:41:58:41:69 | read(...) : String | semmle.label | read(...) : String |
|
||||
| MvelInjection.java:43:5:43:14 | expression | semmle.label | expression |
|
||||
| MvelInjection.java:48:7:48:18 | read(...) : String | semmle.label | read(...) : String |
|
||||
| MvelInjection.java:49:5:49:14 | expression | semmle.label | expression |
|
||||
| MvelInjection.java:53:20:53:31 | read(...) : String | semmle.label | read(...) : String |
|
||||
| MvelInjection.java:57:5:57:18 | compiledScript | semmle.label | compiledScript |
|
||||
| MvelInjection.java:60:21:60:26 | script | semmle.label | script |
|
||||
| MvelInjection.java:65:58:65:69 | read(...) : String | semmle.label | read(...) : String |
|
||||
| MvelInjection.java:68:5:68:10 | script | semmle.label | script |
|
||||
| MvelInjection.java:72:26:72:37 | read(...) | semmle.label | read(...) |
|
||||
| MvelInjection.java:77:7:77:52 | compileTemplate(...) | semmle.label | compileTemplate(...) |
|
||||
| MvelInjection.java:77:40:77:51 | read(...) : String | semmle.label | read(...) : String |
|
||||
| MvelInjection.java:81:54:81:65 | read(...) : String | semmle.label | read(...) : String |
|
||||
| MvelInjection.java:82:29:82:46 | compile(...) | semmle.label | compile(...) |
|
||||
| MvelInjection.java:86:58:86:69 | read(...) : String | semmle.label | read(...) : String |
|
||||
| MvelInjection.java:88:32:88:41 | expression | semmle.label | expression |
|
||||
| MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
|
||||
| MvelInjection.java:95:14:95:36 | new String(...) : String | semmle.label | new String(...) : String |
|
||||
#select
|
||||
| MvelInjection.java:25:15:25:26 | read(...) | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:25:15:25:26 | read(...) | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
||||
| MvelInjection.java:30:28:30:37 | expression | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:30:28:30:37 | expression | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
||||
| MvelInjection.java:36:5:36:13 | statement | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:36:5:36:13 | statement | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
||||
| MvelInjection.java:37:5:37:13 | statement | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:37:5:37:13 | statement | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
||||
| MvelInjection.java:43:5:43:14 | expression | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:43:5:43:14 | expression | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
||||
| MvelInjection.java:49:5:49:14 | expression | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:49:5:49:14 | expression | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
||||
| MvelInjection.java:57:5:57:18 | compiledScript | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:57:5:57:18 | compiledScript | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
||||
| MvelInjection.java:60:21:60:26 | script | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:60:21:60:26 | script | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
||||
| MvelInjection.java:68:5:68:10 | script | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:68:5:68:10 | script | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
||||
| MvelInjection.java:72:26:72:37 | read(...) | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:72:26:72:37 | read(...) | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
||||
| MvelInjection.java:77:7:77:52 | compileTemplate(...) | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:77:7:77:52 | compileTemplate(...) | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
||||
| MvelInjection.java:82:29:82:46 | compile(...) | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:82:29:82:46 | compile(...) | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
||||
| MvelInjection.java:88:32:88:41 | expression | MvelInjection.java:92:27:92:49 | getInputStream(...) : InputStream | MvelInjection.java:88:32:88:41 | expression | MVEL injection from $@. | MvelInjection.java:92:27:92:49 | getInputStream(...) | this user input |
|
|
@ -0,0 +1,98 @@
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.net.Socket;
|
||||
import java.util.HashMap;
|
||||
import javax.script.CompiledScript;
|
||||
import javax.script.SimpleScriptContext;
|
||||
import org.mvel2.MVEL;
|
||||
import org.mvel2.MVELRuntime;
|
||||
import org.mvel2.ParserContext;
|
||||
import org.mvel2.compiler.CompiledAccExpression;
|
||||
import org.mvel2.compiler.CompiledExpression;
|
||||
import org.mvel2.compiler.ExecutableStatement;
|
||||
import org.mvel2.compiler.ExpressionCompiler;
|
||||
import org.mvel2.integration.impl.ImmutableDefaultFactory;
|
||||
import org.mvel2.jsr223.MvelCompiledScript;
|
||||
import org.mvel2.jsr223.MvelScriptEngine;
|
||||
import org.mvel2.templates.CompiledTemplate;
|
||||
import org.mvel2.templates.TemplateCompiler;
|
||||
import org.mvel2.templates.TemplateRuntime;
|
||||
|
||||
public class MvelInjection {
|
||||
|
||||
public static void testWithMvelEval(Socket socket) throws IOException {
|
||||
MVEL.eval(read(socket));
|
||||
}
|
||||
|
||||
public static void testWithMvelCompileAndExecute(Socket socket) throws IOException {
|
||||
Serializable expression = MVEL.compileExpression(read(socket));
|
||||
MVEL.executeExpression(expression);
|
||||
}
|
||||
|
||||
public static void testWithExpressionCompiler(Socket socket) throws IOException {
|
||||
ExpressionCompiler compiler = new ExpressionCompiler(read(socket));
|
||||
ExecutableStatement statement = compiler.compile();
|
||||
statement.getValue(new Object(), new ImmutableDefaultFactory());
|
||||
statement.getValue(new Object(), new Object(), new ImmutableDefaultFactory());
|
||||
}
|
||||
|
||||
public static void testWithCompiledExpressionGetDirectValue(Socket socket) throws IOException {
|
||||
ExpressionCompiler compiler = new ExpressionCompiler(read(socket));
|
||||
CompiledExpression expression = compiler.compile();
|
||||
expression.getDirectValue(new Object(), new ImmutableDefaultFactory());
|
||||
}
|
||||
|
||||
public static void testCompiledAccExpressionGetValue(Socket socket) throws IOException {
|
||||
CompiledAccExpression expression = new CompiledAccExpression(
|
||||
read(socket).toCharArray(), Object.class, new ParserContext());
|
||||
expression.getValue(new Object(), new ImmutableDefaultFactory());
|
||||
}
|
||||
|
||||
public static void testMvelScriptEngineCompileAndEvaluate(Socket socket) throws Exception {
|
||||
String input = read(socket);
|
||||
|
||||
MvelScriptEngine engine = new MvelScriptEngine();
|
||||
CompiledScript compiledScript = engine.compile(input);
|
||||
compiledScript.eval();
|
||||
|
||||
Serializable script = engine.compiledScript(input);
|
||||
engine.evaluate(script, new SimpleScriptContext());
|
||||
}
|
||||
|
||||
public static void testMvelCompiledScriptCompileAndEvaluate(Socket socket) throws Exception {
|
||||
MvelScriptEngine engine = new MvelScriptEngine();
|
||||
ExpressionCompiler compiler = new ExpressionCompiler(read(socket));
|
||||
ExecutableStatement statement = compiler.compile();
|
||||
MvelCompiledScript script = new MvelCompiledScript(engine, statement);
|
||||
script.eval(new SimpleScriptContext());
|
||||
}
|
||||
|
||||
public static void testTemplateRuntimeEval(Socket socket) throws Exception {
|
||||
TemplateRuntime.eval(read(socket), new HashMap());
|
||||
}
|
||||
|
||||
public static void testTemplateRuntimeCompileTemplateAndExecute(Socket socket) throws Exception {
|
||||
TemplateRuntime.execute(
|
||||
TemplateCompiler.compileTemplate(read(socket)), new HashMap());
|
||||
}
|
||||
|
||||
public static void testTemplateRuntimeCompileAndExecute(Socket socket) throws Exception {
|
||||
TemplateCompiler compiler = new TemplateCompiler(read(socket));
|
||||
TemplateRuntime.execute(compiler.compile(), new HashMap());
|
||||
}
|
||||
|
||||
public static void testMvelRuntimeExecute(Socket socket) throws Exception {
|
||||
ExpressionCompiler compiler = new ExpressionCompiler(read(socket));
|
||||
CompiledExpression expression = compiler.compile();
|
||||
MVELRuntime.execute(false, expression, new Object(), new ImmutableDefaultFactory());
|
||||
}
|
||||
|
||||
public static String read(Socket socket) throws IOException {
|
||||
try (InputStream is = socket.getInputStream()) {
|
||||
byte[] bytes = new byte[1024];
|
||||
int n = is.read(bytes);
|
||||
return new String(bytes, 0, n);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
experimental/Security/CWE/CWE-094/MvelInjection.ql
|
|
@ -1 +1 @@
|
|||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../../stubs/mvel2-2.4.7:${testdir}/../../../../stubs/jsr223-api
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package javax.script;
|
||||
|
||||
public class CompiledScript {
|
||||
public Object eval() throws ScriptException { return null; }
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package javax.script;
|
||||
|
||||
public interface ScriptContext {}
|
|
@ -0,0 +1,3 @@
|
|||
package javax.script;
|
||||
|
||||
public class ScriptException extends Exception {}
|
|
@ -0,0 +1,3 @@
|
|||
package javax.script;
|
||||
|
||||
public class SimpleScriptContext implements ScriptContext {}
|
|
@ -0,0 +1,9 @@
|
|||
package org.mvel2;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class MVEL {
|
||||
public static Object eval(String expression) { return null; }
|
||||
public static Serializable compileExpression(String expression) { return null; }
|
||||
public static Object executeExpression(Object compiledExpression) { return null; }
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.mvel2;
|
||||
|
||||
import org.mvel2.compiler.CompiledExpression;
|
||||
import org.mvel2.integration.VariableResolverFactory;
|
||||
|
||||
public class MVELRuntime {
|
||||
public static Object execute(boolean debugger, CompiledExpression expression, Object ctx, VariableResolverFactory variableFactory) { return null; }
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package org.mvel2;
|
||||
|
||||
public class ParserContext {}
|
|
@ -0,0 +1,7 @@
|
|||
package org.mvel2.compiler;
|
||||
|
||||
import org.mvel2.integration.VariableResolverFactory;
|
||||
|
||||
public interface Accessor {
|
||||
public Object getValue(Object ctx, Object elCtx, VariableResolverFactory factory);
|
||||
}
|
|
@ -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; }
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.mvel2.compiler;
|
||||
|
||||
import org.mvel2.integration.VariableResolverFactory;
|
||||
|
||||
public class CompiledExpression implements ExecutableStatement {
|
||||
public Object getDirectValue(Object staticContext, VariableResolverFactory factory) { return null; }
|
||||
public Object getValue(Object staticContext, VariableResolverFactory factory) { return null; }
|
||||
public Object getValue(Object ctx, Object elCtx, VariableResolverFactory factory) { return null; }
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.mvel2.compiler;
|
||||
|
||||
import java.io.Serializable;
|
||||
import org.mvel2.integration.VariableResolverFactory;
|
||||
|
||||
public interface ExecutableStatement extends Accessor, Serializable {
|
||||
public Object getValue(Object staticContext, VariableResolverFactory factory);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package org.mvel2.compiler;
|
||||
|
||||
public class ExpressionCompiler {
|
||||
public ExpressionCompiler(String expression) {}
|
||||
public CompiledExpression compile() { return null; }
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package org.mvel2.integration;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface VariableResolverFactory extends Serializable {}
|
|
@ -0,0 +1,5 @@
|
|||
package org.mvel2.integration.impl;
|
||||
|
||||
import org.mvel2.integration.VariableResolverFactory;
|
||||
|
||||
public class ImmutableDefaultFactory implements VariableResolverFactory {}
|
|
@ -0,0 +1,11 @@
|
|||
package org.mvel2.jsr223;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.script.CompiledScript;
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
public class MvelCompiledScript extends CompiledScript {
|
||||
public MvelCompiledScript(MvelScriptEngine engine, Serializable compiledScript) {}
|
||||
public Object eval(ScriptContext context) throws ScriptException { return null; }
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.mvel2.jsr223;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.script.CompiledScript;
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
public class MvelScriptEngine {
|
||||
public CompiledScript compile(String script) throws ScriptException { return null; }
|
||||
public Serializable compiledScript(String script) throws ScriptException { return null; }
|
||||
public Object evaluate(Serializable expression, ScriptContext context) throws ScriptException { return null; }
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package org.mvel2.templates;
|
||||
|
||||
public class CompiledTemplate {}
|
|
@ -0,0 +1,7 @@
|
|||
package org.mvel2.templates;
|
||||
|
||||
public class TemplateCompiler {
|
||||
public TemplateCompiler(String template) {}
|
||||
public static CompiledTemplate compileTemplate(String template) { return null; }
|
||||
public CompiledTemplate compile() { return null; }
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.mvel2.templates;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class TemplateRuntime {
|
||||
public static Object eval(String template, Map vars) { return null; }
|
||||
public static Object execute(CompiledTemplate compiled, Map vars) { return null; }
|
||||
}
|
Загрузка…
Ссылка в новой задаче