Skip to content

Commit 784ccb7

Browse files
committed
Rust: Define Rust queries and extensions more consistently.
1 parent 1acbdba commit 784ccb7

File tree

8 files changed

+122
-85
lines changed

8 files changed

+122
-85
lines changed

rust/ql/lib/codeql/rust/security/CleartextLoggingExtensions.qll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ module CleartextLogging {
3636
*/
3737
private class SensitiveDataAsSource extends Source instanceof SensitiveData { }
3838

39-
/** A sink for logging from model data. */
40-
private class ModelsAsDataSinks extends Sink {
41-
ModelsAsDataSinks() { exists(string s | sinkNode(this, s) and s.matches("log-injection%")) }
39+
/**
40+
* A sink for logging from model data.
41+
*/
42+
private class ModelsAsDataSink extends Sink {
43+
ModelsAsDataSink() { exists(string s | sinkNode(this, s) and s.matches("log-injection%")) }
4244
}
4345
}

rust/ql/lib/codeql/rust/security/CleartextTransmissionExtensions.qll

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,48 @@ private import codeql.rust.dataflow.FlowSink
1010
private import codeql.rust.Concepts
1111

1212
/**
13-
* A data flow sink for cleartext transmission vulnerabilities. That is,
14-
* a `DataFlow::Node` of something that is transmitted over a network.
13+
* Provides default sources, sinks and barriers for detecting cleartext transmission
14+
* vulnerabilities, as well as extension points for adding your own.
1515
*/
16-
abstract class CleartextTransmissionSink extends QuerySink::Range {
17-
override string getSinkType() { result = "CleartextTransmission" }
18-
}
16+
module CleartextTransmission {
17+
/**
18+
* A data flow source for cleartext transmission vulnerabilities.
19+
*/
20+
abstract class Source extends DataFlow::Node { }
1921

20-
/**
21-
* A barrier for cleartext transmission vulnerabilities.
22-
*/
23-
abstract class CleartextTransmissionBarrier extends DataFlow::Node { }
22+
/**
23+
* A data flow sink for cleartext transmission vulnerabilities. That is,
24+
* a `DataFlow::Node` of something that is transmitted over a network.
25+
*/
26+
abstract class Sink extends QuerySink::Range {
27+
override string getSinkType() { result = "CleartextTransmission" }
28+
}
2429

25-
/**
26-
* A unit class for adding additional flow steps.
27-
*/
28-
class CleartextTransmissionAdditionalFlowStep extends Unit {
2930
/**
30-
* Holds if the step from `node1` to `node2` should be considered a flow
31-
* step for paths related to cleartext transmission vulnerabilities.
31+
* A barrier for cleartext transmission vulnerabilities.
3232
*/
33-
abstract predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo);
34-
}
33+
abstract class Barrier extends DataFlow::Node { }
3534

36-
/**
37-
* A sink defined through MaD.
38-
*/
39-
private class MadCleartextTransmissionSink extends CleartextTransmissionSink {
40-
MadCleartextTransmissionSink() { sinkNode(this, "transmission") }
35+
/**
36+
* A unit class for adding additional flow steps.
37+
*/
38+
class AdditionalFlowStep extends Unit {
39+
/**
40+
* Holds if the step from `node1` to `node2` should be considered a flow
41+
* step for paths related to cleartext transmission vulnerabilities.
42+
*/
43+
abstract predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo);
44+
}
45+
46+
/**
47+
* Sensitive data, considered as a flow source.
48+
*/
49+
private class SensitiveDataAsSource extends Source instanceof SensitiveData { }
50+
51+
/**
52+
* A sink defined through MaD.
53+
*/
54+
private class ModelsAsDataSink extends Sink {
55+
ModelsAsDataSink() { sinkNode(this, "transmission") }
56+
}
4157
}

rust/ql/lib/codeql/rust/security/SqlInjectionExtensions.qll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ module SqlInjection {
5151
SqlExecutionAsSink() { this = any(SqlExecution e).getSql() }
5252
}
5353

