Skip to content

Commit 1aa2236

Browse files
authored
Merge pull request #18977 from geoffw0/sourcesinkdoc
Rust: Source and sink doc / tidy up
2 parents 72c7024 + 0df652b commit 1aa2236

File tree

10 files changed

+96
-22
lines changed

10 files changed

+96
-22
lines changed

rust/ql/lib/codeql/rust/Concepts.qll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,29 @@ class ModeledRemoteSource extends RemoteSource::Range {
152152
ModeledRemoteSource() { sourceNode(this, "remote") }
153153
}
154154

155+
/**
156+
* A data flow sink that is used in a query.
157+
*
158+
* Extend this class to refine existing API models. If you want to model new APIs,
159+
* extend `QuerySink::Range` instead.
160+
*/
161+
final class QuerySink = QuerySink::Range;
162+
163+
/**
164+
* Provides a class for modeling new query sinks.
165+
*/
166+
module QuerySink {
167+
/**
168+
* A data flow sink that is used in a query.
169+
*/
170+
abstract class Range extends DataFlow::Node {
171+
/**
172+
* Gets a string that describes the type of this sink (usually the query it applies to).
173+
*/
174+
abstract string getSinkType();
175+
}
176+
}
177+
155178
/**
156179
* A data flow node that constructs a SQL statement (for later execution).
157180
*

rust/ql/lib/codeql/rust/dataflow/FlowSink.qll

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
1-
/** Provides classes and predicates for defining flow sinks. */
1+
/**
2+
* Provides classes and predicates for defining flow sinks.
3+
*
4+
* Flow sinks defined here feed into data flow configurations as follows:
5+
*
6+
* ```text
7+
* data from *.model.yml | QL extensions of FlowSink::Range
8+
* v v
9+
* FlowSink (associated with a models-as-data kind string)
10+
* v
11+
* sinkNode predicate | other QL defined sinks, for example using concepts
12+
* v v
13+
* various Sink classes for specific data flow configurations <- extending QuerySink
14+
* ```
15+
*
16+
* New sinks should be defined using models-as-data, QL extensions of
17+
* `FlowSink::Range`, or concepts. Data flow configurations should use the
18+
* `sinkNode` predicate and/or concepts to define their sinks.
19+
*/
220

