Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions rust/ql/lib/codeql/rust/Concepts.qll
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,29 @@ class ModeledRemoteSource extends RemoteSource::Range {
ModeledRemoteSource() { sourceNode(this, "remote") }
}

/**
* A data flow sink that is used in a query.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `QuerySink::Range` instead.
*/
final class QuerySink = QuerySink::Range;

/**
* Provides a class for modeling new query sinks.
*/
module QuerySink {
/**
* A data flow sink that is used in a query.
*/
abstract class Range extends DataFlow::Node {
/**
* Gets a string that describes the type of this sink (usually the query it applies to).
*/
abstract string getSinkType();
}
}

/**
* A data flow node that constructs a SQL statement (for later execution).
*
Expand Down
22 changes: 20 additions & 2 deletions rust/ql/lib/codeql/rust/dataflow/FlowSink.qll
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
/** Provides classes and predicates for defining flow sinks. */
/**
* Provides classes and predicates for defining flow sinks.
*
* Flow sinks defined here feed into data flow configurations as follows:
*
* ```text
* data from *.model.yml | QL extensions of FlowSink::Range
* v v
* FlowSink (associated with a models-as-data kind string)
* v
* sinkNode predicate | other QL defined sinks, for example using concepts
* v v
* various Sink classes for specific data flow configurations <- extending QuerySink
* ```
*
* New sinks should be defined using models-as-data, QL extensions of
* `FlowSink::Range`, or concepts. Data flow configurations should use the
* `sinkNode` predicate and/or concepts to define their sinks.
*/

private import rust
private import internal.FlowSummaryImpl as Impl
Expand All @@ -12,7 +30,7 @@ private module Sinks {

/** Provides the `Range` class used to define the extent of `FlowSink`. */
module FlowSink {
/** A flow source. */
/** A flow sink. */
abstract class Range extends Impl::Public::SinkElement {
bindingset[this]
Range() { any() }
Expand Down
26 changes: 25 additions & 1 deletion rust/ql/lib/codeql/rust/dataflow/FlowSource.qll
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@
/** Provides classes and predicates for defining flow sources. */
/**
* Provides classes and predicates for defining flow sources.
*
* Flow sources defined here feed into the `ActiveThreatModelSource` class and
* ultimately reach data flow configurations as follows:
*
* ```text
* data from *.model.yml | QL extensions of FlowSource::Range
* v v
* FlowSource (associated with a models-as-data kind string)
* v
* sourceNode predicate | (theoretically other QL defined sources)
* v v
* ThreatModelSource (associated with a threat model source type)
* v
* ActiveThreatModelSource (just the enabled sources)
* v
* various Source classes for specific data flow configurations
* ```
*
* New sources should be defined using models-as-data or QL extensions of
* `FlowSource::Range`. Data flow configurations on the other hand should use
* `ActiveThreatModelSource` to match sources enabled in the user
* configuration.
*/

private import rust
private import internal.FlowSummaryImpl as Impl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import rust
private import codeql.rust.dataflow.DataFlow
private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.security.SensitiveData
private import codeql.rust.Concepts

/**
* Provides default sources, sinks and barriers for detecting cleartext logging
Expand All @@ -21,7 +22,9 @@ module CleartextLogging {
/**
* A data flow sink for cleartext logging vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
abstract class Sink extends QuerySink::Range {
override string getSinkType() { result = "CleartextLogging" }
}

/**
* A barrier for cleartext logging vulnerabilities.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ module SqlInjection {
/**
* A data flow sink for SQL injection vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
abstract class Sink extends QuerySink::Range {
override string getSinkType() { result = "SqlInjection" }
}

/**
* A barrier for SQL injection vulnerabilities.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ module NormalHashFunction {
* data" vulnerabilities that applies to data that does not require computationally expensive
* hashing. That is, a broken or weak hashing algorithm.
*/
abstract class Sink extends DataFlow::Node {
abstract class Sink extends QuerySink::Range {
/**
* Gets the name of the weak hashing algorithm.
*/
Expand Down Expand Up @@ -76,6 +76,8 @@ module NormalHashFunction {
class WeakHashingOperationInputAsSink extends Sink {
Cryptography::HashingAlgorithm algorithm;

override string getSinkType() { result = "WeakSensitiveDataHashing" }

WeakHashingOperationInputAsSink() {
exists(Cryptography::CryptographicOperation operation |
algorithm.isWeak() and
Expand Down Expand Up @@ -114,7 +116,9 @@ module ComputationallyExpensiveHashFunction {
* hashing. That is, a broken or weak hashing algorithm or one that is not computationally
* expensive enough for password hashing.
*/
abstract class Sink extends DataFlow::Node {
abstract class Sink extends QuerySink::Range {
override string getSinkType() { result = "WeakSensitiveDataHashing" }

/**
* Gets the name of the weak hashing algorithm.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ private import rust
private import codeql.rust.dataflow.DataFlow
private import codeql.rust.controlflow.CfgNodes
private import codeql.rust.dataflow.FlowSink
private import codeql.rust.Concepts

/**
* A data flow sink for regular expression injection vulnerabilities.
*/
abstract class RegexInjectionSink extends DataFlow::Node { }
abstract class RegexInjectionSink extends QuerySink::Range {
override string getSinkType() { result = "RegexInjection" }
}

/**
* A barrier for regular expression injection vulnerabilities.
Expand Down
3 changes: 2 additions & 1 deletion rust/ql/src/queries/summary/QuerySinkCounts.ql
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@

import rust
import codeql.rust.dataflow.DataFlow
import codeql.rust.Concepts
import Stats

from string kind, int num
where num = strictcount(DataFlow::Node n | getAQuerySinkKind(n) = kind)
where num = strictcount(QuerySink s | s.getSinkType() = kind)
select kind, num
5 changes: 3 additions & 2 deletions rust/ql/src/queries/summary/QuerySinks.ql
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

import rust
import codeql.rust.dataflow.DataFlow
import codeql.rust.Concepts
import Stats

from DataFlow::Node n
select n, "Sink for " + strictconcat(getAQuerySinkKind(n), ", ") + "."
from QuerySink s
select s, "Sink for " + concat(s.getSinkType(), ", ") + "."
17 changes: 6 additions & 11 deletions rust/ql/src/queries/summary/Stats.qll
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ private import codeql.rust.dataflow.internal.TaintTrackingImpl
private import codeql.rust.internal.AstConsistency as AstConsistency
private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency
private import codeql.rust.dataflow.internal.DataFlowConsistency as DataFlowConsistency
private import codeql.rust.security.SqlInjectionExtensions
private import codeql.rust.Concepts
// import all query extensions files, so that all extensions of `QuerySink` are found
private import codeql.rust.security.CleartextLoggingExtensions
private import codeql.rust.security.SqlInjectionExtensions
private import codeql.rust.security.WeakSensitiveDataHashingExtensions
private import codeql.rust.security.regex.RegexInjectionExtensions

/**
* Gets a count of the total number of lines of code in the database.
Expand Down Expand Up @@ -55,16 +59,7 @@ int getTaintEdgesCount() {
)
}

/**
* Gets a kind of query for which `n` is a sink (if any).
*/
string getAQuerySinkKind(DataFlow::Node n) {
n instanceof SqlInjection::Sink and result = "SqlInjection"
or
n instanceof CleartextLogging::Sink and result = "CleartextLogging"
}

/**
* Gets a count of the total number of query sinks in the database.
*/
int getQuerySinksCount() { result = count(DataFlow::Node n | exists(getAQuerySinkKind(n))) }
int getQuerySinksCount() { result = count(QuerySink s) }