Skip to content

Commit ac58299

Browse files
authored
Merge pull request github#12541 from egregius313/egregius313/refactor-queries-to-new-dataflow-api
Java: Refactor more queries to the new DataFlow module API
2 parents fa60fa0 + 83b0d07 commit ac58299

20 files changed

+254
-170
lines changed

java/ql/lib/semmle/code/java/security/XxeLocalQuery.qll

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ private import semmle.code.java.dataflow.TaintTracking
66
private import semmle.code.java.security.XxeQuery
77

88
/**
9+
* DEPRECATED: Use `XxeLocalFlow` instead.
10+
*
911
* A taint-tracking configuration for unvalidated local user input that is used in XML external entity expansion.
1012
*/
11-
class XxeLocalConfig extends TaintTracking::Configuration {
13+
deprecated class XxeLocalConfig extends TaintTracking::Configuration {
1214
XxeLocalConfig() { this = "XxeLocalConfig" }
1315

1416
override predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput }
@@ -21,3 +23,23 @@ class XxeLocalConfig extends TaintTracking::Configuration {
2123
any(XxeAdditionalTaintStep s).step(n1, n2)
2224
}
2325
}
26+
27+
/**
28+
* A taint-tracking configuration for unvalidated local user input that is used in XML external entity expansion.
29+
*/
30+
module XxeLocalConfig implements DataFlow::ConfigSig {
31+
predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput }
32+
33+
predicate isSink(DataFlow::Node sink) { sink instanceof XxeSink }
34+
35+
predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof XxeSanitizer }
36+
37+
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
38+
any(XxeAdditionalTaintStep s).step(n1, n2)
39+
}
40+
}
41+
42+
/**
43+
* Detect taint flow of unvalidated local user input that is used in XML external entity expansion.
44+
*/
45+
module XxeLocalFlow = TaintTracking::Make<XxeLocalConfig>;

java/ql/lib/semmle/code/java/security/XxeRemoteQuery.qll

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ private import semmle.code.java.dataflow.TaintTracking
66
private import semmle.code.java.security.XxeQuery
77

88
/**
9+
* DEPRECATED: Use `XxeFlow` instead.
10+
*
911
* A taint-tracking configuration for unvalidated remote user input that is used in XML external entity expansion.
1012
*/
11-
class XxeConfig extends TaintTracking::Configuration {
13+
deprecated class XxeConfig extends TaintTracking::Configuration {
1214
XxeConfig() { this = "XxeConfig" }
1315

1416
override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
@@ -21,3 +23,23 @@ class XxeConfig extends TaintTracking::Configuration {
2123
any(XxeAdditionalTaintStep s).step(n1, n2)
2224
}
2325
}
26+
27+
/**
28+
* A taint-tracking configuration for unvalidated remote user input that is used in XML external entity expansion.
29+
*/
30+
module XxeConfig implements DataFlow::ConfigSig {
31+
predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
32+
33+
predicate isSink(DataFlow::Node sink) { sink instanceof XxeSink }
34+
35+
predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof XxeSanitizer }
36+
37+
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
38+
any(XxeAdditionalTaintStep s).step(n1, n2)
39+
}
40+
}
41+
42+
/**
43+
* Detect taint flow of unvalidated remote user input that is used in XML external entity expansion.
44+
*/
45+
module XxeFlow = TaintTracking::Make<XxeConfig>;

java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,33 @@ import semmle.code.java.dataflow.FlowSources
1818
private import semmle.code.java.dataflow.ExternalFlow
1919
import semmle.code.java.security.PathCreation
2020
import semmle.code.java.security.PathSanitizer
21-
import DataFlow::PathGraph
2221
import TaintedPathCommon
2322