321
private import rust
422
private import internal.FlowSummaryImpl as Impl
@@ -12,7 +30,7 @@ private module Sinks {
1230

1331
/** Provides the `Range` class used to define the extent of `FlowSink`. */
1432
module FlowSink {
15-
/** A flow source. */
33+
/** A flow sink. */
1634
abstract class Range extends Impl::Public::SinkElement {
1735
bindingset[this]
1836
Range() { any() }

rust/ql/lib/codeql/rust/dataflow/FlowSource.qll

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
1-
/** Provides classes and predicates for defining flow sources. */
1+
/**
2+
* Provides classes and predicates for defining flow sources.
3+
*
4+
* Flow sources defined here feed into the `ActiveThreatModelSource` class and
5+
* ultimately reach data flow configurations as follows:
6+
*
7+
* ```text
8+
* data from *.model.yml | QL extensions of FlowSource::Range
9+
* v v
10+
* FlowSource (associated with a models-as-data kind string)
11+
* v
12+
* sourceNode predicate | (theoretically other QL defined sources)
13+
* v v
14+
* ThreatModelSource (associated with a threat model source type)
15+
* v
16+
* ActiveThreatModelSource (just the enabled sources)
17+
* v
18+
* various Source classes for specific data flow configurations
19+
* ```
20+
*
21+
* New sources should be defined using models-as-data or QL extensions of
22+
* `FlowSource::Range`. Data flow configurations on the other hand should use
23+
* `ActiveThreatModelSource` to match sources enabled in the user
24+
* configuration.
25+
*/
226

327
private import rust
428
private import internal.FlowSummaryImpl as Impl

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import rust
77
private import codeql.rust.dataflow.DataFlow
88
private import codeql.rust.dataflow.internal.DataFlowImpl
99
private import codeql.rust.security.SensitiveData
10+
private import codeql.rust.Concepts
1011

1112
/**
1213
* Provides default sources, sinks and barriers for detecting cleartext logging
@@ -21,7 +22,9 @@ module CleartextLogging {
2122
/**
2223
* A data flow sink for cleartext logging vulnerabilities.
2324
*/
24-
abstract class Sink extends DataFlow::Node { }
25+
abstract class Sink extends QuerySink::Range {
26+
override string getSinkType() { result = "CleartextLogging" }
27+
}
2528

2629
/**
2730
* A barrier for cleartext logging vulnerabilities.

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ module SqlInjection {
2323
/**
2424
* A data flow sink for SQL injection vulnerabilities.
2525
*/
26-
abstract class Sink extends DataFlow::Node { }
26+
abstract class Sink extends QuerySink::Range {
27+
override string getSinkType() { result = "SqlInjection" }
28+
}
2729

2830
/**
2931
* A barrier for SQL injection vulnerabilities.

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ module NormalHashFunction {
4343
* data" vulnerabilities that applies to data that does not require computationally expensive
4444
* hashing. That is, a broken or weak hashing algorithm.
4545
*/
46-
abstract class Sink extends DataFlow::Node {
46+
abstract class Sink extends QuerySink::Range {
4747
/**
4848
* Gets the name of the weak hashing algorithm.
4949
*/
@@ -76,6 +76,8 @@ module NormalHashFunction {
7676
class WeakHashingOperationInputAsSink extends Sink {
7777
Cryptography::HashingAlgorithm algorithm;
7878

79+
override string getSinkType() { result = "WeakSensitiveDataHashing" }
80+
7981
WeakHashingOperationInputAsSink() {
8082
exists(Cryptography::CryptographicOperation operation |
8183
algorithm.isWeak() and
@@ -114,7 +116,9 @@ module ComputationallyExpensiveHashFunction {
114116
* hashing. That is, a broken or weak hashing algorithm or one that is not computationally
115117
* expensive enough for password hashing.
116118
*/
117-
abstract class Sink extends DataFlow::Node {
119+
abstract class Sink extends QuerySink::Range {
120+
override string getSinkType() { result = "WeakSensitiveDataHashing" }
121+
118122
/**
119123
* Gets the name of the weak hashing algorithm.
120124
*/

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@ private import rust
88
private import codeql.rust.dataflow.DataFlow
99
private import codeql.rust.controlflow.CfgNodes
1010
private import codeql.rust.dataflow.FlowSink
11+
private import codeql.rust.Concepts
1112

1213
/**
1314
* A data flow sink for regular expression injection vulnerabilities.
1415
*/
15-
abstract class RegexInjectionSink extends DataFlow::Node { }
16+
abstract class RegexInjectionSink extends QuerySink::Range {
17+
override string getSinkType() { result = "RegexInjection" }
18+
}
1619

1720
/**
1821
* A barrier for regular expression injection vulnerabilities.

rust/ql/src/queries/summary/QuerySinkCounts.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010

1111
import rust
1212
import codeql.rust.dataflow.DataFlow
13+
import codeql.rust.Concepts
1314
import Stats
1415

1516
from string kind, int num
16-
where num = strictcount(DataFlow::Node n | getAQuerySinkKind(n) = kind)
17+
where num = strictcount(QuerySink s | s.getSinkType() = kind)
1718
select kind, num

rust/ql/src/queries/summary/QuerySinks.ql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111

1212
import rust
1313
import codeql.rust.dataflow.DataFlow
14+
import codeql.rust.Concepts
1415
import Stats
1516

16-
from DataFlow::Node n
17-
select n, "Sink for " + strictconcat(getAQuerySinkKind(n), ", ") + "."
17+
from QuerySink s
18+
select s, "Sink for " + concat(s.getSinkType(), ", ") + "."

rust/ql/src/queries/summary/Stats.qll

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@ private import codeql.rust.dataflow.internal.TaintTrackingImpl
99
private import codeql.rust.internal.AstConsistency as AstConsistency
1010
private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency
1111
private import codeql.rust.dataflow.internal.DataFlowConsistency as DataFlowConsistency
12-
private import codeql.rust.security.SqlInjectionExtensions
12+
private import codeql.rust.Concepts
13+
// import all query extensions files, so that all extensions of `QuerySink` are found
1314
private import codeql.rust.security.CleartextLoggingExtensions
15+
private import codeql.rust.security.SqlInjectionExtensions
16+
private import codeql.rust.security.WeakSensitiveDataHashingExtensions
17+
private import codeql.rust.security.regex.RegexInjectionExtensions
1418

1519
/**
1620
* Gets a count of the total number of lines of code in the database.
@@ -55,16 +59,7 @@ int getTaintEdgesCount() {
5559
)
5660
}
5761

58-
/**
59-
* Gets a kind of query for which `n` is a sink (if any).
60-
*/
61-
string getAQuerySinkKind(DataFlow::Node n) {
62-
n instanceof SqlInjection::Sink and result = "SqlInjection"
63-
or
64-
n instanceof CleartextLogging::Sink and result = "CleartextLogging"
65-
}
66-
6762
/**
6863
* Gets a count of the total number of query sinks in the database.
6964
*/
70-
int getQuerySinksCount() { result = count(DataFlow::Node n | exists(getAQuerySinkKind(n))) }
65+
int getQuerySinksCount() { result = count(QuerySink s) }

0 commit comments

Comments
 (0)