Better sink in SandboxedJexlFlowConfig

This commit is contained in:
Artem Smotrakov
2021-02-20 11:17:51 +01:00
parent 042c0b005e
commit 43a07bb13a
3 changed files with 51 additions and 45 deletions

View File

@@ -1,6 +1,6 @@
/**
* @name Expression language injection (Jexl)
* @description Evaluation of a user-controlled Jexl expression
* @name Expression language injection (JEXL)
* @description Evaluation of a user-controlled JEXL expression
* may lead to arbitrary code execution.
* @kind path-problem
* @problem.severity error
@@ -16,4 +16,4 @@ import DataFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, JexlInjectionConfig conf
where conf.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Jexl injection from $@.", source.getNode(), "this user input"
select sink.getNode(), source, sink, "JEXL injection from $@.", source.getNode(), "this user input"

View File

@@ -4,15 +4,16 @@ import semmle.code.java.dataflow.TaintTracking
/**
* A taint-tracking configuration for unsafe user input
* that is used to construct and evaluate a Jexl expression.
* It supports both Jexl2 and Jexl3.
* that is used to construct and evaluate a JEXL expression.
* It supports both JEXL 2 and 3.
*/
class JexlInjectionConfig extends TaintTracking::Configuration {
JexlInjectionConfig() { this = "JexlInjectionConfig" }
override predicate isSource(DataFlow::Node source) {
source instanceof TaintedSpringRequestBody or
source instanceof RemoteFlowSource
source instanceof RemoteFlowSource or
source instanceof LocalUserInput
}
override predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink }
@@ -35,9 +36,9 @@ private class TaintedSpringRequestBody extends DataFlow::Node {
/**
* A sink for Expresssion Language injection vulnerabilities via Jexl,
* i.e. method calls that run evaluation of a Jexl expression.
* i.e. method calls that run evaluation of a JEXL expression.
*
* Creating a `Callable` from a tainted Jexl expression or script is considered as a sink
* Creating a `Callable` from a tainted JEXL expression or script is considered as a sink
* although the tainted expression is not executed at this point.
* Here we assume that it will get executed at some point,
* maybe stored in an object field and then reached by a different flow.
@@ -60,7 +61,7 @@ private class JexlEvaluationSink extends DataFlow::ExprNode {
/**
* Defines method calls that propagate tainted data via one of the methods
* from Jexl library.
* from JEXL library.
*/
private class TaintPropagatingJexlMethodCall extends MethodAccess {
Expr taintFromExpr;
@@ -97,14 +98,14 @@ private class TaintPropagatingJexlMethodCall extends MethodAccess {
}
/**
* Holds if `expr` is a Jexl engine that is not configured with a sandbox.
* Holds if `expr` is a JEXL engine that is not configured with a sandbox.
*/
private predicate isUnsafeEngine(Expr expr) {
not exists(SandboxedJexlFlowConfig config | config.hasFlowTo(DataFlow::exprNode(expr)))
}
/**
* A configuration for a tracking sandboxed Jexl engines.
* A configuration for a tracking sandboxed JEXL engines.
*/
private class SandboxedJexlFlowConfig extends DataFlow2::Configuration {
SandboxedJexlFlowConfig() { this = "JexlInjection::SandboxedJexlFlowConfig" }
@@ -112,9 +113,14 @@ private class SandboxedJexlFlowConfig extends DataFlow2::Configuration {
override predicate isSource(DataFlow::Node node) { node instanceof SandboxedJexlSource }
override predicate isSink(DataFlow::Node node) {
node.asExpr().getType() instanceof JexlEngine or
node.asExpr().getType() instanceof JxltEngine or
node.asExpr().getType() instanceof UnifiedJexl
exists(MethodAccess ma, Method m | ma.getMethod() = m |
(
m instanceof CreateJexlScriptMethod or
m instanceof CreateJexlExpressionMethod or
m instanceof CreateJexlTemplateMethod
) and
ma.getQualifier() = node.asExpr()
)
}
override predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
@@ -123,7 +129,7 @@ private class SandboxedJexlFlowConfig extends DataFlow2::Configuration {
}
/**
* Defines a data flow source for Jexl engines configured with a sandbox.
* Defines a data flow source for JEXL engines configured with a sandbox.
*/
private class SandboxedJexlSource extends DataFlow::ExprNode {
SandboxedJexlSource() {
@@ -143,7 +149,7 @@ private class SandboxedJexlSource extends DataFlow::ExprNode {
}
/**
* Holds if `fromNode` to `toNode` is a dataflow step that creates one of the Jexl engines.
* Holds if `fromNode` to `toNode` is a dataflow step that creates one of the JEXL engines.
*/
private predicate createsJexlEngine(DataFlow::Node fromNode, DataFlow::Node toNode) {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
@@ -162,7 +168,7 @@ private predicate createsJexlEngine(DataFlow::Node fromNode, DataFlow::Node toNo
/**
* Holds if `fromNode` to `toNode` is a dataflow step that returns data from
* a tainted bean by calling one of its getters.
* a bean by calling one of its getters.
*/
private predicate returnsDataFromBean(DataFlow::Node fromNode, DataFlow::Node toNode) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
@@ -173,7 +179,7 @@ private predicate returnsDataFromBean(DataFlow::Node fromNode, DataFlow::Node to
}
/**
* Method in the `JexlEngine` class that get or set a property with a Jexl expression.
* A methods in the `JexlEngine` class that gets or sets a property with a JEXL expression.
*/
private class JexlEngineGetSetPropertyMethod extends Method {
JexlEngineGetSetPropertyMethod() {
@@ -183,7 +189,7 @@ private class JexlEngineGetSetPropertyMethod extends Method {
}
/**
* Defines methods that triggers direct evaluation of Jexl expressions.
* A method that triggers direct evaluation of JEXL expressions.
*/
private class DirectJexlEvaluationMethod extends Method {
DirectJexlEvaluationMethod() {
@@ -202,14 +208,14 @@ private class DirectJexlEvaluationMethod extends Method {
}
/**
* Defines methods that create a Jexl script.
* A method that creates a JEXL script.
*/
private class CreateJexlScriptMethod extends Method {
CreateJexlScriptMethod() { getDeclaringType() instanceof JexlEngine and hasName("createScript") }
}
/**
* Defines methods that creates a `Callable` for a Jexl expression or script.
* A method that creates a `Callable` for a JEXL expression or script.
*/
private class CreateJexlCallableMethod extends Method {
CreateJexlCallableMethod() {
@@ -219,7 +225,7 @@ private class CreateJexlCallableMethod extends Method {
}
/**
* Defines methods that create a Jexl template.
* A method that creates a JEXL template.
*/
private class CreateJexlTemplateMethod extends Method {
CreateJexlTemplateMethod() {
@@ -229,7 +235,7 @@ private class CreateJexlTemplateMethod extends Method {
}
/**
* Defines methods that create a Jexl expression.
* A method that creates a JEXL expression.
*/
private class CreateJexlExpressionMethod extends Method {
CreateJexlExpressionMethod() {

View File

@@ -171,25 +171,25 @@ nodes
| Jexl3Injection.java:161:13:161:52 | customRequest : CustomRequest | semmle.label | customRequest : CustomRequest |
| Jexl3Injection.java:164:27:164:30 | expr : String | semmle.label | expr : String |
#select
| Jexl2Injection.java:14:9:14:9 | e | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:14:9:14:9 | e | Jexl injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:22:9:22:9 | e | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:22:9:22:9 | e | Jexl injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:29:9:29:14 | script | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:29:9:29:14 | script | Jexl injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:38:13:38:18 | script | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:38:13:38:18 | script | Jexl injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:46:40:46:47 | jexlExpr | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:46:40:46:47 | jexlExpr | Jexl injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:51:40:51:47 | jexlExpr | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:51:40:51:47 | jexlExpr | Jexl injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:57:9:57:35 | parse(...) | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:57:9:57:35 | parse(...) | Jexl injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:63:9:63:35 | parse(...) | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:63:9:63:35 | parse(...) | Jexl injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:69:9:69:44 | createTemplate(...) | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:69:9:69:44 | createTemplate(...) | Jexl injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:19:9:19:9 | e | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:19:9:19:9 | e | Jexl injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:19:9:19:9 | e | Jexl3Injection.java:143:13:143:37 | expr : String | Jexl3Injection.java:19:9:19:9 | e | Jexl injection from $@. | Jexl3Injection.java:143:13:143:37 | expr | this user input |
| Jexl3Injection.java:19:9:19:9 | e | Jexl3Injection.java:151:13:151:34 | data : Data | Jexl3Injection.java:19:9:19:9 | e | Jexl injection from $@. | Jexl3Injection.java:151:13:151:34 | data | this user input |
| Jexl3Injection.java:19:9:19:9 | e | Jexl3Injection.java:161:13:161:52 | customRequest : CustomRequest | Jexl3Injection.java:19:9:19:9 | e | Jexl injection from $@. | Jexl3Injection.java:161:13:161:52 | customRequest | this user input |
| Jexl3Injection.java:26:9:26:9 | e | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:26:9:26:9 | e | Jexl injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:33:9:33:14 | script | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:33:9:33:14 | script | Jexl injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:42:13:42:18 | script | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:42:13:42:18 | script | Jexl injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:50:40:50:47 | jexlExpr | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:50:40:50:47 | jexlExpr | Jexl injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:55:40:55:47 | jexlExpr | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:55:40:55:47 | jexlExpr | Jexl injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:61:9:61:39 | createExpression(...) | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:61:9:61:39 | createExpression(...) | Jexl injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:67:9:67:39 | createExpression(...) | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:67:9:67:39 | createExpression(...) | Jexl injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:73:9:73:37 | createTemplate(...) | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:73:9:73:37 | createTemplate(...) | Jexl injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:82:13:82:13 | e | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:82:13:82:13 | e | Jexl injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:14:9:14:9 | e | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:14:9:14:9 | e | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:22:9:22:9 | e | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:22:9:22:9 | e | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:29:9:29:14 | script | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:29:9:29:14 | script | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:38:13:38:18 | script | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:38:13:38:18 | script | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:46:40:46:47 | jexlExpr | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:46:40:46:47 | jexlExpr | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:51:40:51:47 | jexlExpr | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:51:40:51:47 | jexlExpr | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:57:9:57:35 | parse(...) | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:57:9:57:35 | parse(...) | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:63:9:63:35 | parse(...) | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:63:9:63:35 | parse(...) | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:69:9:69:44 | createTemplate(...) | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:69:9:69:44 | createTemplate(...) | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:19:9:19:9 | e | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:19:9:19:9 | e | JEXL injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:19:9:19:9 | e | Jexl3Injection.java:143:13:143:37 | expr : String | Jexl3Injection.java:19:9:19:9 | e | JEXL injection from $@. | Jexl3Injection.java:143:13:143:37 | expr | this user input |
| Jexl3Injection.java:19:9:19:9 | e | Jexl3Injection.java:151:13:151:34 | data : Data | Jexl3Injection.java:19:9:19:9 | e | JEXL injection from $@. | Jexl3Injection.java:151:13:151:34 | data | this user input |
| Jexl3Injection.java:19:9:19:9 | e | Jexl3Injection.java:161:13:161:52 | customRequest : CustomRequest | Jexl3Injection.java:19:9:19:9 | e | JEXL injection from $@. | Jexl3Injection.java:161:13:161:52 | customRequest | this user input |
| Jexl3Injection.java:26:9:26:9 | e | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:26:9:26:9 | e | JEXL injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:33:9:33:14 | script | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:33:9:33:14 | script | JEXL injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:42:13:42:18 | script | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:42:13:42:18 | script | JEXL injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:50:40:50:47 | jexlExpr | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:50:40:50:47 | jexlExpr | JEXL injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:55:40:55:47 | jexlExpr | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:55:40:55:47 | jexlExpr | JEXL injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:61:9:61:39 | createExpression(...) | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:61:9:61:39 | createExpression(...) | JEXL injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:67:9:67:39 | createExpression(...) | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:67:9:67:39 | createExpression(...) | JEXL injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:73:9:73:37 | createTemplate(...) | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:73:9:73:37 | createTemplate(...) | JEXL injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:82:13:82:13 | e | Jexl3Injection.java:92:25:92:47 | getInputStream(...) : InputStream | Jexl3Injection.java:82:13:82:13 | e | JEXL injection from $@. | Jexl3Injection.java:92:25:92:47 | getInputStream(...) | this user input |