Skip to content

Commit 9eeae71

Browse files
authored
Merge pull request #18712 from GeekMasher/rust-db-sources
Rust: Add Database Sources + tokio-postgres support
2 parents 0b2e307 + be883ad commit 9eeae71

File tree

4 files changed

+63
-4
lines changed

4 files changed

+63
-4
lines changed

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

+26
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,32 @@ class ModeledEnvironmentSource extends EnvironmentSource::Range {
100100
ModeledEnvironmentSource() { sourceNode(this, "environment-source") }
101101
}
102102

103+
/**
104+
* A data flow source corresponding to the program's database reads.
105+
*/
106+
final class DatabaseSource = DatabaseSource::Range;
107+
108+
/**
109+
* Provides a class for modeling new sources for the program's database reads.
110+
*/
111+
module DatabaseSource {
112+
/**
113+
* A data flow source corresponding to the program's database reads.
114+
*/
115+
abstract class Range extends ThreatModelSource::Range {
116+
override string getThreatModel() { result = "database" }
117+
118+
override string getSourceType() { result = "DatabaseSource" }
119+
}
120+
}
121+
122+
/**
123+
* An externally modeled source for data from the program's database.
124+
*/
125+
class ModeledDatabaseSource extends DatabaseSource::Range {
126+
ModeledDatabaseSource() { sourceNode(this, "database") }
127+
}
128+
103129
/**
104130
* A data flow source for remote (network) data.
105131
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/rust-all
4+
extensible: sinkModel
5+
data:
6+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::client::Client>::execute", "Argument[0]", "sql-injection", "manual"]
7+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::client::Client>::batch_execute", "Argument[0]", "sql-injection", "manual"]
8+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::client::Client>::execute_raw", "Argument[0]", "sql-injection", "manual"]
9+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::client::Client>::prepare", "Argument[0]", "sql-injection", "manual"]
10+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::client::Client>::prepare_typed", "Argument[0]", "sql-injection", "manual"]
11+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::client::Client>::query", "Argument[0]", "sql-injection", "manual"]
12+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::client::Client>::query_opt", "Argument[0]", "sql-injection", "manual"]
13+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::client::Client>::query_raw", "Argument[0]", "sql-injection", "manual"]
14+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::client::Client>::query_typed", "Argument[0]", "sql-injection", "manual"]
15+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::client::Client>::query_typed_raw", "Argument[0]", "sql-injection", "manual"]
16+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::client::Client>::simple_query", "Argument[0]", "sql-injection", "manual"]
17+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::client::Client>::simple_query_raw", "Argument[0]", "sql-injection", "manual"]
18+
19+
- addsTo:
20+
pack: codeql/rust-all
21+
extensible: sourceModel
22+
data:
23+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::row::Row>::get", "ReturnValue", "database", "manual"]
24+
- ["repo:https://github.com/sfackler/rust-postgres:tokio-postgres", "<crate::row::Row>::try_get", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "database", "manual"]

rust/ql/test/library-tests/frameworks/postgres/Postgres.ql

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import rust
2+
import codeql.rust.Concepts
23
import codeql.rust.security.SqlInjectionExtensions
34
import utils.test.InlineExpectationsTest
45

56
module PostgresTest implements TestSig {
6-
string getARelevantTag() { result = "sql-sink" }
7+
string getARelevantTag() { result = ["sql-sink", "database-read"] }
78

89
predicate hasActualResult(Location location, string element, string tag, string value) {
910
exists(SqlInjection::Sink sink |
@@ -13,6 +14,14 @@ module PostgresTest implements TestSig {
1314
tag = "sql-sink" and
1415
value = ""
1516
)
17+
or
18+
exists(ModeledDatabaseSource source |
19+
location = source.getLocation() and
20+
location.getFile().getBaseName() != "" and
21+
element = source.toString() and
22+
tag = "database-read" and
23+
value = ""
24+
)
1625
}
1726
}
1827

rust/ql/test/library-tests/frameworks/postgres/main.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
3333
// conn.query_typed_raw(query.as_str(), &[])?;
3434

3535
for row in &conn.query("SELECT id, name, age FROM person", &[])? { // $ sql-sink
36-
let id: i32 = row.get("id");
37-
let name: &str = row.get("name");
38-
let age: i32 = row.get("age");
36+
let id: i32 = row.get("id"); // $ database-read
37+
let name: &str = row.try_get("name")?; // $ database-read
38+
let age: i32 = row.try_get("age").unwrap(); // $ database-read
3939
println!("found person: {} {} {}", id, name, age);
4040
}
4141

0 commit comments

Comments
 (0)