24-
class TaintedPathLocalConfig extends TaintTracking::Configuration {
25-
TaintedPathLocalConfig() { this = "TaintedPathLocalConfig" }
23+
module TaintedPathLocalConfig implements DataFlow::ConfigSig {
24+
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
2625

27-
override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
28-
29-
override predicate isSink(DataFlow::Node sink) {
26+
predicate isSink(DataFlow::Node sink) {
3027
sink.asExpr() = any(PathCreation p).getAnInput()
3128
or
3229
sinkNode(sink, "create-file")
3330
}
3431

35-
override predicate isSanitizer(DataFlow::Node sanitizer) {
32+
predicate isBarrier(DataFlow::Node sanitizer) {
3633
sanitizer.getType() instanceof BoxedType or
3734
sanitizer.getType() instanceof PrimitiveType or
3835
sanitizer.getType() instanceof NumberType or
3936
sanitizer instanceof PathInjectionSanitizer
4037
}
4138

42-
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
39+
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
4340
any(TaintedPathAdditionalTaintStep s).step(n1, n2)
4441
}
4542
}
4643

44+
module TaintedPathLocalFlow = TaintTracking::Make<TaintedPathLocalConfig>;
45+
46+
import TaintedPathLocalFlow::PathGraph
47+
4748
/**
4849
* Gets the data-flow node at which to report a path ending at `sink`.
4950
*
@@ -52,13 +53,13 @@ class TaintedPathLocalConfig extends TaintTracking::Configuration {
5253
* continue to report there; otherwise we report directly at `sink`.
5354
*/
5455
DataFlow::Node getReportingNode(DataFlow::Node sink) {
55-
any(TaintedPathLocalConfig c).hasFlowTo(sink) and
56+
TaintedPathLocalFlow::hasFlowTo(sink) and
5657
if exists(PathCreation pc | pc.getAnInput() = sink.asExpr())
5758
then result.asExpr() = any(PathCreation pc | pc.getAnInput() = sink.asExpr())
5859
else result = sink
5960
}
6061

61-
from DataFlow::PathNode source, DataFlow::PathNode sink, TaintedPathLocalConfig conf
62-
where conf.hasFlowPath(source, sink)
62+
from TaintedPathLocalFlow::PathNode source, TaintedPathLocalFlow::PathNode sink
63+
where TaintedPathLocalFlow::hasFlowPath(source, sink)
6364
select getReportingNode(sink.getNode()), source, sink, "This path depends on a $@.",
6465
source.getNode(), "user-provided value"

java/ql/src/Security/CWE/CWE-022/ZipSlip.ql

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ import semmle.code.java.controlflow.Guards
1717
import semmle.code.java.dataflow.SSA
1818
import semmle.code.java.dataflow.TaintTracking
1919
import semmle.code.java.security.PathSanitizer
20-
import DataFlow
21-
import PathGraph
2220
private import semmle.code.java.dataflow.ExternalFlow
2321

2422
/**
@@ -36,27 +34,29 @@ class ArchiveEntryNameMethod extends Method {
3634
}
3735
}
3836

39-
class ZipSlipConfiguration extends TaintTracking::Configuration {
40-
ZipSlipConfiguration() { this = "ZipSlip" }
41-
42-
override predicate isSource(Node source) {
37+
module ZipSlipConfig implements DataFlow::ConfigSig {
38+
predicate isSource(DataFlow::Node source) {
4339
source.asExpr().(MethodAccess).getMethod() instanceof ArchiveEntryNameMethod
4440
}
4541

46-
override predicate isSink(Node sink) { sink instanceof FileCreationSink }
42+
predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink }
4743

48-
override predicate isSanitizer(Node node) { node instanceof PathInjectionSanitizer }
44+
predicate isBarrier(DataFlow::Node node) { node instanceof PathInjectionSanitizer }
4945
}
5046

47+
module ZipSlipFlow = TaintTracking::Make<ZipSlipConfig>;
48+
49+
import ZipSlipFlow::PathGraph
50+
5151
/**
5252
* A sink that represents a file creation, such as a file write, copy or move operation.
5353
*/
5454
private class FileCreationSink extends DataFlow::Node {
5555
FileCreationSink() { sinkNode(this, "create-file") }
5656
}
5757

58-
from PathNode source, PathNode sink
59-
where any(ZipSlipConfiguration c).hasFlowPath(source, sink)
58+
from ZipSlipFlow::PathNode source, ZipSlipFlow::PathNode sink
59+
where ZipSlipFlow::hasFlowPath(source, sink)
6060
select source.getNode(), source, sink,
6161
"Unsanitized archive entry, which may contain '..', is used in a $@.", sink.getNode(),
6262
"file system operation"

java/ql/src/Security/CWE/CWE-090/LdapInjection.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
import java
1515
import semmle.code.java.dataflow.FlowSources
1616
import LdapInjectionLib
17-
import DataFlow::PathGraph
17+
import LdapInjectionFlow::PathGraph
1818

19-
from DataFlow::PathNode source, DataFlow::PathNode sink, LdapInjectionFlowConfig conf
20-
where conf.hasFlowPath(source, sink)
19+
from LdapInjectionFlow::PathNode source, LdapInjectionFlow::PathNode sink
20+
where LdapInjectionFlow::hasFlowPath(source, sink)
2121
select sink.getNode(), source, sink, "This LDAP query depends on a $@.", source.getNode(),
2222
"user-provided value"
Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
import java
22
import semmle.code.java.dataflow.FlowSources
3-
import DataFlow
43
import semmle.code.java.security.LdapInjection
54

65
/**
76
* A taint-tracking configuration for unvalidated user input that is used to construct LDAP queries.
87
*/
9-
class LdapInjectionFlowConfig extends TaintTracking::Configuration {
10-
LdapInjectionFlowConfig() { this = "LdapInjectionFlowConfig" }
8+
module LdapInjectionFlowConfig implements DataFlow::ConfigSig {
9+
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
1110

12-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
11+
predicate isSink(DataFlow::Node sink) { sink instanceof LdapInjectionSink }
1312

14-
override predicate isSink(DataFlow::Node sink) { sink instanceof LdapInjectionSink }
13+
predicate isBarrier(DataFlow::Node node) { node instanceof LdapInjectionSanitizer }
1514

16-
override predicate isSanitizer(DataFlow::Node node) { node instanceof LdapInjectionSanitizer }
17-
18-
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
15+
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
1916
any(LdapInjectionAdditionalTaintStep a).step(pred, succ)
2017
}
2118
}
19+
20+
module LdapInjectionFlow = TaintTracking::Make<LdapInjectionFlowConfig>;

java/ql/src/Security/CWE/CWE-094/InsecureBeanValidation.ql

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import java
1414
import semmle.code.java.dataflow.TaintTracking
1515
import semmle.code.java.dataflow.FlowSources
16-
import DataFlow::PathGraph
1716
private import semmle.code.java.dataflow.ExternalFlow
1817

1918
/**
@@ -56,14 +55,16 @@ class SetMessageInterpolatorCall extends MethodAccess {
5655
* Taint tracking BeanValidationConfiguration describing the flow of data from user input
5756
* to the argument of a method that builds constraint error messages.
5857
*/
59-
class BeanValidationConfig extends TaintTracking::Configuration {
60-
BeanValidationConfig() { this = "BeanValidationConfig" }
58+
module BeanValidationConfig implements DataFlow::ConfigSig {
59+
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
6160

62-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
63-
64-
override predicate isSink(DataFlow::Node sink) { sink instanceof BeanValidationSink }
61+
predicate isSink(DataFlow::Node sink) { sink instanceof BeanValidationSink }
6562
}
6663

64+
module BeanValidationFlow = TaintTracking::Make<BeanValidationConfig>;
65+
66+
import BeanValidationFlow::PathGraph
67+
6768
/**
6869
* A bean validation sink, such as method `buildConstraintViolationWithTemplate`
6970
* declared on a subtype of `javax.validation.ConstraintValidatorContext`.
@@ -72,13 +73,13 @@ private class BeanValidationSink extends DataFlow::Node {
7273
BeanValidationSink() { sinkNode(this, "bean-validation") }
7374
}
7475

75-
from BeanValidationConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink
76+
from BeanValidationFlow::PathNode source, BeanValidationFlow::PathNode sink
7677
where
7778
(
7879
not exists(SetMessageInterpolatorCall c)
7980
or
8081
exists(SetMessageInterpolatorCall c | not c.isSafe())
8182
) and
82-
cfg.hasFlowPath(source, sink)
83+
BeanValidationFlow::hasFlowPath(source, sink)
8384
select sink.getNode(), source, sink, "Custom constraint error message contains an unsanitized $@.",
8485
source, "user-provided value"

java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,29 @@
1313
import java
1414
import semmle.code.java.dataflow.FlowSources
1515
import semmle.code.java.StringFormat
16-
import DataFlow::PathGraph
1716

18-
class ExternallyControlledFormatStringConfig extends TaintTracking::Configuration {
19-
ExternallyControlledFormatStringConfig() { this = "ExternallyControlledFormatStringConfig" }
17+
module ExternallyControlledFormatStringConfig implements DataFlow::ConfigSig {
18+
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
2019

21-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
22-
23-
override predicate isSink(DataFlow::Node sink) {
20+
predicate isSink(DataFlow::Node sink) {
2421
sink.asExpr() = any(StringFormat formatCall).getFormatArgument()
2522
}
2623

27-
override predicate isSanitizer(DataFlow::Node node) {
24+
predicate isBarrier(DataFlow::Node node) {
2825
node.getType() instanceof NumericType or node.getType() instanceof BooleanType
2926
}
3027
}
3128

29+
module ExternallyControlledFormatStringFlow =
30+
TaintTracking::Make<ExternallyControlledFormatStringConfig>;
31+
32+
import ExternallyControlledFormatStringFlow::PathGraph
33+
3234
from
33-
DataFlow::PathNode source, DataFlow::PathNode sink, StringFormat formatCall,
34-
ExternallyControlledFormatStringConfig conf
35-
where conf.hasFlowPath(source, sink) and sink.getNode().asExpr() = formatCall.getFormatArgument()
35+
ExternallyControlledFormatStringFlow::PathNode source,
36+
ExternallyControlledFormatStringFlow::PathNode sink, StringFormat formatCall
37+
where
38+
ExternallyControlledFormatStringFlow::hasFlowPath(source, sink) and
39+
sink.getNode().asExpr() = formatCall.getFormatArgument()
3640
select formatCall.getFormatArgument(), source, sink, "Format string depends on a $@.",
3741
source.getNode(), "user-provided value"

java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatStringLocal.ql

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,25 @@
1313
import java
1414
import semmle.code.java.dataflow.FlowSources
1515
import semmle.code.java.StringFormat
16-
import DataFlow::PathGraph
1716

18-
class ExternallyControlledFormatStringLocalConfig extends TaintTracking::Configuration {
19-
ExternallyControlledFormatStringLocalConfig() {
20-
this = "ExternallyControlledFormatStringLocalConfig"
21-
}
22-
23-
override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
17+
module ExternallyControlledFormatStringLocalConfig implements DataFlow::ConfigSig {
18+
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
2419

25-
override predicate isSink(DataFlow::Node sink) {
20+
predicate isSink(DataFlow::Node sink) {
2621
sink.asExpr() = any(StringFormat formatCall).getFormatArgument()
2722
}
2823
}
2924

25+
module ExternallyControlledFormatStringLocalFlow =
26+
TaintTracking::Make<ExternallyControlledFormatStringLocalConfig>;
27+
28+
import ExternallyControlledFormatStringLocalFlow::PathGraph
29+
3030
from
31-
DataFlow::PathNode source, DataFlow::PathNode sink, StringFormat formatCall,
32-
ExternallyControlledFormatStringLocalConfig conf
33-
where conf.hasFlowPath(source, sink) and sink.getNode().asExpr() = formatCall.getFormatArgument()
31+
ExternallyControlledFormatStringLocalFlow::PathNode source,
32+
ExternallyControlledFormatStringLocalFlow::PathNode sink, StringFormat formatCall
33+
where
34+
ExternallyControlledFormatStringLocalFlow::hasFlowPath(source, sink) and
35+
sink.getNode().asExpr() = formatCall.getFormatArgument()
3436
select formatCall.getFormatArgument(), source, sink, "Format string depends on a $@.",
3537
source.getNode(), "user-provided value"

0 commit comments

Comments
 (0)