Skip to content

Commit

Permalink
Rust: Implement query, source/sink/barrier classes and concepts. All …
Browse files Browse the repository at this point in the history
…of this is framework, nothing is concretely modelled yet.
  • Loading branch information
geoffw0 committed Nov 19, 2024
1 parent 6a7fb06 commit c7c6924
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 4 deletions.
138 changes: 138 additions & 0 deletions rust/ql/lib/codeql/rust/Concepts.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/**
* Provides abstract classes representing generic concepts such as file system
* access or system command execution, for which individual framework libraries
* provide concrete subclasses.
*/

private import codeql.rust.dataflow.DataFlow
private import codeql.threatmodels.ThreatModels

/**
* A data flow source for a specific threat-model.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `ThreatModelSource::Range` instead.
*/
class ThreatModelSource extends DataFlow::Node instanceof ThreatModelSource::Range {
/**
* Gets a string that represents the source kind with respect to threat modeling.
*
* See
* - https://github.com/github/codeql/blob/main/docs/codeql/reusables/threat-model-description.rst
* - https://github.com/github/codeql/blob/main/shared/threat-models/ext/threat-model-grouping.model.yml
*/
string getThreatModel() { result = super.getThreatModel() }

/**
* Gets a string that describes the type of this threat-model source.
*/
string getSourceType() { result = super.getSourceType() }
}

/**
* Provides a class for modeling new sources for specific threat-models.
*/
module ThreatModelSource {
/**
* A data flow source, for a specific threat-model.
*/
abstract class Range extends DataFlow::Node {
/**
* Gets a string that represents the source kind with respect to threat modeling.
*/
abstract string getThreatModel();

/**
* Gets a string that describes the type of this threat-model source.
*/
abstract string getSourceType();
}
}

/**
* A data flow source that is enabled in the current threat model configuration.
*/
class ActiveThreatModelSource extends ThreatModelSource {
ActiveThreatModelSource() {
currentThreatModel(this.getThreatModel())
}
}

/**
* A data-flow node that constructs a SQL statement.
*
* Often, it is worthy of an alert if a SQL statement is constructed such that
* executing it would be a security risk.
*
* If it is important that the SQL statement is executed, use `SqlExecution`.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `SqlConstruction::Range` instead.
*/
class SqlConstruction extends DataFlow::Node instanceof SqlConstruction::Range {
/**
* Gets the argument that specifies the SQL statements to be constructed.
*/
DataFlow::Node getSql() { result = super.getSql() }
}

/**
* Provides a class for modeling new SQL execution APIs.
*/
module SqlConstruction {
/**
* A data-flow node that constructs a SQL statement.
*/
abstract class Range extends DataFlow::Node {
/**
* Gets the argument that specifies the SQL statements to be constructed.
*/
abstract DataFlow::Node getSql();
}
}

/**
* A data-flow node that executes SQL statements.
*
* If the context of interest is such that merely constructing a SQL statement
* would be valuable to report, consider using `SqlConstruction`.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `SqlExecution::Range` instead.
*/
class SqlExecution extends DataFlow::Node instanceof SqlExecution::Range {
/**
* Gets the argument that specifies the SQL statements to be executed.
*/
DataFlow::Node getSql() { result = super.getSql() }
}

/**
* Provides a class for modeling new SQL execution APIs.
*/
module SqlExecution {
/**
* A data-flow node that executes SQL statements.
*/
abstract class Range extends DataFlow::Node {
/**
* Gets the argument that specifies the SQL statements to be executed.
*/
abstract DataFlow::Node getSql();
}
}

/**
* A data-flow node that performs SQL sanitization.
*/
class SqlSanitization extends DataFlow::Node instanceof SqlSanitization::Range { }

/**
* Provides a class for modeling new SQL sanitization APIs.
*/
module SqlSanitization {
/**
* A data-flow node that performs SQL sanitization.
*/
abstract class Range extends DataFlow::Node { }
}
50 changes: 50 additions & 0 deletions rust/ql/lib/codeql/rust/security/SqlInjectionExtensions.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Provides classes and predicates for reasoning about database
* queries built from user-controlled sources (that is, SQL injection
* vulnerabilities).
*/

import rust
private import codeql.rust.dataflow.DataFlow
private import codeql.rust.Concepts
private import codeql.util.Unit

/**
* Provides default sources, sinks and barriers for detecting SQL injection
* vulnerabilities, as well as extension points for adding your own.
*/
module SqlInjection {
/**
* A data flow source for SQL injection vulnerabilities.
*/
abstract class Source extends DataFlow::Node { }

/**
* A data flow sink for SQL injection vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }

/**
* A barrier for SQL injection vulnerabilities.
*/
abstract class Barrier extends DataFlow::Node { }

/**
* An active threat-model source, considered as a flow source.
*/
private class ActiveThreatModelSourceAsSource extends Source, ActiveThreatModelSource { }

/**
* A flow sink that is the statement of an SQL construction.
*/
class SqlConstructionAsSink extends Sink {
SqlConstructionAsSink() { this = any(SqlConstruction c).getSql() }
}

/**
* A flow sink that is the statement of an SQL execution.
*/
class SqlExecutionAsSink extends Sink {
SqlExecutionAsSink() { this = any(SqlExecution e).getSql() }
}
}
1 change: 1 addition & 0 deletions rust/ql/lib/qlpack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dependencies:
codeql/controlflow: ${workspace}
codeql/dataflow: ${workspace}
codeql/regex: ${workspace}
codeql/threat-models: ${workspace}
codeql/mad: ${workspace}
codeql/ssa: ${workspace}
codeql/tutorial: ${workspace}
Expand Down
22 changes: 19 additions & 3 deletions rust/ql/src/queries/security/CWE-089/SqlInjection.ql
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,29 @@
* external/cwe/cwe-089
*/

import rust
import codeql.rust.dataflow.DataFlow
/*import codeql.rust.security.SqlInjectionQuery
import codeql.rust.dataflow.TaintTracking
import codeql.rust.security.SqlInjectionExtensions
import SqlInjectionFlow::PathGraph

/**
* A taint configuration for tainted data that reaches a SQL sink.
*/
module SqlInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node instanceof SqlInjection::Source }

predicate isSink(DataFlow::Node node) { node instanceof SqlInjection::Sink }

predicate isBarrier(DataFlow::Node barrier) { barrier instanceof SqlInjection::Barrier }
}

/**
* Detect taint flow of tainted data that reaches a SQL sink.
*/
module SqlInjectionFlow = TaintTracking::Global<SqlInjectionConfig>;

from SqlInjectionFlow::PathNode sourceNode, SqlInjectionFlow::PathNode sinkNode
where SqlInjectionFlow::flowPath(sourceNode, sinkNode)
select sinkNode.getNode(), sourceNode, sinkNode, "This query depends on a $@.",
sourceNode.getNode(), "user-provided value"

Check warning

Code scanning / CodeQL

Consistent alert message Warning

The rust/sql-injection query does not have the same alert message as cs, py, rb.
*/
select 0
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
| 0 |
#select
edges
nodes
subpaths

0 comments on commit c7c6924

Please sign in to comment.