Skip to content

Commit 38e0524

Browse files
committed
More csv sinks and sources
1 parent 53e04d0 commit 38e0524

File tree

5 files changed

+54
-114
lines changed

5 files changed

+54
-114
lines changed

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

Lines changed: 33 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ private class DefaultJexlInjectionSinkModel extends SinkModelCsv {
3030
"org.apache.commons.jexl2;Script;false;callable;;;Argument[-1];jexl",
3131
"org.apache.commons.jexl2;JexlScript;false;execute;;;Argument[-1];jexl",
3232
"org.apache.commons.jexl2;JexlScript;false;callable;;;Argument[-1];jexl",
33-
"org.apache.commons.jexl2;JxltEngine$Expression;false;evaluate;;;Argument[-1];jexl",
34-
"org.apache.commons.jexl2;JxltEngine$Expression;false;prepare;;;Argument[-1];jexl",
35-
"org.apache.commons.jexl2;JxltEngine$Template;false;evaluate;;;Argument[-1];jexl",
3633
"org.apache.commons.jexl2;UnifiedJEXL$Expression;false;evaluate;;;Argument[-1];jexl",
3734
"org.apache.commons.jexl2;UnifiedJEXL$Expression;false;prepare;;;Argument[-1];jexl",
3835
"org.apache.commons.jexl2;UnifiedJEXL$Template;false;evaluate;;;Argument[-1];jexl",
@@ -51,10 +48,7 @@ private class DefaultJexlInjectionSinkModel extends SinkModelCsv {
5148
"org.apache.commons.jexl3;JexlScript;false;callable;;;Argument[-1];jexl",
5249
"org.apache.commons.jexl3;JxltEngine$Expression;false;evaluate;;;Argument[-1];jexl",
5350
"org.apache.commons.jexl3;JxltEngine$Expression;false;prepare;;;Argument[-1];jexl",
54-
"org.apache.commons.jexl3;JxltEngine$Template;false;evaluate;;;Argument[-1];jexl",
55-
"org.apache.commons.jexl3;UnifiedJEXL$Expression;false;evaluate;;;Argument[-1];jexl",
56-
"org.apache.commons.jexl3;UnifiedJEXL$Expression;false;prepare;;;Argument[-1];jexl",
57-
"org.apache.commons.jexl3;UnifiedJEXL$Template;false;evaluate;;;Argument[-1];jexl"
51+
"org.apache.commons.jexl3;JxltEngine$Template;false;evaluate;;;Argument[-1];jexl"
5852
]
5953
}
6054
}
@@ -135,48 +129,50 @@ private predicate isUnsafeEngine(Expr expr) {
135129
private class SandboxedJexlFlowConfig extends DataFlow2::Configuration {
136130
SandboxedJexlFlowConfig() { this = "JexlInjection::SandboxedJexlFlowConfig" }
137131

138-
override predicate isSource(DataFlow::Node node) { node instanceof SandboxedJexlSource }
132+
override predicate isSource(DataFlow::Node node) { sourceNode(node, "sandboxed-jexl") }
139133

140-
override predicate isSink(DataFlow::Node node) {
141-
exists(MethodAccess ma, Method m | ma.getMethod() = m |
142-
(
143-
m instanceof CreateJexlScriptMethod or
144-
m instanceof CreateJexlExpressionMethod or
145-
m instanceof CreateJexlTemplateMethod
146-
) and
147-
ma.getQualifier() = node.asExpr()
148-
)
149-
}
134+
override predicate isSink(DataFlow::Node node) { sinkNode(node, "sandboxed-jexl") }
150135

151136
override predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
152-
createsJexlEngine(fromNode, toNode)
137+
createJexlEngineStep(fromNode, toNode)
153138
}
154139
}
155140

