From 3fa93e5ca9d35a71603b6180e008a36ff9375c8c Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Nov 2024 19:35:24 +0000 Subject: [PATCH 01/17] Rust: Add rust/summary/taint-sources query. --- rust/ql/src/queries/summary/TaintSources.ql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 rust/ql/src/queries/summary/TaintSources.ql diff --git a/rust/ql/src/queries/summary/TaintSources.ql b/rust/ql/src/queries/summary/TaintSources.ql new file mode 100644 index 000000000000..2e1bc7205e27 --- /dev/null +++ b/rust/ql/src/queries/summary/TaintSources.ql @@ -0,0 +1,17 @@ +/** + * @name Taint Sources + * @description List all sources of untrusted input that have been idenfitied + * in the database. + * @kind problem + * @problem.severity info + * @id rust/summary/taint-sources + * @tags summary + */ + +import rust +import codeql.rust.Concepts + +from ThreatModelSource s, string defaultString +where + if s instanceof ActiveThreatModelSource then defaultString = ", DEFAULT" else defaultString = "" +select s, s.getSourceType() + " (" + s.getThreatModel() + defaultString + ")" From ca424d1e61ed1fb1e10610071a24e9a1bc2e1a33 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 20 Nov 2024 16:36:03 +0000 Subject: [PATCH 02/17] Rust: Add a count of flow sources to rust/summary/summary-statistics. --- rust/ql/src/queries/summary/SummaryStats.ql | 5 +++++ rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 2 ++ 2 files changed, 7 insertions(+) diff --git a/rust/ql/src/queries/summary/SummaryStats.ql b/rust/ql/src/queries/summary/SummaryStats.ql index 3f24eb50d196..b453d80e5e00 100644 --- a/rust/ql/src/queries/summary/SummaryStats.ql +++ b/rust/ql/src/queries/summary/SummaryStats.ql @@ -7,6 +7,7 @@ */ import rust +import codeql.rust.Concepts import codeql.rust.Diagnostics import Stats @@ -37,4 +38,8 @@ where key = "Inconsistencies - CFG" and value = getTotalCfgInconsistencies() or key = "Inconsistencies - data flow" and value = getTotalDataFlowInconsistencies() + or + key = "Taint sources - total" and value = count(ThreatModelSource s) + or + key = "Taint sources - active" and value = count(ActiveThreatModelSource s) select key, value diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index aeba0ac1ee6c..69be8e0c6d05 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -10,3 +10,5 @@ | Inconsistencies - data flow | 0 | | Lines of code extracted | 59 | | Lines of user code extracted | 59 | +| Taint sources - active | 0 | +| Taint sources - total | 0 | From a85ad4ec294df25fe44acf0d60e493131be07273 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 Nov 2024 21:34:16 +0000 Subject: [PATCH 03/17] Rust: Add a dataflow/sources test. --- .../dataflow/sources/TaintSources.expected | 0 .../dataflow/sources/TaintSources.qlref | 2 + .../dataflow/sources/options.yml | 3 + .../library-tests/dataflow/sources/reqwest.rs | 36 ++++++++++ .../library-tests/dataflow/sources/test.rs | 70 +++++++++++++++++++ 5 files changed, 111 insertions(+) create mode 100644 rust/ql/test/library-tests/dataflow/sources/TaintSources.expected create mode 100644 rust/ql/test/library-tests/dataflow/sources/TaintSources.qlref create mode 100644 rust/ql/test/library-tests/dataflow/sources/options.yml create mode 100644 rust/ql/test/library-tests/dataflow/sources/reqwest.rs create mode 100644 rust/ql/test/library-tests/dataflow/sources/test.rs diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.qlref b/rust/ql/test/library-tests/dataflow/sources/TaintSources.qlref new file mode 100644 index 000000000000..3f6de4d0e4e3 --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/sources/TaintSources.qlref @@ -0,0 +1,2 @@ +query: queries/summary/TaintSources.ql +postprocess: utils/InlineExpectationsTestQuery.ql diff --git a/rust/ql/test/library-tests/dataflow/sources/options.yml b/rust/ql/test/library-tests/dataflow/sources/options.yml new file mode 100644 index 000000000000..3885768c7fa9 --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/sources/options.yml @@ -0,0 +1,3 @@ +qltest_cargo_check: true +qltest_dependencies: + - reqwest = { version = "0.12.9", features = ["blocking"] } diff --git a/rust/ql/test/library-tests/dataflow/sources/reqwest.rs b/rust/ql/test/library-tests/dataflow/sources/reqwest.rs new file mode 100644 index 000000000000..3e8f5ef8510a --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/sources/reqwest.rs @@ -0,0 +1,36 @@ + +// --- stubs for the "reqwest" library --- + +/* + --- we don't seem to have a way to use this, hence we currently test against the real reqwest library +#[derive(Debug)] +pub struct Error { } + +pub mod blocking { + pub struct Response { } + impl Response { + pub fn text(self) -> Result { + Ok("".to_string()) + } + } + + pub fn get(url: T) -> Result { + let _url = url; + + Ok(Response {}) + } +} + +pub struct Response { } +impl Response { + pub async fn text(self) -> Result { + Ok("".to_string()) + } +} + +pub async fn get(url: T) -> Result { + let _url = url; + + Ok(Response {}) +} +*/ diff --git a/rust/ql/test/library-tests/dataflow/sources/test.rs b/rust/ql/test/library-tests/dataflow/sources/test.rs new file mode 100644 index 000000000000..62b00e94b9df --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/sources/test.rs @@ -0,0 +1,70 @@ +#![allow(deprecated)] + +fn sink(_: T) { } + +// --- tests --- + +fn test_env_vars() { + sink(std::env::var("HOME")); // $ MISSING: Alert[rust/summary/taint-sources] hasTaintFlow + sink(std::env::var_os("PATH")); // $ MISSING: Alert[rust/summary/taint-sources] hasTaintFlow + + let var1 = std::env::var("HOME").expect("HOME not set"); // $ MISSING: Alert[rust/summary/taint-sources] + let var2 = std::env::var_os("PATH").unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + + sink(var1); // $ MISSING: hasTaintFlow + sink(var2); // $ MISSING: hasTaintFlow + + for (key, value) in std::env::vars() { // $ MISSING: Alert[rust/summary/taint-sources] + sink(key); // $ MISSING: hasTaintFlow + sink(value); // $ MISSING: hasTaintFlow + } + + for (key, value) in std::env::vars_os() { // $ MISSING: Alert[rust/summary/taint-sources] + sink(key); // $ MISSING: hasTaintFlow + sink(value); // $ MISSING: hasTaintFlow + } +} + +fn test_env_args() { + let args: Vec = std::env::args().collect(); // $ MISSING: Alert[rust/summary/taint-sources] + let my_path = &args[0]; + let arg1 = &args[1]; + let arg2 = std::env::args().nth(2).unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + let arg3 = std::env::args_os().nth(3).unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + + sink(my_path); // $ MISSING: hasTaintFlow + sink(arg1); // $ MISSING: hasTaintFlow + sink(arg2); // $ MISSING: hasTaintFlow + sink(arg3); // $ MISSING: hasTaintFlow + + for arg in std::env::args() { // $ MISSING: Alert[rust/summary/taint-sources] + sink(arg); // $ MISSING: hasTaintFlow + } + + for arg in std::env::args_os() { // $ MISSING: Alert[rust/summary/taint-sources] + sink(arg); // $ MISSING: hasTaintFlow + } +} + +fn test_env_dirs() { + let dir = std::env::current_dir().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources] + let exe = std::env::current_exe().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources] + let home = std::env::home_dir().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources] + + sink(dir); // $ MISSING: hasTaintFlow + sink(exe); // $ MISSING: hasTaintFlow + sink(home); // $ MISSING: hasTaintFlow +} + +async fn test_reqwest() -> Result<(), reqwest::Error> { + let remote_string1 = reqwest::blocking::get("http://example.com/")?.text()?; // $ MISSING: Alert[rust/summary/taint-sources] + sink(remote_string1); // $ MISSING: hasTaintFlow + + let remote_string2 = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + sink(remote_string2); // $ MISSING: hasTaintFlow + + let remote_string3 = reqwest::get("http://example.com/").await?.text().await?; // $ MISSING: Alert[rust/summary/taint-sources] + sink(remote_string3); // $ MISSING: hasTaintFlow + + Ok(()) +} From be40085982b6771278e7f3add8c75899d380f4f8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 20 Nov 2024 16:12:47 +0000 Subject: [PATCH 04/17] Rust: Add a test of flow sources reaching sinks as well. --- .../dataflow/sources/InlineFlow.expected | 0 .../dataflow/sources/InlineFlow.ql | 21 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected create mode 100644 rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql new file mode 100644 index 000000000000..85bb2c9dbf02 --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql @@ -0,0 +1,21 @@ +import rust +import codeql.rust.dataflow.DataFlow +import codeql.rust.Concepts +import utils.InlineFlowTest + +/** + * Configuration for flow from any threat model source to an argument of a function called `sink`. + */ +module MyFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof ThreatModelSource } + + predicate isSink(DataFlow::Node sink) { + any(CallExpr call | call.getExpr().(PathExpr).getPath().toString() = "sink") + .getArgList() + .getAnArg() = sink.asExpr() + } +} + +module MyFlowTest = TaintFlowTest; + +import MyFlowTest From 374769873ac0eaf6e24076ce29f4a23bd5f2e438 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:15:36 +0000 Subject: [PATCH 05/17] Rust: Add Frameworks.qll infrastructure. --- rust/ql/lib/codeql/rust/Concepts.qll | 1 + rust/ql/lib/codeql/rust/Frameworks.qll | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 rust/ql/lib/codeql/rust/Frameworks.qll diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index 5befe006bc69..672ae09e4c23 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -6,6 +6,7 @@ private import codeql.rust.dataflow.DataFlow private import codeql.threatmodels.ThreatModels +private import codeql.rust.Frameworks /** * A data flow source for a specific threat-model. diff --git a/rust/ql/lib/codeql/rust/Frameworks.qll b/rust/ql/lib/codeql/rust/Frameworks.qll new file mode 100644 index 000000000000..2b4bdaff056d --- /dev/null +++ b/rust/ql/lib/codeql/rust/Frameworks.qll @@ -0,0 +1,3 @@ +/** + * This file imports all models of frameworks and libraries. + */ From e64f139c98360e81c1d799ada385ab95f1441444 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 20 Nov 2024 12:47:01 +0000 Subject: [PATCH 06/17] Rust: Model std::env. --- rust/ql/lib/codeql/rust/Concepts.qll | 26 +++++++++++++++ rust/ql/lib/codeql/rust/Frameworks.qll | 2 ++ .../lib/codeql/rust/frameworks/stdlib/Env.qll | 33 +++++++++++++++++++ .../dataflow/sources/TaintSources.expected | 14 ++++++++ .../library-tests/dataflow/sources/test.rs | 28 ++++++++-------- 5 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index 672ae09e4c23..8f35ea589e8a 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -47,6 +47,32 @@ class ActiveThreatModelSource extends ThreatModelSource { ActiveThreatModelSource() { currentThreatModel(this.getThreatModel()) } } +/** + * A data flow source corresponding to the program's command line arguments or path. + */ +class CommandLineArgsSource extends ThreatModelSource instanceof CommandLineArgsSource::Range { } + +module CommandLineArgsSource { + abstract class Range extends ThreatModelSource::Range { + override string getThreatModel() { result = "commandargs" } + + override string getSourceType() { result = "CommandLineArgs" } + } +} + +/** + * A data flow source corresponding to the program's environment. + */ +class EnvironmentSource extends ThreatModelSource instanceof EnvironmentSource::Range { } + +module EnvironmentSource { + abstract class Range extends ThreatModelSource::Range { + override string getThreatModel() { result = "environment" } + + override string getSourceType() { result = "EnvironmentSource" } + } +} + /** * A data-flow node that constructs a SQL statement. * diff --git a/rust/ql/lib/codeql/rust/Frameworks.qll b/rust/ql/lib/codeql/rust/Frameworks.qll index 2b4bdaff056d..4ed5d72b898e 100644 --- a/rust/ql/lib/codeql/rust/Frameworks.qll +++ b/rust/ql/lib/codeql/rust/Frameworks.qll @@ -1,3 +1,5 @@ /** * This file imports all models of frameworks and libraries. */ + +private import codeql.rust.frameworks.stdlib.Env diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll new file mode 100644 index 000000000000..b3d1eac8f5d6 --- /dev/null +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll @@ -0,0 +1,33 @@ +/** + * Provides modeling for the `std::env` library. + */ + +private import rust +private import codeql.rust.Concepts + +/** + * A call to `std::env::args` or `std::env::args_os`. + */ +private class StdEnvArgs extends CommandLineArgsSource::Range { + StdEnvArgs() { + this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::args", "crate::env::args_os"] + } +} + +/** + * A call to `std::env::current_dir`, `std::env::current_exe` or `std::env::home_dir`. + */ +private class StdEnvDir extends CommandLineArgsSource::Range { + StdEnvDir() { + this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"] + } +} + +/** + * A call to `std::env::var`, `std::env::var_os`, `std::env::vars` or `std::env::vars_os`. + */ +private class StdEnvVar extends EnvironmentSource::Range { + StdEnvVar() { + this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"] + } +} diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected index e69de29bb2d1..06b84dc590a0 100644 --- a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected +++ b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected @@ -0,0 +1,14 @@ +| test.rs:8:10:8:30 | CallExpr | EnvironmentSource (environment) | +| test.rs:9:10:9:33 | CallExpr | EnvironmentSource (environment) | +| test.rs:11:16:11:36 | CallExpr | EnvironmentSource (environment) | +| test.rs:12:16:12:39 | CallExpr | EnvironmentSource (environment) | +| test.rs:17:25:17:40 | CallExpr | EnvironmentSource (environment) | +| test.rs:22:25:22:43 | CallExpr | EnvironmentSource (environment) | +| test.rs:29:29:29:44 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:32:16:32:31 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:33:16:33:34 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:40:16:40:31 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:44:16:44:34 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:50:15:50:37 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:51:15:51:37 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:52:16:52:35 | CallExpr | CommandLineArgs (commandargs) | diff --git a/rust/ql/test/library-tests/dataflow/sources/test.rs b/rust/ql/test/library-tests/dataflow/sources/test.rs index 62b00e94b9df..00cc96bdc003 100644 --- a/rust/ql/test/library-tests/dataflow/sources/test.rs +++ b/rust/ql/test/library-tests/dataflow/sources/test.rs @@ -5,51 +5,51 @@ fn sink(_: T) { } // --- tests --- fn test_env_vars() { - sink(std::env::var("HOME")); // $ MISSING: Alert[rust/summary/taint-sources] hasTaintFlow - sink(std::env::var_os("PATH")); // $ MISSING: Alert[rust/summary/taint-sources] hasTaintFlow + sink(std::env::var("HOME")); // $ Alert[rust/summary/taint-sources] hasTaintFlow + sink(std::env::var_os("PATH")); // $ Alert[rust/summary/taint-sources] hasTaintFlow - let var1 = std::env::var("HOME").expect("HOME not set"); // $ MISSING: Alert[rust/summary/taint-sources] - let var2 = std::env::var_os("PATH").unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + let var1 = std::env::var("HOME").expect("HOME not set"); // $ Alert[rust/summary/taint-sources] + let var2 = std::env::var_os("PATH").unwrap(); // $ Alert[rust/summary/taint-sources] sink(var1); // $ MISSING: hasTaintFlow sink(var2); // $ MISSING: hasTaintFlow - for (key, value) in std::env::vars() { // $ MISSING: Alert[rust/summary/taint-sources] + for (key, value) in std::env::vars() { // $ Alert[rust/summary/taint-sources] sink(key); // $ MISSING: hasTaintFlow sink(value); // $ MISSING: hasTaintFlow } - for (key, value) in std::env::vars_os() { // $ MISSING: Alert[rust/summary/taint-sources] + for (key, value) in std::env::vars_os() { // $ Alert[rust/summary/taint-sources] sink(key); // $ MISSING: hasTaintFlow sink(value); // $ MISSING: hasTaintFlow } } fn test_env_args() { - let args: Vec = std::env::args().collect(); // $ MISSING: Alert[rust/summary/taint-sources] + let args: Vec = std::env::args().collect(); // $ Alert[rust/summary/taint-sources] let my_path = &args[0]; let arg1 = &args[1]; - let arg2 = std::env::args().nth(2).unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] - let arg3 = std::env::args_os().nth(3).unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + let arg2 = std::env::args().nth(2).unwrap(); // $ Alert[rust/summary/taint-sources] + let arg3 = std::env::args_os().nth(3).unwrap(); // $ Alert[rust/summary/taint-sources] sink(my_path); // $ MISSING: hasTaintFlow sink(arg1); // $ MISSING: hasTaintFlow sink(arg2); // $ MISSING: hasTaintFlow sink(arg3); // $ MISSING: hasTaintFlow - for arg in std::env::args() { // $ MISSING: Alert[rust/summary/taint-sources] + for arg in std::env::args() { // $ Alert[rust/summary/taint-sources] sink(arg); // $ MISSING: hasTaintFlow } - for arg in std::env::args_os() { // $ MISSING: Alert[rust/summary/taint-sources] + for arg in std::env::args_os() { // $ Alert[rust/summary/taint-sources] sink(arg); // $ MISSING: hasTaintFlow } } fn test_env_dirs() { - let dir = std::env::current_dir().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources] - let exe = std::env::current_exe().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources] - let home = std::env::home_dir().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources] + let dir = std::env::current_dir().expect("FAILED"); // $ Alert[rust/summary/taint-sources] + let exe = std::env::current_exe().expect("FAILED"); // $ Alert[rust/summary/taint-sources] + let home = std::env::home_dir().expect("FAILED"); // $ Alert[rust/summary/taint-sources] sink(dir); // $ MISSING: hasTaintFlow sink(exe); // $ MISSING: hasTaintFlow From 176e9a425ffe80a49de258d106d5e34bac822ef1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:25:58 +0000 Subject: [PATCH 07/17] Rust: Model reqwest. --- rust/ql/lib/codeql/rust/Concepts.qll | 13 +++++++++++++ rust/ql/lib/codeql/rust/Frameworks.qll | 1 + rust/ql/lib/codeql/rust/frameworks/Reqwest.qll | 16 ++++++++++++++++ .../dataflow/sources/TaintSources.expected | 3 +++ .../test/library-tests/dataflow/sources/test.rs | 6 +++--- 5 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/frameworks/Reqwest.qll diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index 8f35ea589e8a..21fd9bd0d398 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -73,6 +73,19 @@ module EnvironmentSource { } } +/** + * A data flow source for remote (network) data. + */ +class RemoteSource extends ThreatModelSource instanceof RemoteSource::Range { } + +module RemoteSource { + abstract class Range extends ThreatModelSource::Range { + override string getThreatModel() { result = "remote" } + + override string getSourceType() { result = "RemoteSource" } + } +} + /** * A data-flow node that constructs a SQL statement. * diff --git a/rust/ql/lib/codeql/rust/Frameworks.qll b/rust/ql/lib/codeql/rust/Frameworks.qll index 4ed5d72b898e..601e87ef6ebc 100644 --- a/rust/ql/lib/codeql/rust/Frameworks.qll +++ b/rust/ql/lib/codeql/rust/Frameworks.qll @@ -2,4 +2,5 @@ * This file imports all models of frameworks and libraries. */ +private import codeql.rust.frameworks.Reqwest private import codeql.rust.frameworks.stdlib.Env diff --git a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll new file mode 100644 index 000000000000..3f24c1e9e7fe --- /dev/null +++ b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll @@ -0,0 +1,16 @@ +/** + * Provides modeling for the `reqwest` library. + */ + +private import rust +private import codeql.rust.Concepts + +/** + * A call to `reqwest::get` or `reqwest::blocking::get`. + */ +private class ReqwestGet extends RemoteSource::Range { + ReqwestGet() { + this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + ["crate::get", "crate::blocking::get"] + } +} diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected index 06b84dc590a0..e7d561f5f58d 100644 --- a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected +++ b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected @@ -12,3 +12,6 @@ | test.rs:50:15:50:37 | CallExpr | CommandLineArgs (commandargs) | | test.rs:51:15:51:37 | CallExpr | CommandLineArgs (commandargs) | | test.rs:52:16:52:35 | CallExpr | CommandLineArgs (commandargs) | +| test.rs:60:26:60:70 | CallExpr | RemoteSource (remote, DEFAULT) | +| test.rs:63:26:63:70 | CallExpr | RemoteSource (remote, DEFAULT) | +| test.rs:66:26:66:60 | CallExpr | RemoteSource (remote, DEFAULT) | diff --git a/rust/ql/test/library-tests/dataflow/sources/test.rs b/rust/ql/test/library-tests/dataflow/sources/test.rs index 00cc96bdc003..e4701865a7ea 100644 --- a/rust/ql/test/library-tests/dataflow/sources/test.rs +++ b/rust/ql/test/library-tests/dataflow/sources/test.rs @@ -57,13 +57,13 @@ fn test_env_dirs() { } async fn test_reqwest() -> Result<(), reqwest::Error> { - let remote_string1 = reqwest::blocking::get("http://example.com/")?.text()?; // $ MISSING: Alert[rust/summary/taint-sources] + let remote_string1 = reqwest::blocking::get("http://example.com/")?.text()?; // $ Alert[rust/summary/taint-sources] sink(remote_string1); // $ MISSING: hasTaintFlow - let remote_string2 = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap(); // $ MISSING: Alert[rust/summary/taint-sources] + let remote_string2 = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap(); // $ Alert[rust/summary/taint-sources] sink(remote_string2); // $ MISSING: hasTaintFlow - let remote_string3 = reqwest::get("http://example.com/").await?.text().await?; // $ MISSING: Alert[rust/summary/taint-sources] + let remote_string3 = reqwest::get("http://example.com/").await?.text().await?; // $ Alert[rust/summary/taint-sources] sink(remote_string3); // $ MISSING: hasTaintFlow Ok(()) From 292b29b0e3d7ba7cbf85f4700bc54e343a82a1f1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 21 Nov 2024 23:05:08 +0000 Subject: [PATCH 08/17] Rust: Fix following rebase on main. --- rust/ql/lib/codeql/rust/frameworks/Reqwest.qll | 2 +- rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll | 6 +++--- rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll index 3f24c1e9e7fe..cb0924f93a1c 100644 --- a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll +++ b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll @@ -10,7 +10,7 @@ private import codeql.rust.Concepts */ private class ReqwestGet extends RemoteSource::Range { ReqwestGet() { - this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::get", "crate::blocking::get"] } } diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll index b3d1eac8f5d6..2319c4262487 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll @@ -10,7 +10,7 @@ private import codeql.rust.Concepts */ private class StdEnvArgs extends CommandLineArgsSource::Range { StdEnvArgs() { - this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::args", "crate::env::args_os"] + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::args", "crate::env::args_os"] } } @@ -19,7 +19,7 @@ private class StdEnvArgs extends CommandLineArgsSource::Range { */ private class StdEnvDir extends CommandLineArgsSource::Range { StdEnvDir() { - this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"] + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"] } } @@ -28,6 +28,6 @@ private class StdEnvDir extends CommandLineArgsSource::Range { */ private class StdEnvVar extends EnvironmentSource::Range { StdEnvVar() { - this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"] + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"] } } diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql index 85bb2c9dbf02..1499784ac0e4 100644 --- a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql +++ b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql @@ -12,7 +12,7 @@ module MyFlowConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { any(CallExpr call | call.getExpr().(PathExpr).getPath().toString() = "sink") .getArgList() - .getAnArg() = sink.asExpr() + .getAnArg() = sink.asExpr().getExpr() } } From 20eaaa56999e0774b9bf416b7653a5b5fd75366b Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 09:22:11 +0000 Subject: [PATCH 09/17] Rust: Use final extensions. --- rust/ql/lib/codeql/rust/Concepts.qll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index 21fd9bd0d398..a9ec8dfe530e 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -50,7 +50,7 @@ class ActiveThreatModelSource extends ThreatModelSource { /** * A data flow source corresponding to the program's command line arguments or path. */ -class CommandLineArgsSource extends ThreatModelSource instanceof CommandLineArgsSource::Range { } +final class CommandLineArgsSource = CommandLineArgsSource::Range; module CommandLineArgsSource { abstract class Range extends ThreatModelSource::Range { @@ -63,7 +63,7 @@ module CommandLineArgsSource { /** * A data flow source corresponding to the program's environment. */ -class EnvironmentSource extends ThreatModelSource instanceof EnvironmentSource::Range { } +final class EnvironmentSource = EnvironmentSource::Range; module EnvironmentSource { abstract class Range extends ThreatModelSource::Range { @@ -76,7 +76,7 @@ module EnvironmentSource { /** * A data flow source for remote (network) data. */ -class RemoteSource extends ThreatModelSource instanceof RemoteSource::Range { } +final class RemoteSource = RemoteSource::Range; module RemoteSource { abstract class Range extends ThreatModelSource::Range { From ed67dae8500fe886312b21968673eb749a19764e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:20:04 +0000 Subject: [PATCH 10/17] Rust: Make ql-for-ql happy. --- rust/ql/src/queries/summary/TaintSources.ql | 4 +-- .../dataflow/sources/TaintSources.expected | 34 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/rust/ql/src/queries/summary/TaintSources.ql b/rust/ql/src/queries/summary/TaintSources.ql index 2e1bc7205e27..f7dc95eccb48 100644 --- a/rust/ql/src/queries/summary/TaintSources.ql +++ b/rust/ql/src/queries/summary/TaintSources.ql @@ -13,5 +13,5 @@ import codeql.rust.Concepts from ThreatModelSource s, string defaultString where - if s instanceof ActiveThreatModelSource then defaultString = ", DEFAULT" else defaultString = "" -select s, s.getSourceType() + " (" + s.getThreatModel() + defaultString + ")" + if s instanceof ActiveThreatModelSource then defaultString = " (DEFAULT)" else defaultString = "" +select s, "Flow source '" + s.getSourceType() + "' of type " + s.getThreatModel() + defaultString + "." diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected index e7d561f5f58d..50336f15571f 100644 --- a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected +++ b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected @@ -1,17 +1,17 @@ -| test.rs:8:10:8:30 | CallExpr | EnvironmentSource (environment) | -| test.rs:9:10:9:33 | CallExpr | EnvironmentSource (environment) | -| test.rs:11:16:11:36 | CallExpr | EnvironmentSource (environment) | -| test.rs:12:16:12:39 | CallExpr | EnvironmentSource (environment) | -| test.rs:17:25:17:40 | CallExpr | EnvironmentSource (environment) | -| test.rs:22:25:22:43 | CallExpr | EnvironmentSource (environment) | -| test.rs:29:29:29:44 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:32:16:32:31 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:33:16:33:34 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:40:16:40:31 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:44:16:44:34 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:50:15:50:37 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:51:15:51:37 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:52:16:52:35 | CallExpr | CommandLineArgs (commandargs) | -| test.rs:60:26:60:70 | CallExpr | RemoteSource (remote, DEFAULT) | -| test.rs:63:26:63:70 | CallExpr | RemoteSource (remote, DEFAULT) | -| test.rs:66:26:66:60 | CallExpr | RemoteSource (remote, DEFAULT) | +| test.rs:8:10:8:30 | CallExpr | Flow source 'EnvironmentSource' of type environment. | +| test.rs:9:10:9:33 | CallExpr | Flow source 'EnvironmentSource' of type environment. | +| test.rs:11:16:11:36 | CallExpr | Flow source 'EnvironmentSource' of type environment. | +| test.rs:12:16:12:39 | CallExpr | Flow source 'EnvironmentSource' of type environment. | +| test.rs:17:25:17:40 | CallExpr | Flow source 'EnvironmentSource' of type environment. | +| test.rs:22:25:22:43 | CallExpr | Flow source 'EnvironmentSource' of type environment. | +| test.rs:29:29:29:44 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:32:16:32:31 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:33:16:33:34 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:40:16:40:31 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:44:16:44:34 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:50:15:50:37 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:51:15:51:37 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:52:16:52:35 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:60:26:60:70 | CallExpr | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:63:26:63:70 | CallExpr | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:66:26:66:60 | CallExpr | Flow source 'RemoteSource' of type remote (DEFAULT). | From 194f967d74f2e2e0cc88c79711fe88d289d5bdef Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:36:54 +0000 Subject: [PATCH 11/17] Rust: Required doc comments. --- rust/ql/lib/codeql/rust/Concepts.qll | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/rust/ql/lib/codeql/rust/Concepts.qll b/rust/ql/lib/codeql/rust/Concepts.qll index a9ec8dfe530e..9369668923f8 100644 --- a/rust/ql/lib/codeql/rust/Concepts.qll +++ b/rust/ql/lib/codeql/rust/Concepts.qll @@ -52,7 +52,13 @@ class ActiveThreatModelSource extends ThreatModelSource { */ final class CommandLineArgsSource = CommandLineArgsSource::Range; +/** + * Provides a class for modeling new sources for the program's command line arguments or path. + */ module CommandLineArgsSource { + /** + * A data flow source corresponding to the program's command line arguments or path. + */ abstract class Range extends ThreatModelSource::Range { override string getThreatModel() { result = "commandargs" } @@ -65,7 +71,13 @@ module CommandLineArgsSource { */ final class EnvironmentSource = EnvironmentSource::Range; +/** + * Provides a class for modeling new sources for the program's environment. + */ module EnvironmentSource { + /** + * A data flow source corresponding to the program's environment. + */ abstract class Range extends ThreatModelSource::Range { override string getThreatModel() { result = "environment" } @@ -78,7 +90,13 @@ module EnvironmentSource { */ final class RemoteSource = RemoteSource::Range; +/** + * Provides a class for modeling new sources of remote (network) data. + */ module RemoteSource { + /** + * A data flow source for remote (network) data. + */ abstract class Range extends ThreatModelSource::Range { override string getThreatModel() { result = "remote" } From fe2d0b631c87f059c3b9db367dc5da8516e88aba Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:37:15 +0000 Subject: [PATCH 12/17] Rust: Autoformat. --- rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll index 2319c4262487..69658d5fec53 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll @@ -10,7 +10,8 @@ private import codeql.rust.Concepts */ private class StdEnvArgs extends CommandLineArgsSource::Range { StdEnvArgs() { - this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::args", "crate::env::args_os"] + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + ["crate::env::args", "crate::env::args_os"] } } @@ -19,7 +20,8 @@ private class StdEnvArgs extends CommandLineArgsSource::Range { */ private class StdEnvDir extends CommandLineArgsSource::Range { StdEnvDir() { - this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"] + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + ["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"] } } @@ -28,6 +30,7 @@ private class StdEnvDir extends CommandLineArgsSource::Range { */ private class StdEnvVar extends EnvironmentSource::Range { StdEnvVar() { - this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"] + this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = + ["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"] } } From 75a3c931d1c86dceb2f6b8ebbf727fbafabee751 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:58:23 +0000 Subject: [PATCH 13/17] Rust: Autoformat (again). --- rust/ql/src/queries/summary/TaintSources.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rust/ql/src/queries/summary/TaintSources.ql b/rust/ql/src/queries/summary/TaintSources.ql index f7dc95eccb48..9ac72b706efb 100644 --- a/rust/ql/src/queries/summary/TaintSources.ql +++ b/rust/ql/src/queries/summary/TaintSources.ql @@ -14,4 +14,5 @@ import codeql.rust.Concepts from ThreatModelSource s, string defaultString where if s instanceof ActiveThreatModelSource then defaultString = " (DEFAULT)" else defaultString = "" -select s, "Flow source '" + s.getSourceType() + "' of type " + s.getThreatModel() + defaultString + "." +select s, + "Flow source '" + s.getSourceType() + "' of type " + s.getThreatModel() + defaultString + "." From d8b58f21c77ac6490dca125a2821d8d0d45621cc Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 16:42:24 +0000 Subject: [PATCH 14/17] Rust: Restrict ReqwestGet by crate origin. --- rust/ql/lib/codeql/rust/frameworks/Reqwest.qll | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll index cb0924f93a1c..141f9767ecad 100644 --- a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll +++ b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll @@ -9,8 +9,11 @@ private import codeql.rust.Concepts * A call to `reqwest::get` or `reqwest::blocking::get`. */ private class ReqwestGet extends RemoteSource::Range { + CallExpr ce; + ReqwestGet() { - this.asExpr().getExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = - ["crate::get", "crate::blocking::get"] + this.asExpr().getExpr() = ce and + ce.getExpr().(PathExpr).getPath().getResolvedCrateOrigin().matches("%reqwest") and + ce.getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::get", "crate::blocking::get"] } } From f2f577f86c5cc4b7f38181d754af9821ec9905c2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 17:09:52 +0000 Subject: [PATCH 15/17] Rust: Fix toString(). --- rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql index 1499784ac0e4..85ac4eec6983 100644 --- a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql +++ b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql @@ -4,13 +4,13 @@ import codeql.rust.Concepts import utils.InlineFlowTest /** - * Configuration for flow from any threat model source to an argument of a function called `sink`. + * Configuration for flow from any threat model source to an argument of the function `sink`. */ module MyFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ThreatModelSource } predicate isSink(DataFlow::Node sink) { - any(CallExpr call | call.getExpr().(PathExpr).getPath().toString() = "sink") + any(CallExpr call | call.getExpr().(PathExpr).getPath().getResolvedPath() = "crate::test::sink") .getArgList() .getAnArg() = sink.asExpr().getExpr() } From 4c50c083fbdc71db38d5cee8ce64e4e9e0c740cc Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 22 Nov 2024 17:12:09 +0000 Subject: [PATCH 16/17] Rust: Implement good suggestions from ql-for-ql. --- rust/ql/lib/codeql/rust/frameworks/Reqwest.qll | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll index 141f9767ecad..2ab11a20ed4b 100644 --- a/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll +++ b/rust/ql/lib/codeql/rust/frameworks/Reqwest.qll @@ -9,11 +9,11 @@ private import codeql.rust.Concepts * A call to `reqwest::get` or `reqwest::blocking::get`. */ private class ReqwestGet extends RemoteSource::Range { - CallExpr ce; - ReqwestGet() { - this.asExpr().getExpr() = ce and - ce.getExpr().(PathExpr).getPath().getResolvedCrateOrigin().matches("%reqwest") and - ce.getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::get", "crate::blocking::get"] + exists(CallExpr ce | + this.asExpr().getExpr() = ce and + ce.getExpr().(PathExpr).getPath().getResolvedCrateOrigin().matches("%reqwest") and + ce.getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::get", "crate::blocking::get"] + ) } } From bded7085f0b2c456ea60f1c26e8949bde2c3f215 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 25 Nov 2024 10:01:47 +0000 Subject: [PATCH 17/17] Rust: Effect of toString changes in main. --- .../dataflow/sources/TaintSources.expected | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected index 50336f15571f..cebbc00f3a5e 100644 --- a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected +++ b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected @@ -1,17 +1,17 @@ -| test.rs:8:10:8:30 | CallExpr | Flow source 'EnvironmentSource' of type environment. | -| test.rs:9:10:9:33 | CallExpr | Flow source 'EnvironmentSource' of type environment. | -| test.rs:11:16:11:36 | CallExpr | Flow source 'EnvironmentSource' of type environment. | -| test.rs:12:16:12:39 | CallExpr | Flow source 'EnvironmentSource' of type environment. | -| test.rs:17:25:17:40 | CallExpr | Flow source 'EnvironmentSource' of type environment. | -| test.rs:22:25:22:43 | CallExpr | Flow source 'EnvironmentSource' of type environment. | -| test.rs:29:29:29:44 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:32:16:32:31 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:33:16:33:34 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:40:16:40:31 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:44:16:44:34 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:50:15:50:37 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:51:15:51:37 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:52:16:52:35 | CallExpr | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:60:26:60:70 | CallExpr | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:63:26:63:70 | CallExpr | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:66:26:66:60 | CallExpr | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:8:10:8:30 | ...::var(...) | Flow source 'EnvironmentSource' of type environment. | +| test.rs:9:10:9:33 | ...::var_os(...) | Flow source 'EnvironmentSource' of type environment. | +| test.rs:11:16:11:36 | ...::var(...) | Flow source 'EnvironmentSource' of type environment. | +| test.rs:12:16:12:39 | ...::var_os(...) | Flow source 'EnvironmentSource' of type environment. | +| test.rs:17:25:17:40 | ...::vars(...) | Flow source 'EnvironmentSource' of type environment. | +| test.rs:22:25:22:43 | ...::vars_os(...) | Flow source 'EnvironmentSource' of type environment. | +| test.rs:29:29:29:44 | ...::args(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:32:16:32:31 | ...::args(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:33:16:33:34 | ...::args_os(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:40:16:40:31 | ...::args(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:44:16:44:34 | ...::args_os(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:50:15:50:37 | ...::current_dir(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:51:15:51:37 | ...::current_exe(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:52:16:52:35 | ...::home_dir(...) | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:60:26:60:70 | ...::get(...) | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:63:26:63:70 | ...::get(...) | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:66:26:66:60 | ...::get(...) | Flow source 'RemoteSource' of type remote (DEFAULT). |