Skip to content

Commit c7c6924

Browse files
committed
Rust: Implement query, source/sink/barrier classes and concepts. All of this is framework, nothing is concretely modelled yet.
1 parent 6a7fb06 commit c7c6924

File tree

5 files changed

+212
-4
lines changed

5 files changed

+212
-4
lines changed

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

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/**
2+
* Provides abstract classes representing generic concepts such as file system
3+
* access or system command execution, for which individual framework libraries
4+
* provide concrete subclasses.
5+
*/
6+
7+
private import codeql.rust.dataflow.DataFlow
8+
private import codeql.threatmodels.ThreatModels
9+
10+
/**
11+
* A data flow source for a specific threat-model.
12+
*
13+
* Extend this class to refine existing API models. If you want to model new APIs,
14+
* extend `ThreatModelSource::Range` instead.
15+
*/
16+
class ThreatModelSource extends DataFlow::Node instanceof ThreatModelSource::Range {
17+
/**
18+
* Gets a string that represents the source kind with respect to threat modeling.
19+
*
20+
* See
21+
* - https://github.com/github/codeql/blob/main/docs/codeql/reusables/threat-model-description.rst
22+
* - https://github.com/github/codeql/blob/main/shared/threat-models/ext/threat-model-grouping.model.yml
23+
*/
24+
string getThreatModel() { result = super.getThreatModel() }
25+
26+
/**
27+
* Gets a string that describes the type of this threat-model source.
28+
*/
29+
string getSourceType() { result = super.getSourceType() }
30+
}
31+
32+
/**
33+
* Provides a class for modeling new sources for specific threat-models.
34+
*/
35+
module ThreatModelSource {
36+
/**
37+
* A data flow source, for a specific threat-model.
38+
*/
39+
abstract class Range extends DataFlow::Node {
40+
/**
41+
* Gets a string that represents the source kind with respect to threat modeling.
42+
*/
43+
abstract string getThreatModel();
44+
45+
/**
46+
* Gets a string that describes the type of this threat-model source.
47+
*/
48+
abstract string getSourceType();
49+
}
50+
}
51+
52+
/**
53+
* A data flow source that is enabled in the current threat model configuration.
54+
*/
55+
class ActiveThreatModelSource extends ThreatModelSource {
56+
ActiveThreatModelSource() {
57+
currentThreatModel(this.getThreatModel())
58+
}
59+
}
60+
61+
/**
62+
* A data-flow node that constructs a SQL statement.
63+
*
64+
* Often, it is worthy of an alert if a SQL statement is constructed such that
65+
* executing it would be a security risk.
66+
*
67+
* If it is important that the SQL statement is executed, use `SqlExecution`.
68+
*
69+
* Extend this class to refine existing API models. If you want to model new APIs,
70+
* extend `SqlConstruction::Range` instead.
71+
*/
72+
class SqlConstruction extends DataFlow::Node instanceof SqlConstruction::Range {
73+
/**
74+
* Gets the argument that specifies the SQL statements to be constructed.
75+
*/
76+
DataFlow::Node getSql() { result = super.getSql() }
77+
}
78+
79+
/**
80+
* Provides a class for modeling new SQL execution APIs.
81+
*/
82+
module SqlConstruction {
83+
/**
84+
* A data-flow node that constructs a SQL statement.
85+
*/
86+
abstract class Range extends DataFlow::Node {
87+
/**
88+
* Gets the argument that specifies the SQL statements to be constructed.
89+
*/
90+
abstract DataFlow::Node getSql();
91+
}
92+
}
93+
94+
/**
95+
* A data-flow node that executes SQL statements.
96+
*
97+
* If the context of interest is such that merely constructing a SQL statement
98+
* would be valuable to report, consider using `SqlConstruction`.
99+
*
100+
* Extend this class to refine existing API models. If you want to model new APIs,
101+
* extend `SqlExecution::Range` instead.
102+
*/
103+
class SqlExecution extends DataFlow::Node instanceof SqlExecution::Range {
104+
/**
105+
* Gets the argument that specifies the SQL statements to be executed.
106+
*/
107+
DataFlow::Node getSql() { result = super.getSql() }
108+
}
109+
110+
/**
111+
* Provides a class for modeling new SQL execution APIs.
112+
*/
113+
module SqlExecution {
114+
/**
115+
* A data-flow node that executes SQL statements.
116+
*/
117+
abstract class Range extends DataFlow::Node {
118+
/**
119+
* Gets the argument that specifies the SQL statements to be executed.
120+
*/
121+
abstract DataFlow::Node getSql();
122+
}
123+
}
124+
125+
/**
126+
* A data-flow node that performs SQL sanitization.
127+
*/
128+
class SqlSanitization extends DataFlow::Node instanceof SqlSanitization::Range { }
129+
130+
/**
131+
* Provides a class for modeling new SQL sanitization APIs.
132+
*/
133+
module SqlSanitization {
134+
/**
135+
* A data-flow node that performs SQL sanitization.
136+
*/
137+
abstract class Range extends DataFlow::Node { }
138+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* Provides classes and predicates for reasoning about database
3+
* queries built from user-controlled sources (that is, SQL injection
4+
* vulnerabilities).
5+
*/
6+
7+
import rust
8+
private import codeql.rust.dataflow.DataFlow
9+
private import codeql.rust.Concepts
10+
private import codeql.util.Unit
11+
12+
/**
13+
* Provides default sources, sinks and barriers for detecting SQL injection
14+
* vulnerabilities, as well as extension points for adding your own.
15+
*/
16+
module SqlInjection {
17+
/**
18+
* A data flow source for SQL injection vulnerabilities.
19+
*/
20+
abstract class Source extends DataFlow::Node { }
21+
22+
/**
23+
* A data flow sink for SQL injection vulnerabilities.
24+
*/
25+
abstract class Sink extends DataFlow::Node { }
26+
27+
/**
28+
* A barrier for SQL injection vulnerabilities.
29+
*/
30+
abstract class Barrier extends DataFlow::Node { }
31+
32+
/**
33+
* An active threat-model source, considered as a flow source.
34+
*/
35+
private class ActiveThreatModelSourceAsSource extends Source, ActiveThreatModelSource { }
36+
37+
/**
38+
* A flow sink that is the statement of an SQL construction.
39+
*/
40+
class SqlConstructionAsSink extends Sink {
41+
SqlConstructionAsSink() { this = any(SqlConstruction c).getSql() }
42+
}
43+
44+
/**
45+
* A flow sink that is the statement of an SQL execution.
46+
*/
47+
class SqlExecutionAsSink extends Sink {
48+
SqlExecutionAsSink() { this = any(SqlExecution e).getSql() }
49+
}
50+
}

rust/ql/lib/qlpack.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ dependencies:
88
codeql/controlflow: ${workspace}
99
codeql/dataflow: ${workspace}
1010
codeql/regex: ${workspace}
11+
codeql/threat-models: ${workspace}
1112
codeql/mad: ${workspace}
1213
codeql/ssa: ${workspace}
1314
codeql/tutorial: ${workspace}

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,29 @@
1010
* external/cwe/cwe-089
1111
*/
1212

13+
import rust
1314
import codeql.rust.dataflow.DataFlow
14-
/*import codeql.rust.security.SqlInjectionQuery
15+
import codeql.rust.dataflow.TaintTracking
16+
import codeql.rust.security.SqlInjectionExtensions
1517
import SqlInjectionFlow::PathGraph
1618

19+
/**
20+
* A taint configuration for tainted data that reaches a SQL sink.
21+
*/
22+
module SqlInjectionConfig implements DataFlow::ConfigSig {
23+
predicate isSource(DataFlow::Node node) { node instanceof SqlInjection::Source }
24+
25+
predicate isSink(DataFlow::Node node) { node instanceof SqlInjection::Sink }
26+
27+
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof SqlInjection::Barrier }
28+
}
29+
30+
/**
31+
* Detect taint flow of tainted data that reaches a SQL sink.
32+
*/
33+
module SqlInjectionFlow = TaintTracking::Global<SqlInjectionConfig>;
34+
1735
from SqlInjectionFlow::PathNode sourceNode, SqlInjectionFlow::PathNode sinkNode
1836
where SqlInjectionFlow::flowPath(sourceNode, sinkNode)
1937
select sinkNode.getNode(), sourceNode, sinkNode, "This query depends on a $@.",
2038
sourceNode.getNode(), "user-provided value"
21-
*/
22-
select 0
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
| 0 |
1+
#select
2+
edges
3+
nodes
4+
subpaths

0 commit comments

Comments
 (0)