156-
/**
157-
* Defines a data flow source for JEXL engines configured with a sandbox.
158-
*/
159-
private class SandboxedJexlSource extends DataFlow::ExprNode {
160-
SandboxedJexlSource() {
161-
exists(MethodAccess ma, Method m | m = ma.getMethod() |
162-
m.getDeclaringType() instanceof JexlBuilder and
163-
m.hasName(["uberspect", "sandbox"]) and
164-
m.getReturnType() instanceof JexlBuilder and
165-
this.asExpr() = [ma, ma.getQualifier()]
166-
)
167-
or
168-
exists(ConstructorCall cc |
169-
cc.getConstructedType() instanceof JexlEngine and
170-
cc.getArgument(0).getType() instanceof JexlUberspect and
171-
cc = this.asExpr()
172-
)
141+
private class SandoboxedJexlSourceModel extends SourceModelCsv {
142+
override predicate row(string row) {
143+
row =
144+
[
145+
// JEXL2
146+
"org.apache.commons.jexl2;JexlEngine;false;JexlEngine;(Uberspect,JexlArithmetic,Map<String,Object>,Log);;ReturnValue;sandboxed-jexl",
147+
// JEXL3
148+
"org.apache.commons.jexl3;JexlBuilder;false;uberspect;(JexlUberspect);;ReturnValue;sandboxed-jexl",
149+
"org.apache.commons.jexl3;JexlBuilder;false;sandbox;(JexlSandbox);;ReturnValue;sandboxed-jexl"
150+
]
151+
}
152+
}
153+
154+
private class SandoboxedJexlSinkModel extends SinkModelCsv {
155+
override predicate row(string row) {
156+
row =
157+
[
158+
// JEXL2
159+
"org.apache.commons.jexl2;JexlEngine;false;createScript;;;Argument[-1];sandboxed-jexl",
160+
"org.apache.commons.jexl2;JexlEngine;false;createExpression;;;Argument[-1];sandboxed-jexl",
161+
"org.apache.commons.jexl2;UnifiedJEXL;false;parse;;;Argument[-1];sandboxed-jexl",
162+
"org.apache.commons.jexl2;UnifiedJEXL;false;createTemplate;;;Argument[-1];sandboxed-jexl",
163+
// JEXL3
164+
"org.apache.commons.jexl3;JexlEngine;false;createScript;;;Argument[-1];sandboxed-jexl",
165+
"org.apache.commons.jexl3;JexlEngine;false;createExpression;;;Argument[-1];sandboxed-jexl",
166+
"org.apache.commons.jexl3;JxltEngine;false;createExpression;;;Argument[-1];sandboxed-jexl",
167+
"org.apache.commons.jexl3;JxltEngine;false;createTemplate;;;Argument[-1];sandboxed-jexl"
168+
]
173169
}
174170
}
175171

176172
/**
177173
* Holds if `fromNode` to `toNode` is a dataflow step that creates one of the JEXL engines.
178174
*/
179-
private predicate createsJexlEngine(DataFlow::Node fromNode, DataFlow::Node toNode) {
175+
private predicate createJexlEngineStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
180176
exists(MethodAccess ma, Method m | m = ma.getMethod() |
181177
(m.getDeclaringType() instanceof JexlBuilder or m.getDeclaringType() instanceof JexlEngine) and
182178
m.hasName(["create", "createJxltEngine"]) and
@@ -191,52 +187,13 @@ private predicate createsJexlEngine(DataFlow::Node fromNode, DataFlow::Node toNo
191187
)
192188
}
193189

194-
/**
195-
* A methods in the `JexlEngine` class that gets or sets a property with a JEXL expression.
196-
*/
197-
private class JexlEngineGetSetPropertyMethod extends Method {
198-
JexlEngineGetSetPropertyMethod() {
199-
getDeclaringType() instanceof JexlEngine and
200-
hasName(["getProperty", "setProperty"])
201-
}
202-
}
203-
204-
/**
205-
* A method that triggers direct evaluation of JEXL expressions.
206-
*/
207-
private class DirectJexlEvaluationMethod extends Method {
208-
DirectJexlEvaluationMethod() {
209-
getDeclaringType() instanceof JexlExpression and hasName("evaluate")
210-
or
211-
getDeclaringType() instanceof JexlScript and hasName("execute")
212-
or
213-
getDeclaringType() instanceof JxltEngineExpression and hasName(["evaluate", "prepare"])
214-
or
215-
getDeclaringType() instanceof JxltEngineTemplate and hasName("evaluate")
216-
or
217-
getDeclaringType() instanceof UnifiedJexlExpression and hasName(["evaluate", "prepare"])
218-
or
219-
getDeclaringType() instanceof UnifiedJexlTemplate and hasName("evaluate")
220-
}
221-
}
222-
223190
/**
224191
* A method that creates a JEXL script.
225192
*/
226193
private class CreateJexlScriptMethod extends Method {
227194
CreateJexlScriptMethod() { getDeclaringType() instanceof JexlEngine and hasName("createScript") }
228195
}
229196

230-
/**
231-
* A method that creates a `Callable` for a JEXL expression or script.
232-
*/
233-
private class CreateJexlCallableMethod extends Method {
234-
CreateJexlCallableMethod() {
235-
(getDeclaringType() instanceof JexlExpression or getDeclaringType() instanceof JexlScript) and
236-
hasName("callable")
237-
}
238-
}
239-
240197
/**
241198
* A method that creates a JEXL template.
242199
*/
@@ -263,14 +220,6 @@ private class JexlRefType extends RefType {
263220
JexlRefType() { getPackage().hasName(["org.apache.commons.jexl2", "org.apache.commons.jexl3"]) }
264221
}
265222

266-
private class JexlExpression extends JexlRefType {
267-
JexlExpression() { hasName(["Expression", "JexlExpression"]) }
268-
}
269-
270-
private class JexlScript extends JexlRefType {
271-
JexlScript() { hasName(["Script", "JexlScript"]) }
272-
}
273-
274223
private class JexlBuilder extends JexlRefType {
275224
JexlBuilder() { hasName("JexlBuilder") }
276225
}
@@ -287,29 +236,6 @@ private class UnifiedJexl extends JexlRefType {
287236
UnifiedJexl() { hasName("UnifiedJEXL") }
288237
}
289238

290-
private class JexlUberspect extends Interface {
291-
JexlUberspect() {
292-
hasQualifiedName("org.apache.commons.jexl2.introspection", "Uberspect") or
293-
hasQualifiedName("org.apache.commons.jexl3.introspection", "JexlUberspect")
294-
}
295-
}
296-
297-
private class JxltEngineExpression extends NestedType {
298-
JxltEngineExpression() { getEnclosingType() instanceof JxltEngine and hasName("Expression") }
299-
}
300-
301-
private class JxltEngineTemplate extends NestedType {
302-
JxltEngineTemplate() { getEnclosingType() instanceof JxltEngine and hasName("Template") }
303-
}
304-
305-
private class UnifiedJexlExpression extends NestedType {
306-
UnifiedJexlExpression() { getEnclosingType() instanceof UnifiedJexl and hasName("Expression") }
307-
}
308-
309-
private class UnifiedJexlTemplate extends NestedType {
310-
UnifiedJexlTemplate() { getEnclosingType() instanceof UnifiedJexl and hasName("Template") }
311-
}
312-
313239
private class Reader extends RefType {
314240
Reader() { hasQualifiedName("java.io", "Reader") }
315241
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../../stubs/mvel2-2.4.7:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../../stubs/scriptengine:${testdir}/../../../../stubs/java-ee-el:${testdir}/../../../../stubs/juel-2.2:${testdir}/../../../stubs/groovy-all-3.0.7:${testdir}/../../../../stubs/servlet-api-2.4
1+
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../../stubs/mvel2-2.4.7:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../../stubs/scriptengine:${testdir}/../../../../stubs/java-ee-el:${testdir}/../../../../stubs/juel-2.2:${testdir}/../../../stubs/groovy-all-3.0.7:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/apache-commons-logging-1.2
22

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.apache.commons.jexl2;
2+
3+
public class JexlArithmetic {
4+
5+
}

java/ql/test/stubs/apache-commons-jexl-2.1.1/org/apache/commons/jexl2/JexlEngine.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22

33
import java.util.Map;
44
import org.apache.commons.jexl2.introspection.*;
5+
import org.apache.commons.logging.Log;
56

67
public class JexlEngine {
78

8-
public JexlEngine() {}
9+
public JexlEngine() {
10+
}
911

10-
public JexlEngine(Uberspect uberspect, Object arithmetic, Map<String, Object> functions, Object log) {}
12+
public JexlEngine(Uberspect uberspect, JexlArithmetic arithmetic, Map<String, Object> functions, Log log) {
13+
}
1114

1215
public Expression createExpression(String expression) {
1316
return null;
@@ -41,9 +44,10 @@ public Object getProperty(JexlContext context, Object bean, String expr) {
4144
return null;
4245
}
4346

44-
public void setProperty(Object bean, String expr, Object value) {}
47+
public void setProperty(Object bean, String expr, Object value) {
48+
}
49+
50+
public void setProperty(JexlContext context, Object bean, String expr, Object value) {
51+
}
4552

46-
public void setProperty(JexlContext context, Object bean, String expr, Object value) {}
47-
48-
4953
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.apache.commons.logging;
2+
3+
public interface Log {
4+
5+
}

0 commit comments

Comments
 (0)