54-
/** A sink for sql-injection from model data. */
55-
private class ModelsAsDataSinks extends Sink {
56-
ModelsAsDataSinks() { sinkNode(this, "sql-injection") }
54+
/**
55+
* A sink for sql-injection from model data.
56+
*/
57+
private class ModelsAsDataSink extends Sink {
58+
ModelsAsDataSink() { sinkNode(this, "sql-injection") }
5759
}
5860
}

rust/ql/lib/codeql/rust/security/regex/RegexInjectionExtensions.qll

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,60 +11,71 @@ private import codeql.rust.dataflow.FlowSink
1111
private import codeql.rust.Concepts
1212

1313
/**
14-
* A data flow sink for regular expression injection vulnerabilities.
14+
* Provides default sources, sinks and barriers for detecting regular expression
15+
* injection vulnerabilities, as well as extension points for adding your own.
1516
*/
16-
abstract class RegexInjectionSink extends QuerySink::Range {
17-
override string getSinkType() { result = "RegexInjection" }
18-
}
17+
module RegexInjection {
18+
/**
19+
* A data flow sink for regular expression injection vulnerabilities.
20+
*/
21+
abstract class Sink extends QuerySink::Range {
22+
override string getSinkType() { result = "RegexInjection" }
23+
}
1924

20-
/**
21-
* A barrier for regular expression injection vulnerabilities.
22-
*/
23-
abstract class RegexInjectionBarrier extends DataFlow::Node { }
25+
/**
26+
* A barrier for regular expression injection vulnerabilities.
27+
*/
28+
abstract class Barrier extends DataFlow::Node { }
2429

25-
/** A sink for `a` in `Regex::new(a)` when `a` is not a literal. */
26-
private class NewRegexInjectionSink extends RegexInjectionSink {
27-
NewRegexInjectionSink() {
28-
exists(CallExprCfgNode call, PathExpr path |
29-
path = call.getFunction().getExpr() and
30-
path.getResolvedCrateOrigin() = "repo:https://github.com/rust-lang/regex:regex" and
31-
path.getResolvedPath() = "<crate::regex::string::Regex>::new" and
32-
this.asExpr() = call.getArgument(0) and
33-
not this.asExpr() instanceof LiteralExprCfgNode
34-
)
30+
/**
31+
* A sink for `a` in `Regex::new(a)` when `a` is not a literal.
32+
*/
33+
private class NewSink extends Sink {
34+
NewSink() {
35+
exists(CallExprCfgNode call, PathExpr path |
36+
path = call.getFunction().getExpr() and
37+
path.getResolvedCrateOrigin() = "repo:https://github.com/rust-lang/regex:regex" and
38+
path.getResolvedPath() = "<crate::regex::string::Regex>::new" and
39+
this.asExpr() = call.getArgument(0) and
40+
not this.asExpr() instanceof LiteralExprCfgNode
41+
)
42+
}
3543
}
36-
}
3744

38-
private class MadRegexInjectionSink extends RegexInjectionSink {
39-
MadRegexInjectionSink() { sinkNode(this, "regex-use") }
40-
}
45+
/**
46+
* A sink for regular expression injection from model data.
47+
*/
48+
private class ModelsAsDataSink extends Sink {
49+
ModelsAsDataSink() { sinkNode(this, "regex-use") }
50+
}
4151

42-
/**
43-
* A unit class for adding additional flow steps.
44-
*/
45-
class RegexInjectionAdditionalFlowStep extends Unit {
4652
/**
47-
* Holds if the step from `node1` to `node2` should be considered a flow
48-
* step for paths related to regular expression injection vulnerabilities.
53+
* A unit class for adding additional flow steps.
4954
*/
50-
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
51-
}
55+
class AdditionalFlowStep extends Unit {
56+
/**
57+
* Holds if the step from `node1` to `node2` should be considered a flow
58+
* step for paths related to regular expression injection vulnerabilities.
59+
*/
60+
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
61+
}
5262

53-
/**
54-
* An escape barrier for regular expression injection vulnerabilities.
55-
*/
56-
private class RegexInjectionDefaultBarrier extends RegexInjectionBarrier {
57-
RegexInjectionDefaultBarrier() {
58-
// A barrier is any call to a function named `escape`, in particular this
59-
// makes calls to `regex::escape` a barrier.
60-
this.asExpr()
61-
.getExpr()
62-
.(CallExpr)
63-
.getFunction()
64-
.(PathExpr)
65-
.getPath()
66-
.getSegment()
67-
.getIdentifier()
68-
.getText() = "escape"
63+
/**
64+
* An escape barrier for regular expression injection vulnerabilities.
65+
*/
66+
private class DefaultBarrier extends Barrier {
67+
DefaultBarrier() {
68+
// A barrier is any call to a function named `escape`, in particular this
69+
// makes calls to `regex::escape` a barrier.
70+
this.asExpr()
71+
.getExpr()
72+
.(CallExpr)
73+
.getFunction()
74+
.(PathExpr)
75+
.getPath()
76+
.getSegment()
77+
.getIdentifier()
78+
.getText() = "escape"
79+
}
6980
}
7081
}

rust/ql/src/queries/security/CWE-020/RegexInjection.ql

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,16 @@ private import codeql.rust.security.regex.RegexInjectionExtensions
2424
* A taint configuration for detecting regular expression injection vulnerabilities.
2525
*/
2626
module RegexInjectionConfig implements DataFlow::ConfigSig {
27+
import RegexInjection
28+
2729
predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource }
2830

29-
predicate isSink(DataFlow::Node sink) { sink instanceof RegexInjectionSink }
31+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
3032

31-
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof RegexInjectionBarrier }
33+
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof Barrier }
3234

3335
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
34-
any(RegexInjectionAdditionalFlowStep s).step(nodeFrom, nodeTo)
36+
any(AdditionalFlowStep s).step(nodeFrom, nodeTo)
3537
}
3638
}
3739

