Skip to content

Commit d254d91

Browse files
committed
Refactor Injection queries
1 parent 7002ed5 commit d254d91

10 files changed

+73
-63
lines changed

java/ql/src/experimental/Security/CWE/CWE-094/BeanShellInjection.ql

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,15 @@
1414
import java
1515
import BeanShellInjection
1616
import semmle.code.java.dataflow.FlowSources
17-
import DataFlow::PathGraph
17+
import semmle.code.java.dataflow.TaintTracking
18+
import BeanShellInjectionFlow::PathGraph
1819

19-
class BeanShellInjectionConfig extends TaintTracking::Configuration {
20-
BeanShellInjectionConfig() { this = "BeanShellInjectionConfig" }
20+
module BeanShellInjectionConfig implements DataFlow::ConfigSig {
21+
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
2122

22-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
23+
predicate isSink(DataFlow::Node sink) { sink instanceof BeanShellInjectionSink }
2324

24-
override predicate isSink(DataFlow::Node sink) { sink instanceof BeanShellInjectionSink }
25-
26-
override predicate isAdditionalTaintStep(DataFlow::Node prod, DataFlow::Node succ) {
25+
predicate isAdditionalFlowStep(DataFlow::Node prod, DataFlow::Node succ) {
2726
exists(ClassInstanceExpr cie |
2827
cie.getConstructedType()
2928
.hasQualifiedName("org.springframework.scripting.support", "StaticScriptSource") and
@@ -42,7 +41,9 @@ class BeanShellInjectionConfig extends TaintTracking::Configuration {
4241
}
4342
}
4443

45-
from DataFlow::PathNode source, DataFlow::PathNode sink, BeanShellInjectionConfig conf
46-
where conf.hasFlowPath(source, sink)
44+
module BeanShellInjectionFlow = TaintTracking::Global<BeanShellInjectionConfig>;
45+
46+
from BeanShellInjectionFlow::PathNode source, BeanShellInjectionFlow::PathNode sink
47+
where BeanShellInjectionFlow::flowPath(source, sink)
4748
select sink.getNode(), source, sink, "BeanShell injection from $@.", source.getNode(),
4849
"this user input"

java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoading.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313

1414
import java
1515
import InsecureDexLoading
16-
import DataFlow::PathGraph
16+
import InsecureDexFlow::PathGraph
1717

18-
from DataFlow::PathNode source, DataFlow::PathNode sink, InsecureDexConfiguration conf
19-
where conf.hasFlowPath(source, sink)
18+
from InsecureDexFlow::PathNode source, InsecureDexFlow::PathNode sink
19+
where InsecureDexFlow::flowPath(source, sink)
2020
select sink.getNode(), source, sink, "Potential arbitrary code execution due to $@.",
2121
source.getNode(), "a value loaded from a world-writable source."

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
import java
2+
import semmle.code.java.dataflow.TaintTracking
23
import semmle.code.java.dataflow.FlowSources
34

45
/**
56
* A taint-tracking configuration detecting unsafe use of a
67
* `DexClassLoader` by an Android app.
78
*/
8-
class InsecureDexConfiguration extends TaintTracking::Configuration {
9-
InsecureDexConfiguration() { this = "Insecure Dex File Load" }
9+
module InsecureDexConfig implements DataFlow::ConfigSig {
10+
predicate isSource(DataFlow::Node source) { source instanceof InsecureDexSource }
1011

11-
override predicate isSource(DataFlow::Node source) { source instanceof InsecureDexSource }
12+
predicate isSink(DataFlow::Node sink) { sink instanceof InsecureDexSink }
1213

13-
override predicate isSink(DataFlow::Node sink) { sink instanceof InsecureDexSink }
14-
15-
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
16-
flowStep(pred, succ)
17-
}
14+
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { flowStep(pred, succ) }
1815
}
1916

17+
module InsecureDexFlow = TaintTracking::Global<InsecureDexConfig>;
18+
2019
/** A data flow source for insecure Dex class loading vulnerabilities. */
2120
abstract class InsecureDexSource extends DataFlow::Node { }
2221

java/ql/src/experimental/Security/CWE/CWE-094/JShellInjection.ql

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,15 @@
1414
import java
1515
import JShellInjection
1616
import semmle.code.java.dataflow.FlowSources
17-
import DataFlow::PathGraph
17+
import semmle.code.java.dataflow.TaintTracking
18+
import JShellInjectionFlow::PathGraph
1819

19-
class JShellInjectionConfiguration extends TaintTracking::Configuration {
20-
JShellInjectionConfiguration() { this = "JShellInjectionConfiguration" }
20+
module JShellInjectionConfig implements DataFlow::ConfigSig {
21+
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
2122

22-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
23+
predicate isSink(DataFlow::Node sink) { sink instanceof JShellInjectionSink }
2324

24-
override predicate isSink(DataFlow::Node sink) { sink instanceof JShellInjectionSink }
25-
26-
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
25+
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
2726
exists(SourceCodeAnalysisAnalyzeCompletionCall scaacc |
2827
scaacc.getArgument(0) = pred.asExpr() and scaacc = succ.asExpr()
2928
)
@@ -34,7 +33,9 @@ class JShellInjectionConfiguration extends TaintTracking::Configuration {
3433
}
3534
}
3635

37-
from DataFlow::PathNode source, DataFlow::PathNode sink, JShellInjectionConfiguration conf
38-
where conf.hasFlowPath(source, sink)
36+
module JShellInjectionFlow = TaintTracking::Global<JShellInjectionConfig>;
37+
38+
from JShellInjectionFlow::PathNode source, JShellInjectionFlow::PathNode sink
39+
where JShellInjectionFlow::flowPath(source, sink)
3940
select sink.getNode(), source, sink, "JShell injection from $@.", source.getNode(),
4041
"this user input"

java/ql/src/experimental/Security/CWE/CWE-094/JakartaExpressionInjection.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313

1414
import java
1515
import JakartaExpressionInjectionLib
16-
import DataFlow::PathGraph
16+
import JakartaExpressionInjectionFlow::PathGraph
1717

18-
from DataFlow::PathNode source, DataFlow::PathNode sink, JakartaExpressionInjectionConfig conf
19-
where conf.hasFlowPath(source, sink)
18+
from JakartaExpressionInjectionFlow::PathNode source, JakartaExpressionInjectionFlow::PathNode sink
19+
where JakartaExpressionInjectionFlow::flowPath(source, sink)
2020
select sink.getNode(), source, sink, "Jakarta Expression Language injection from $@.",
2121
source.getNode(), "this user input"

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,22 @@ import semmle.code.java.dataflow.TaintTracking
77
* A taint-tracking configuration for unsafe user input
88
* that is used to construct and evaluate an expression.
99
*/
10-
class JakartaExpressionInjectionConfig extends TaintTracking::Configuration {
11-
JakartaExpressionInjectionConfig() { this = "JakartaExpressionInjectionConfig" }
10+
module JakartaExpressionInjectionConfig implements DataFlow::ConfigSig {
11+
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
1212

13-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
13+
predicate isSink(DataFlow::Node sink) { sink instanceof ExpressionEvaluationSink }
1414

15-
override predicate isSink(DataFlow::Node sink) { sink instanceof ExpressionEvaluationSink }
16-
17-
override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
15+
predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
1816
any(TaintPropagatingCall c).taintFlow(fromNode, toNode) or
1917
hasGetterFlow(fromNode, toNode)
2018
}
2119
}
2220

21+
/**
22+
* Taint-tracking flow from remote sources, through an expression, to its eventual evaluation.
23+
*/
24+
module JakartaExpressionInjectionFlow = TaintTracking::Global<JakartaExpressionInjectionConfig>;
25+
2326
/**
2427
* A sink for Expresssion Language injection vulnerabilities,
2528
* i.e. method calls that run evaluation of an expression.

java/ql/src/experimental/Security/CWE/CWE-094/JythonInjection.ql

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414

1515
import java
1616
import semmle.code.java.dataflow.FlowSources
17+
import semmle.code.java.dataflow.TaintTracking
1718
import semmle.code.java.frameworks.spring.SpringController
18-
import DataFlow::PathGraph
19+
import CodeInjectionFlow::PathGraph
1920

2021
/** The class `org.python.util.PythonInterpreter`. */
2122
class PythonInterpreter extends RefType {
@@ -101,15 +102,19 @@ class CodeInjectionSink extends DataFlow::ExprNode {
101102
* A taint configuration for tracking flow from `RemoteFlowSource` to a Jython method call
102103
* `CodeInjectionSink` that executes injected code.
103104
*/
104-
class CodeInjectionConfiguration extends TaintTracking::Configuration {
105-
CodeInjectionConfiguration() { this = "CodeInjectionConfiguration" }
105+
module CodeInjectionConfig implements DataFlow::ConfigSig {
106+
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
106107

107-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
108-
109-
override predicate isSink(DataFlow::Node sink) { sink instanceof CodeInjectionSink }
108+
predicate isSink(DataFlow::Node sink) { sink instanceof CodeInjectionSink }
110109
}
111110

112-
from DataFlow::PathNode source, DataFlow::PathNode sink, CodeInjectionConfiguration conf
113-
where conf.hasFlowPath(source, sink)
111+
/**
112+
* Taint tracking flow from `RemoteFlowSource` to a Jython method call
113+
* `CodeInjectionSink` that executes injected code.
114+
*/
115+
module CodeInjectionFlow = TaintTracking::Global<CodeInjectionConfig>;
116+
117+
from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink
118+
where CodeInjectionFlow::flowPath(source, sink)
114119
select sink.getNode().(CodeInjectionSink).getMethodAccess(), source, sink, "Jython evaluate $@.",
115120
source.getNode(), "user input"

java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.ql

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
*/
1313

1414
import java
15+
import semmle.code.java.dataflow.TaintTracking
1516
import semmle.code.java.dataflow.FlowSources
16-
import DataFlow::PathGraph
17+
import ScriptInjectionFlow::PathGraph
1718

1819
/** A method of ScriptEngine that allows code injection. */
1920
class ScriptEngineMethod extends Method {
@@ -133,15 +134,15 @@ class ScriptInjectionSink extends DataFlow::ExprNode {
133134
* A taint tracking configuration that tracks flow from `RemoteFlowSource` to an argument
134135
* of a method call that executes injected script.
135136
*/
136-
class ScriptInjectionConfiguration extends TaintTracking::Configuration {
137-
ScriptInjectionConfiguration() { this = "ScriptInjectionConfiguration" }
137+
module ScriptInjectionConfig implements DataFlow::ConfigSig {
138+
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
138139

139-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
140-
141-
override predicate isSink(DataFlow::Node sink) { sink instanceof ScriptInjectionSink }
140+
predicate isSink(DataFlow::Node sink) { sink instanceof ScriptInjectionSink }
142141
}
143142

144-
from DataFlow::PathNode source, DataFlow::PathNode sink, ScriptInjectionConfiguration conf
145-
where conf.hasFlowPath(source, sink)
143+
module ScriptInjectionFlow = TaintTracking::Global<ScriptInjectionConfig>;
144+
145+
from ScriptInjectionFlow::PathNode source, ScriptInjectionFlow::PathNode sink
146+
where ScriptInjectionFlow::flowPath(source, sink)
146147
select sink.getNode().(ScriptInjectionSink).getMethodAccess(), source, sink,
147148
"Java Script Engine evaluate $@.", source.getNode(), "user input"

java/ql/src/experimental/Security/CWE/CWE-094/SpringViewManipulation.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212

1313
import java
1414
import SpringViewManipulationLib
15-
import DataFlow::PathGraph
15+
import SpringViewManipulationFlow::PathGraph
1616

17-
from DataFlow::PathNode source, DataFlow::PathNode sink, SpringViewManipulationConfig conf
17+
from SpringViewManipulationFlow::PathNode source, SpringViewManipulationFlow::PathNode sink
1818
where
1919
thymeleafIsUsed() and
20-
conf.hasFlowPath(source, sink)
20+
SpringViewManipulationFlow::flowPath(source, sink)
2121
select sink.getNode(), source, sink, "Potential Spring Expression Language injection from $@.",
2222
source.getNode(), "this user input"

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,16 @@ class PortletRenderRequestMethod extends Method {
4040
* A taint-tracking configuration for unsafe user input
4141
* that can lead to Spring View Manipulation vulnerabilities.
4242
*/
43-
class SpringViewManipulationConfig extends TaintTracking::Configuration {
44-
SpringViewManipulationConfig() { this = "Spring View Manipulation Config" }
45-
46-
override predicate isSource(DataFlow::Node source) {
43+
module SpringViewManipulationConfig implements DataFlow::ConfigSig {
44+
predicate isSource(DataFlow::Node source) {
4745
source instanceof RemoteFlowSource or
4846
source instanceof WebRequestSource or
4947
source.asExpr().(MethodAccess).getMethod() instanceof PortletRenderRequestMethod
5048
}
5149

52-
override predicate isSink(DataFlow::Node sink) { sink instanceof SpringViewManipulationSink }
50+
predicate isSink(DataFlow::Node sink) { sink instanceof SpringViewManipulationSink }
5351

54-
override predicate isSanitizer(DataFlow::Node node) {
52+
predicate isBarrier(DataFlow::Node node) {
5553
// Block flows like
5654
// ```
5755
// a = "redirect:" + taint`
@@ -88,6 +86,8 @@ class SpringViewManipulationConfig extends TaintTracking::Configuration {
8886
}
8987
}
9088

89+
module SpringViewManipulationFlow = TaintTracking::Global<SpringViewManipulationConfig>;
90+
9191
private Call getAStringCombiningCall() {
9292
exists(StringCombiningMethod m | result = m.getAReference())
9393
}

0 commit comments

Comments
 (0)