Skip to content

Commit 4924a0f

Browse files
committed
Rust: Introduce a QuerySink class, common to all query sinks.
1 parent dc7d7f1 commit 4924a0f

File tree

7 files changed

+39
-16
lines changed

7 files changed

+39
-16
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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* v
1010
* `sinkNode` predicate | other QL defined sinks, for example using concepts
1111
* v v
12-
* various `Sink` classes for specific data flow configurations
12+
* various `Sink` classes for specific data flow configurations <- extending `QuerySink`
1313
*
1414
* New sinks should be defined using models-as-data, QL extensions of
1515
* `FlowSink::Range`, or concepts. Data flow configurations should use the

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/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: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ 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.Concepts
13+
// import all query extensions files, so that all extensions of `QuerySink` are found
1214
private import codeql.rust.security.SqlInjectionExtensions
1315
private import codeql.rust.security.CleartextLoggingExtensions
1416

@@ -55,16 +57,7 @@ int getTaintEdgesCount() {
5557
)
5658
}
5759

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-
6760
/**
6861
* Gets a count of the total number of query sinks in the database.
6962
*/
70-
int getQuerySinksCount() { result = count(DataFlow::Node n | exists(getAQuerySinkKind(n))) }
63+
int getQuerySinksCount() { result = count(QuerySink s) }

0 commit comments

Comments
 (0)