rust/ql/src/queries/security/CWE-089/SqlInjection.ql

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ import SqlInjectionFlow::PathGraph
2020
* A taint configuration for tainted data that reaches a SQL sink.
2121
*/
2222
module SqlInjectionConfig implements DataFlow::ConfigSig {
23-
predicate isSource(DataFlow::Node node) { node instanceof SqlInjection::Source }
23+
import SqlInjection
2424

25-
predicate isSink(DataFlow::Node node) { node instanceof SqlInjection::Sink }
25+
predicate isSource(DataFlow::Node node) { node instanceof Source }
2626

27-
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof SqlInjection::Barrier }
27+
predicate isSink(DataFlow::Node node) { node instanceof Sink }
28+
29+
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof Barrier }
2830
}
2931

3032
module SqlInjectionFlow = TaintTracking::Global<SqlInjectionConfig>;

rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,16 @@ import codeql.rust.security.CleartextTransmissionExtensions
2222
* transmitted over a network.
2323
*/
2424
module CleartextTransmissionConfig implements DataFlow::ConfigSig {
25-
predicate isSource(DataFlow::Node node) { node instanceof SensitiveData }
25+
import CleartextTransmission
2626

27-
predicate isSink(DataFlow::Node node) { node instanceof CleartextTransmissionSink }
27+
predicate isSource(DataFlow::Node node) { node instanceof Source }
2828

29-
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof CleartextTransmissionBarrier }
29+
predicate isSink(DataFlow::Node node) { node instanceof Sink }
30+
31+
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof Barrier }
3032

3133
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
32-
any(CleartextTransmissionAdditionalFlowStep s).step(nodeFrom, nodeTo)
34+
any(AdditionalFlowStep s).step(nodeFrom, nodeTo)
3335
}
3436

3537
predicate isBarrierIn(DataFlow::Node node) {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
private import codeql.rust.dataflow.DataFlow
22
private import codeql.rust.security.regex.RegexInjectionExtensions
33

4-
query predicate regexInjectionSink(DataFlow::Node node) { node instanceof RegexInjectionSink }
4+
query predicate regexInjectionSink(DataFlow::Node node) { node instanceof RegexInjection::Sink }

0 commit comments

Comments
 (0)