From bb3be2f8af13bba91332366dc98311a9864a96dc Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 21 Jan 2025 10:54:42 +0000
Subject: [PATCH 01/21] Rust: Add a test for the log crate + placeholder query.
---
.../security/CWE-312/CleartextLogging.ql | 20 +++
.../CWE-312/CleartextLogging.expected | 0
.../security/CWE-312/CleartextLogging.qlref | 3 +
.../query-tests/security/CWE-312/options.yml | 3 +
.../security/CWE-312/test_logging.rs | 132 ++++++++++++++++++
5 files changed, 158 insertions(+)
create mode 100644 rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
create mode 100644 rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
create mode 100644 rust/ql/test/query-tests/security/CWE-312/CleartextLogging.qlref
create mode 100644 rust/ql/test/query-tests/security/CWE-312/options.yml
create mode 100644 rust/ql/test/query-tests/security/CWE-312/test_logging.rs
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
new file mode 100644
index 000000000000..810736e5b3a4
--- /dev/null
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
@@ -0,0 +1,20 @@
+/**
+ * @name Cleartext logging of sensitive information
+ * @description Logging sensitive information in plaintext can
+ * expose it to an attacker.
+ * @kind path-problem
+ * @problem.severity error
+ * @security-severity 7.5
+ * @precision high
+ * @id rust/cleartext-logging
+ * @tags security
+ * external/cwe/cwe-312
+ * external/cwe/cwe-359
+ * external/cwe/cwe-532
+ */
+
+import rust
+
+from Element e
+where none()
+select e, ""
diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.qlref b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.qlref
new file mode 100644
index 000000000000..01a435da9202
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.qlref
@@ -0,0 +1,3 @@
+query: queries/security/CWE-312/CleartextLogging.ql
+postprocess:
+ - utils/test/InlineExpectationsTestQuery.ql
diff --git a/rust/ql/test/query-tests/security/CWE-312/options.yml b/rust/ql/test/query-tests/security/CWE-312/options.yml
new file mode 100644
index 000000000000..26180d858d8e
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-312/options.yml
@@ -0,0 +1,3 @@
+qltest_cargo_check: true
+qltest_dependencies:
+ - log = { version = "0.4.25", features = ["kv"] }
diff --git a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
new file mode 100644
index 000000000000..2595f27fcada
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
@@ -0,0 +1,132 @@
+
+use log::{debug, error, info, trace, warn, log, Level};
+
+// --- tests ---
+
+fn get_password() -> String {
+ return "123456".to_string();
+}
+
+fn use_password(password: &String) {
+ // ...
+}
+
+#[derive(Debug)]
+struct MyStruct1 {
+ harmless: String,
+ password: String,
+}
+
+impl std::fmt::Display for MyStruct1 {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ write!(f, "{} {}", self.harmless, self.password)
+ }
+}
+
+#[derive(Debug)]
+struct MyStruct2 {
+ harmless: String,
+ password: String,
+}
+
+impl std::fmt::Display for MyStruct2 {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ write!(f, "{} [REDACTED]", self.harmless) // doesn't output password
+ }
+}
+
+fn test_log(harmless: String, password: String, encrypted_password: String) {
+ // logging macros
+ debug!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ error!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ info!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ trace!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ warn!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ log!(Level::Error, "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+
+ // debug! macro, various formatting
+ debug!("message");
+ debug!("message = {}", harmless);
+ debug!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ debug!("message = {}", encrypted_password);
+ debug!("message = {} {}", harmless, password); // $ MISSING: Alert[rust/cleartext-logging]
+ debug!("message = {harmless}");
+ debug!("message = {harmless} {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ debug!("message = {password}"); // $ MISSING: Alert[rust/cleartext-logging]
+ debug!("message = {password:?}"); // $ MISSING: Alert[rust/cleartext-logging]
+ debug!(target: "target", "message = {}", harmless);
+ debug!(target: "target", "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ debug!(target: &password, "message = {}", harmless); // $ MISSING: Alert[rust/cleartext-logging]
+
+ // log! macro, various formatting
+ log!(Level::Error, "message = {}", harmless);
+ log!(Level::Error, "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ log!(target: "target", Level::Error, "message = {}", harmless);
+ log!(target: "target", Level::Error, "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ log!(target: &password, Level::Error, "message = {}", harmless); // $ MISSING: Alert[rust/cleartext-logging]
+
+ // structured logging
+ error!(value = 1; "message = {}", harmless);
+ error!(value = 1; "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(target: "target", value = 1; "message");
+ error!(target: "target", value = 1; "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(target: &password, value = 1; "message"); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(value = 1; "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(value = password.as_str(); "message"); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(value:? = password.as_str(); "message"); // $ MISSING: Alert[rust/cleartext-logging]
+
+ let value1 = 1;
+ error!(value1; "message = {}", harmless);
+ error!(value1; "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(target: "target", value1; "message");
+ error!(target: "target", value1; "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(target: &password, value1; "message"); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(value1; "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+
+ let value2 = password.as_str();
+ error!(value2; "message"); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(value2:?; "message"); // $ MISSING: Alert[rust/cleartext-logging]
+
+ // pre-formatted
+ let m1 = &password; // $ MISSING: Source=m1
+ info!("message = {}", m1); // $ MISSING: Alert[rust/cleartext-logging]=m1
+
+ let m2 = "message = ".to_string() + &password; // $ MISSING: Source=m2
+ info!("{}", m2); // $ MISSING: Alert[rust/cleartext-logging]=m2
+
+ let m3 = format!("message = {}", password); // $ MISSING:=m3
+ info!("{}", m3); // $ MISSING: Alert[rust/cleartext-logging]=m3
+
+ // logging with a call
+ trace!("message = {}", get_password()); // $ MISSING: Alert[rust/cleartext-logging]
+
+ let str1 = "123456".to_string();
+ trace!("message = {}", &str1); // $ MISSING: Alert[rust/cleartext-logging]
+ use_password(&str1); // (proves that `str1` is a password)
+ trace!("message = {}", &str1); // $ MISSING: Alert[rust/cleartext-logging]
+
+ let str2 = "123456".to_string();
+ trace!("message = {}", &str2);
+
+ // logging from a tuple
+ let t1 = (harmless, password); // $ MISSING:=t1
+ trace!("message = {}", t1.0);
+ trace!("message = {}", t1.1); // $ MISSING: Alert[rust/cleartext-logging]=t1
+ trace!("message = {:?}", t1); // $ MISSING: Alert[rust/cleartext-logging]=t1
+ trace!("message = {:#?}", t1); // $ MISSING: Alert[rust/cleartext-logging]=t1
+
+ // logging from a struct
+ let s1 = MyStruct1 { harmless: "foo".to_string(), password: "123456".to_string() }; // $ MISSING: Source=s1
+ warn!("message = {}", s1.harmless);
+ warn!("message = {}", s1.password); // $ MISSING: Alert[rust/cleartext-logging]
+ warn!("message = {}", s1); // $ MISSING: Alert[rust/cleartext-logging]=s1
+ warn!("message = {:?}", s1); // $ MISSING: Alert[rust/cleartext-logging]=s1
+ warn!("message = {:#?}", s1); // $ MISSING: Alert[rust/cleartext-logging]=s1
+
+ let s2 = MyStruct2 { harmless: "foo".to_string(), password: "123456".to_string() }; // $ MISSING: Source=s2
+ warn!("message = {}", s2.harmless);
+ warn!("message = {}", s2.password); // $ MISSING: Alert[rust/cleartext-logging]
+ warn!("message = {}", s2); // (this implementation does not output the password field)
+ warn!("message = {:?}", s2); // $ MISSING: Alert[rust/cleartext-logging]=s2
+ warn!("message = {:#?}", s2); // $ MISSING: Alert[rust/cleartext-logging]=s2
+}
From 173cfd5c7bf173ada56ba9e698f736bb342f877e Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 21 Jan 2025 12:09:20 +0000
Subject: [PATCH 02/21] Rust: Add test cases for various std:: bits.
---
.../security/CWE-312/test_logging.rs | 50 +++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
index 2595f27fcada..c015bdb24d4c 100644
--- a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
+++ b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
@@ -1,5 +1,7 @@
use log::{debug, error, info, trace, warn, log, Level};
+use std::io::Write as _;
+use std::fmt::Write as _;
// --- tests ---
@@ -97,6 +99,21 @@ fn test_log(harmless: String, password: String, encrypted_password: String) {
let m3 = format!("message = {}", password); // $ MISSING:=m3
info!("{}", m3); // $ MISSING: Alert[rust/cleartext-logging]=m3
+ let mut m4 = String::new();
+ write!(&mut m4, "message = {}", password); // $ MISSING: Source=m4
+ info!("{}", m4); // $ MISSING: Alert[rust/cleartext-logging]=m4
+
+ let mut m5 = String::new();
+ writeln!(&mut m5, "message = {}", password); // $ MISSING: Source=m5
+ info!("{}", m5); // $ MISSING: Alert[rust/cleartext-logging]=m5
+
+ let mut m6 = Vec::new();
+ write!(&mut m6, "message = {}", password); // $ MISSING: Source=m6
+ info!("{}", std::str::from_utf8(&m6).unwrap()); // $ MISSING: Alert[rust/cleartext-logging]=m6
+ unsafe {
+ info!("{}", std::str::from_utf8_unchecked(&m6)); // $ MISSING: Alert[rust/cleartext-logging]=m6
+ }
+
// logging with a call
trace!("message = {}", get_password()); // $ MISSING: Alert[rust/cleartext-logging]
@@ -130,3 +147,36 @@ fn test_log(harmless: String, password: String, encrypted_password: String) {
warn!("message = {:?}", s2); // $ MISSING: Alert[rust/cleartext-logging]=s2
warn!("message = {:#?}", s2); // $ MISSING: Alert[rust/cleartext-logging]=s2
}
+
+fn test_std(password: String, i: i32, opt_i: Option) {
+ print!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ println!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ eprint!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ eprintln!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+
+ match i {
+ 1 => { panic!("message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 2 => { todo!("message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 3 => { unimplemented!("message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 4 => { unreachable!("message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 5 => { assert!(false, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 6 => { assert_eq!(1, 2, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 7 => { assert_ne!(1, 1, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 8 => { debug_assert!(false, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 9 => { debug_assert_eq!(1, 2, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 10 => { debug_assert_ne!(1, 1, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 11 => { _ = opt_i.expect(format!("message = {}", password).as_str()); } // $ MISSING: Alert[rust/cleartext-logging]
+ _ => {}
+ }
+
+ std::io::stdout().lock().write_fmt(format_args!("message = {}", password)); // $ MISSING: Alert[rust/cleartext-logging]
+ std::io::stderr().lock().write_fmt(format_args!("message = {}", password)); // $ MISSING: Alert[rust/cleartext-logging]
+ std::io::stdout().lock().write(format!("message = {}", password).as_bytes()); // $ MISSING: Alert[rust/cleartext-logging]
+ std::io::stdout().lock().write_all(format!("message = {}", password).as_bytes()); // $ MISSING: Alert[rust/cleartext-logging]
+
+ let mut out = std::io::stdout().lock();
+ out.write(format!("message = {}", password).as_bytes()); // $ MISSING: Alert[rust/cleartext-logging]
+
+ let mut err = std::io::stderr().lock();
+ err.write(format!("message = {}", password).as_bytes()); // $ MISSING: Alert[rust/cleartext-logging]
+}
From 4297d05c05c183b230025552c4ca2ed3195393f0 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 21 Jan 2025 16:41:56 +0000
Subject: [PATCH 03/21] Rust: Implement the query.
---
.../security/CWE-312/CleartextLogging.ql | 34 +++++++++++++++++--
.../CWE-312/CleartextLogging.expected | 4 +++
2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
index 810736e5b3a4..b9a1a80b3cf8 100644
--- a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
@@ -14,7 +14,35 @@
*/
import rust
+import codeql.rust.security.CleartextLoggingExtensions
+import codeql.rust.dataflow.DataFlow
+import codeql.rust.dataflow.TaintTracking
-from Element e
-where none()
-select e, ""
+/**
+ * A taint-tracking configuration for cleartext logging vulnerabilities.
+ */
+module CleartextLoggingConfig implements DataFlow::ConfigSig {
+ import CleartextLogging
+
+ predicate isSource(DataFlow::Node source) { source instanceof Source }
+
+ predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
+
+ predicate isBarrier(DataFlow::Node barrier) { barrier instanceof Barrier }
+
+ predicate isBarrierIn(DataFlow::Node node) {
+ // make sources barriers so that we only report the closest instance
+ isSource(node)
+ }
+}
+
+module CleartextLoggingFlow = TaintTracking::Global;
+
+import CleartextLoggingFlow::PathGraph
+
+from CleartextLoggingFlow::PathNode source, CleartextLoggingFlow::PathNode sink
+where CleartextLoggingFlow::flowPath(source, sink)
+select sink.getNode(), source, sink,
+ "This operation writes '" + sink.toString() +
+ "' to a log file. It may contain unencrypted sensitive data from $@.", source,
+ source.getNode().toString()
diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
index e69de29bb2d1..58f42bec0c84 100644
--- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
+++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
@@ -0,0 +1,4 @@
+#select
+edges
+nodes
+subpaths
From 1d2950c70cb070c13334eb9f68bf3ef16cb77a08 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 21 Jan 2025 18:11:53 +0000
Subject: [PATCH 04/21] Rust: Add some sinks.
---
.../lib/codeql/rust/frameworks/log.model.yml | 10 +
.../CWE-312/CleartextLogging.expected | 236 ++++++++++++++++++
.../security/CWE-312/test_logging.rs | 72 +++---
3 files changed, 282 insertions(+), 36 deletions(-)
create mode 100644 rust/ql/lib/codeql/rust/frameworks/log.model.yml
diff --git a/rust/ql/lib/codeql/rust/frameworks/log.model.yml b/rust/ql/lib/codeql/rust/frameworks/log.model.yml
new file mode 100644
index 000000000000..2dcdb61fb625
--- /dev/null
+++ b/rust/ql/lib/codeql/rust/frameworks/log.model.yml
@@ -0,0 +1,10 @@
+extensions:
+ - addsTo:
+ pack: codeql/rust-all
+ extensible: sinkModel
+ data:
+ - ["repo:https://github.com/rust-lang/log:log", "crate::__private_api::log", "Argument[0]", "log-injection", "manual"]
+ - ["lang:std", "crate::io::stdio::_print", "Argument[0]", "log-injection", "manual"]
+ - ["lang:std", "crate::io::stdio::_eprint", "Argument[0]", "log-injection", "manual"]
+ - ["lang:core", "crate::panicking::panic_fmt", "Argument[0]", "log-injection", "manual"]
+ - ["lang:core", "::expect", "Argument[0]", "log-injection", "manual"]
diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
index 58f42bec0c84..1a60f2884338 100644
--- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
+++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
@@ -1,4 +1,240 @@
#select
+| test_logging.rs:42:5:42:36 | ...::log | test_logging.rs:42:28:42:35 | password | test_logging.rs:42:5:42:36 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:42:28:42:35 | password | password |
+| test_logging.rs:43:5:43:36 | ...::log | test_logging.rs:43:28:43:35 | password | test_logging.rs:43:5:43:36 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:43:28:43:35 | password | password |
+| test_logging.rs:44:5:44:35 | ...::log | test_logging.rs:44:27:44:34 | password | test_logging.rs:44:5:44:35 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:44:27:44:34 | password | password |
+| test_logging.rs:45:5:45:36 | ...::log | test_logging.rs:45:28:45:35 | password | test_logging.rs:45:5:45:36 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:45:28:45:35 | password | password |
+| test_logging.rs:46:5:46:35 | ...::log | test_logging.rs:46:27:46:34 | password | test_logging.rs:46:5:46:35 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:46:27:46:34 | password | password |
+| test_logging.rs:47:5:47:48 | ...::log | test_logging.rs:47:40:47:47 | password | test_logging.rs:47:5:47:48 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:47:40:47:47 | password | password |
+| test_logging.rs:52:5:52:36 | ...::log | test_logging.rs:52:28:52:35 | password | test_logging.rs:52:5:52:36 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:52:28:52:35 | password | password |
+| test_logging.rs:54:5:54:49 | ...::log | test_logging.rs:54:41:54:48 | password | test_logging.rs:54:5:54:49 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:54:41:54:48 | password | password |
+| test_logging.rs:56:5:56:47 | ...::log | test_logging.rs:56:39:56:46 | password | test_logging.rs:56:5:56:47 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:56:39:56:46 | password | password |
+| test_logging.rs:57:5:57:34 | ...::log | test_logging.rs:57:24:57:31 | password | test_logging.rs:57:5:57:34 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:57:24:57:31 | password | password |
+| test_logging.rs:58:5:58:36 | ...::log | test_logging.rs:58:24:58:31 | password | test_logging.rs:58:5:58:36 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:58:24:58:31 | password | password |
+| test_logging.rs:60:5:60:54 | ...::log | test_logging.rs:60:46:60:53 | password | test_logging.rs:60:5:60:54 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:60:46:60:53 | password | password |
+| test_logging.rs:65:5:65:48 | ...::log | test_logging.rs:65:40:65:47 | password | test_logging.rs:65:5:65:48 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:65:40:65:47 | password | password |
+| test_logging.rs:67:5:67:66 | ...::log | test_logging.rs:67:58:67:65 | password | test_logging.rs:67:5:67:66 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:67:58:67:65 | password | password |
+| test_logging.rs:72:5:72:47 | ...::log::<...> | test_logging.rs:72:39:72:46 | password | test_logging.rs:72:5:72:47 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:72:39:72:46 | password | password |
+| test_logging.rs:74:5:74:65 | ...::log::<...> | test_logging.rs:74:57:74:64 | password | test_logging.rs:74:5:74:65 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:74:57:74:64 | password | password |
+| test_logging.rs:76:5:76:47 | ...::log::<...> | test_logging.rs:76:39:76:46 | password | test_logging.rs:76:5:76:47 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:76:39:76:46 | password | password |
+| test_logging.rs:82:5:82:44 | ...::log::<...> | test_logging.rs:82:36:82:43 | password | test_logging.rs:82:5:82:44 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:82:36:82:43 | password | password |
+| test_logging.rs:84:5:84:62 | ...::log::<...> | test_logging.rs:84:54:84:61 | password | test_logging.rs:84:5:84:62 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:84:54:84:61 | password | password |
+| test_logging.rs:86:5:86:44 | ...::log::<...> | test_logging.rs:86:36:86:43 | password | test_logging.rs:86:5:86:44 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:86:36:86:43 | password | password |
+| test_logging.rs:100:5:100:19 | ...::log | test_logging.rs:99:38:99:45 | password | test_logging.rs:100:5:100:19 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:99:38:99:45 | password | password |
+| test_logging.rs:118:5:118:42 | ...::log | test_logging.rs:118:28:118:41 | get_password(...) | test_logging.rs:118:5:118:42 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:118:28:118:41 | get_password(...) | get_password(...) |
+| test_logging.rs:131:5:131:32 | ...::log | test_logging.rs:129:25:129:32 | password | test_logging.rs:131:5:131:32 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:129:25:129:32 | password | password |
+| test_logging.rs:152:5:152:36 | ...::_print | test_logging.rs:152:28:152:35 | password | test_logging.rs:152:5:152:36 | ...::_print | This operation writes '...::_print' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:152:28:152:35 | password | password |
+| test_logging.rs:153:5:153:38 | ...::_print | test_logging.rs:153:30:153:37 | password | test_logging.rs:153:5:153:38 | ...::_print | This operation writes '...::_print' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:153:30:153:37 | password | password |
+| test_logging.rs:154:5:154:37 | ...::_eprint | test_logging.rs:154:29:154:36 | password | test_logging.rs:154:5:154:37 | ...::_eprint | This operation writes '...::_eprint' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:154:29:154:36 | password | password |
+| test_logging.rs:155:5:155:39 | ...::_eprint | test_logging.rs:155:31:155:38 | password | test_logging.rs:155:5:155:39 | ...::_eprint | This operation writes '...::_eprint' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:155:31:155:38 | password | password |
+| test_logging.rs:158:16:158:47 | ...::panic_fmt | test_logging.rs:158:39:158:46 | password | test_logging.rs:158:16:158:47 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:158:39:158:46 | password | password |
+| test_logging.rs:159:16:159:46 | ...::panic_fmt | test_logging.rs:159:38:159:45 | password | test_logging.rs:159:16:159:46 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:159:38:159:45 | password | password |
+| test_logging.rs:160:16:160:55 | ...::panic_fmt | test_logging.rs:160:47:160:54 | password | test_logging.rs:160:16:160:55 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:160:47:160:54 | password | password |
+| test_logging.rs:161:16:161:53 | ...::panic_fmt | test_logging.rs:161:45:161:52 | password | test_logging.rs:161:16:161:53 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:161:45:161:52 | password | password |
+| test_logging.rs:162:16:162:55 | ...::panic_fmt | test_logging.rs:162:47:162:54 | password | test_logging.rs:162:16:162:55 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:162:47:162:54 | password | password |
+| test_logging.rs:165:16:165:61 | ...::panic_fmt | test_logging.rs:165:53:165:60 | password | test_logging.rs:165:16:165:61 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:165:53:165:60 | password | password |
+| test_logging.rs:168:27:168:32 | expect | test_logging.rs:168:58:168:65 | password | test_logging.rs:168:27:168:32 | expect | This operation writes 'expect' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:168:58:168:65 | password | password |
edges
+| test_logging.rs:42:12:42:35 | MacroExpr | test_logging.rs:42:5:42:36 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:42:28:42:35 | password | test_logging.rs:42:12:42:35 | MacroExpr | provenance | |
+| test_logging.rs:43:12:43:35 | MacroExpr | test_logging.rs:43:5:43:36 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:43:28:43:35 | password | test_logging.rs:43:12:43:35 | MacroExpr | provenance | |
+| test_logging.rs:44:11:44:34 | MacroExpr | test_logging.rs:44:5:44:35 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:44:27:44:34 | password | test_logging.rs:44:11:44:34 | MacroExpr | provenance | |
+| test_logging.rs:45:12:45:35 | MacroExpr | test_logging.rs:45:5:45:36 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:45:28:45:35 | password | test_logging.rs:45:12:45:35 | MacroExpr | provenance | |
+| test_logging.rs:46:11:46:34 | MacroExpr | test_logging.rs:46:5:46:35 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:46:27:46:34 | password | test_logging.rs:46:11:46:34 | MacroExpr | provenance | |
+| test_logging.rs:47:24:47:47 | MacroExpr | test_logging.rs:47:5:47:48 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:47:40:47:47 | password | test_logging.rs:47:24:47:47 | MacroExpr | provenance | |
+| test_logging.rs:52:12:52:35 | MacroExpr | test_logging.rs:52:5:52:36 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:52:28:52:35 | password | test_logging.rs:52:12:52:35 | MacroExpr | provenance | |
+| test_logging.rs:54:12:54:48 | MacroExpr | test_logging.rs:54:5:54:49 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:54:41:54:48 | password | test_logging.rs:54:12:54:48 | MacroExpr | provenance | |
+| test_logging.rs:56:12:56:46 | MacroExpr | test_logging.rs:56:5:56:47 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:56:39:56:46 | password | test_logging.rs:56:12:56:46 | MacroExpr | provenance | |
+| test_logging.rs:57:12:57:33 | MacroExpr | test_logging.rs:57:5:57:34 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:57:24:57:31 | password | test_logging.rs:57:12:57:33 | MacroExpr | provenance | |
+| test_logging.rs:58:12:58:35 | MacroExpr | test_logging.rs:58:5:58:36 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:58:24:58:31 | password | test_logging.rs:58:12:58:35 | MacroExpr | provenance | |
+| test_logging.rs:60:30:60:53 | MacroExpr | test_logging.rs:60:5:60:54 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:60:46:60:53 | password | test_logging.rs:60:30:60:53 | MacroExpr | provenance | |
+| test_logging.rs:65:24:65:47 | MacroExpr | test_logging.rs:65:5:65:48 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:65:40:65:47 | password | test_logging.rs:65:24:65:47 | MacroExpr | provenance | |
+| test_logging.rs:67:42:67:65 | MacroExpr | test_logging.rs:67:5:67:66 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:67:58:67:65 | password | test_logging.rs:67:42:67:65 | MacroExpr | provenance | |
+| test_logging.rs:72:23:72:46 | MacroExpr | test_logging.rs:72:5:72:47 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:72:39:72:46 | password | test_logging.rs:72:23:72:46 | MacroExpr | provenance | |
+| test_logging.rs:74:41:74:64 | MacroExpr | test_logging.rs:74:5:74:65 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:74:57:74:64 | password | test_logging.rs:74:41:74:64 | MacroExpr | provenance | |
+| test_logging.rs:76:23:76:46 | MacroExpr | test_logging.rs:76:5:76:47 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:76:39:76:46 | password | test_logging.rs:76:23:76:46 | MacroExpr | provenance | |
+| test_logging.rs:82:20:82:43 | MacroExpr | test_logging.rs:82:5:82:44 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:82:36:82:43 | password | test_logging.rs:82:20:82:43 | MacroExpr | provenance | |
+| test_logging.rs:84:38:84:61 | MacroExpr | test_logging.rs:84:5:84:62 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:84:54:84:61 | password | test_logging.rs:84:38:84:61 | MacroExpr | provenance | |
+| test_logging.rs:86:20:86:43 | MacroExpr | test_logging.rs:86:5:86:44 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:86:36:86:43 | password | test_logging.rs:86:20:86:43 | MacroExpr | provenance | |
+| test_logging.rs:99:9:99:10 | m3 | test_logging.rs:100:11:100:18 | MacroExpr | provenance | |
+| test_logging.rs:99:14:99:46 | res | test_logging.rs:99:22:99:45 | { ... } | provenance | |
+| test_logging.rs:99:22:99:45 | ...::format(...) | test_logging.rs:99:14:99:46 | res | provenance | |
+| test_logging.rs:99:22:99:45 | ...::must_use(...) | test_logging.rs:99:9:99:10 | m3 | provenance | |
+| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:19 |
+| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:18 |
+| test_logging.rs:99:38:99:45 | password | test_logging.rs:99:22:99:45 | MacroExpr | provenance | |
+| test_logging.rs:100:11:100:18 | MacroExpr | test_logging.rs:100:5:100:19 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:118:12:118:41 | MacroExpr | test_logging.rs:118:5:118:42 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:118:28:118:41 | get_password(...) | test_logging.rs:118:12:118:41 | MacroExpr | provenance | |
+| test_logging.rs:129:9:129:10 | t1 [tuple.1] | test_logging.rs:131:28:131:29 | t1 [tuple.1] | provenance | |
+| test_logging.rs:129:14:129:33 | TupleExpr [tuple.1] | test_logging.rs:129:9:129:10 | t1 [tuple.1] | provenance | |
+| test_logging.rs:129:25:129:32 | password | test_logging.rs:129:14:129:33 | TupleExpr [tuple.1] | provenance | |
+| test_logging.rs:131:12:131:31 | MacroExpr | test_logging.rs:131:5:131:32 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:131:28:131:29 | t1 [tuple.1] | test_logging.rs:131:28:131:31 | t1.1 | provenance | |
+| test_logging.rs:131:28:131:31 | t1.1 | test_logging.rs:131:12:131:31 | MacroExpr | provenance | |
+| test_logging.rs:152:12:152:35 | MacroExpr | test_logging.rs:152:5:152:36 | ...::_print | provenance | MaD:1 Sink:MaD:1 |
+| test_logging.rs:152:28:152:35 | password | test_logging.rs:152:12:152:35 | MacroExpr | provenance | |
+| test_logging.rs:153:14:153:37 | MacroExpr | test_logging.rs:153:5:153:38 | ...::_print | provenance | MaD:1 Sink:MaD:1 |
+| test_logging.rs:153:30:153:37 | password | test_logging.rs:153:14:153:37 | MacroExpr | provenance | |
+| test_logging.rs:154:13:154:36 | MacroExpr | test_logging.rs:154:5:154:37 | ...::_eprint | provenance | MaD:2 Sink:MaD:2 |
+| test_logging.rs:154:29:154:36 | password | test_logging.rs:154:13:154:36 | MacroExpr | provenance | |
+| test_logging.rs:155:15:155:38 | MacroExpr | test_logging.rs:155:5:155:39 | ...::_eprint | provenance | MaD:2 Sink:MaD:2 |
+| test_logging.rs:155:31:155:38 | password | test_logging.rs:155:15:155:38 | MacroExpr | provenance | |
+| test_logging.rs:158:23:158:46 | MacroExpr | test_logging.rs:158:16:158:47 | ...::panic_fmt | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:158:39:158:46 | password | test_logging.rs:158:23:158:46 | MacroExpr | provenance | |
+| test_logging.rs:159:22:159:45 | MacroExpr | test_logging.rs:159:16:159:46 | ...::panic_fmt | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:159:38:159:45 | password | test_logging.rs:159:22:159:45 | MacroExpr | provenance | |
+| test_logging.rs:160:31:160:54 | MacroExpr | test_logging.rs:160:16:160:55 | ...::panic_fmt | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:160:47:160:54 | password | test_logging.rs:160:31:160:54 | MacroExpr | provenance | |
+| test_logging.rs:161:29:161:52 | MacroExpr | test_logging.rs:161:16:161:53 | ...::panic_fmt | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:161:45:161:52 | password | test_logging.rs:161:29:161:52 | MacroExpr | provenance | |
+| test_logging.rs:162:31:162:54 | MacroExpr | test_logging.rs:162:16:162:55 | ...::panic_fmt | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:162:47:162:54 | password | test_logging.rs:162:31:162:54 | MacroExpr | provenance | |
+| test_logging.rs:165:37:165:60 | MacroExpr | test_logging.rs:165:16:165:61 | ...::panic_fmt | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:165:53:165:60 | password | test_logging.rs:165:37:165:60 | MacroExpr | provenance | |
+| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:17 |
+| test_logging.rs:168:34:168:66 | res | test_logging.rs:168:42:168:65 | { ... } | provenance | |
+| test_logging.rs:168:34:168:75 | ... .as_str(...) | test_logging.rs:168:27:168:32 | expect | provenance | MaD:4 Sink:MaD:4 |
+| test_logging.rs:168:42:168:65 | ...::format(...) | test_logging.rs:168:34:168:66 | res | provenance | |
+| test_logging.rs:168:42:168:65 | ...::must_use(...) | test_logging.rs:168:34:168:66 | MacroExpr | provenance | |
+| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:19 |
+| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:18 |
+| test_logging.rs:168:58:168:65 | password | test_logging.rs:168:42:168:65 | MacroExpr | provenance | |
nodes
+| test_logging.rs:42:5:42:36 | ...::log | semmle.label | ...::log |
+| test_logging.rs:42:12:42:35 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:42:28:42:35 | password | semmle.label | password |
+| test_logging.rs:43:5:43:36 | ...::log | semmle.label | ...::log |
+| test_logging.rs:43:12:43:35 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:43:28:43:35 | password | semmle.label | password |
+| test_logging.rs:44:5:44:35 | ...::log | semmle.label | ...::log |
+| test_logging.rs:44:11:44:34 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:44:27:44:34 | password | semmle.label | password |
+| test_logging.rs:45:5:45:36 | ...::log | semmle.label | ...::log |
+| test_logging.rs:45:12:45:35 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:45:28:45:35 | password | semmle.label | password |
+| test_logging.rs:46:5:46:35 | ...::log | semmle.label | ...::log |
+| test_logging.rs:46:11:46:34 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:46:27:46:34 | password | semmle.label | password |
+| test_logging.rs:47:5:47:48 | ...::log | semmle.label | ...::log |
+| test_logging.rs:47:24:47:47 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:47:40:47:47 | password | semmle.label | password |
+| test_logging.rs:52:5:52:36 | ...::log | semmle.label | ...::log |
+| test_logging.rs:52:12:52:35 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:52:28:52:35 | password | semmle.label | password |
+| test_logging.rs:54:5:54:49 | ...::log | semmle.label | ...::log |
+| test_logging.rs:54:12:54:48 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:54:41:54:48 | password | semmle.label | password |
+| test_logging.rs:56:5:56:47 | ...::log | semmle.label | ...::log |
+| test_logging.rs:56:12:56:46 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:56:39:56:46 | password | semmle.label | password |
+| test_logging.rs:57:5:57:34 | ...::log | semmle.label | ...::log |
+| test_logging.rs:57:12:57:33 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:57:24:57:31 | password | semmle.label | password |
+| test_logging.rs:58:5:58:36 | ...::log | semmle.label | ...::log |
+| test_logging.rs:58:12:58:35 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:58:24:58:31 | password | semmle.label | password |
+| test_logging.rs:60:5:60:54 | ...::log | semmle.label | ...::log |
+| test_logging.rs:60:30:60:53 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:60:46:60:53 | password | semmle.label | password |
+| test_logging.rs:65:5:65:48 | ...::log | semmle.label | ...::log |
+| test_logging.rs:65:24:65:47 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:65:40:65:47 | password | semmle.label | password |
+| test_logging.rs:67:5:67:66 | ...::log | semmle.label | ...::log |
+| test_logging.rs:67:42:67:65 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:67:58:67:65 | password | semmle.label | password |
+| test_logging.rs:72:5:72:47 | ...::log::<...> | semmle.label | ...::log::<...> |
+| test_logging.rs:72:23:72:46 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:72:39:72:46 | password | semmle.label | password |
+| test_logging.rs:74:5:74:65 | ...::log::<...> | semmle.label | ...::log::<...> |
+| test_logging.rs:74:41:74:64 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:74:57:74:64 | password | semmle.label | password |
+| test_logging.rs:76:5:76:47 | ...::log::<...> | semmle.label | ...::log::<...> |
+| test_logging.rs:76:23:76:46 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:76:39:76:46 | password | semmle.label | password |
+| test_logging.rs:82:5:82:44 | ...::log::<...> | semmle.label | ...::log::<...> |
+| test_logging.rs:82:20:82:43 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:82:36:82:43 | password | semmle.label | password |
+| test_logging.rs:84:5:84:62 | ...::log::<...> | semmle.label | ...::log::<...> |
+| test_logging.rs:84:38:84:61 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:84:54:84:61 | password | semmle.label | password |
+| test_logging.rs:86:5:86:44 | ...::log::<...> | semmle.label | ...::log::<...> |
+| test_logging.rs:86:20:86:43 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:86:36:86:43 | password | semmle.label | password |
+| test_logging.rs:99:9:99:10 | m3 | semmle.label | m3 |
+| test_logging.rs:99:14:99:46 | res | semmle.label | res |
+| test_logging.rs:99:22:99:45 | ...::format(...) | semmle.label | ...::format(...) |
+| test_logging.rs:99:22:99:45 | ...::must_use(...) | semmle.label | ...::must_use(...) |
+| test_logging.rs:99:22:99:45 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:99:22:99:45 | { ... } | semmle.label | { ... } |
+| test_logging.rs:99:38:99:45 | password | semmle.label | password |
+| test_logging.rs:100:5:100:19 | ...::log | semmle.label | ...::log |
+| test_logging.rs:100:11:100:18 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:118:5:118:42 | ...::log | semmle.label | ...::log |
+| test_logging.rs:118:12:118:41 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:118:28:118:41 | get_password(...) | semmle.label | get_password(...) |
+| test_logging.rs:129:9:129:10 | t1 [tuple.1] | semmle.label | t1 [tuple.1] |
+| test_logging.rs:129:14:129:33 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] |
+| test_logging.rs:129:25:129:32 | password | semmle.label | password |
+| test_logging.rs:131:5:131:32 | ...::log | semmle.label | ...::log |
+| test_logging.rs:131:12:131:31 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:131:28:131:29 | t1 [tuple.1] | semmle.label | t1 [tuple.1] |
+| test_logging.rs:131:28:131:31 | t1.1 | semmle.label | t1.1 |
+| test_logging.rs:152:5:152:36 | ...::_print | semmle.label | ...::_print |
+| test_logging.rs:152:12:152:35 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:152:28:152:35 | password | semmle.label | password |
+| test_logging.rs:153:5:153:38 | ...::_print | semmle.label | ...::_print |
+| test_logging.rs:153:14:153:37 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:153:30:153:37 | password | semmle.label | password |
+| test_logging.rs:154:5:154:37 | ...::_eprint | semmle.label | ...::_eprint |
+| test_logging.rs:154:13:154:36 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:154:29:154:36 | password | semmle.label | password |
+| test_logging.rs:155:5:155:39 | ...::_eprint | semmle.label | ...::_eprint |
+| test_logging.rs:155:15:155:38 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:155:31:155:38 | password | semmle.label | password |
+| test_logging.rs:158:16:158:47 | ...::panic_fmt | semmle.label | ...::panic_fmt |
+| test_logging.rs:158:23:158:46 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:158:39:158:46 | password | semmle.label | password |
+| test_logging.rs:159:16:159:46 | ...::panic_fmt | semmle.label | ...::panic_fmt |
+| test_logging.rs:159:22:159:45 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:159:38:159:45 | password | semmle.label | password |
+| test_logging.rs:160:16:160:55 | ...::panic_fmt | semmle.label | ...::panic_fmt |
+| test_logging.rs:160:31:160:54 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:160:47:160:54 | password | semmle.label | password |
+| test_logging.rs:161:16:161:53 | ...::panic_fmt | semmle.label | ...::panic_fmt |
+| test_logging.rs:161:29:161:52 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:161:45:161:52 | password | semmle.label | password |
+| test_logging.rs:162:16:162:55 | ...::panic_fmt | semmle.label | ...::panic_fmt |
+| test_logging.rs:162:31:162:54 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:162:47:162:54 | password | semmle.label | password |
+| test_logging.rs:165:16:165:61 | ...::panic_fmt | semmle.label | ...::panic_fmt |
+| test_logging.rs:165:37:165:60 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:165:53:165:60 | password | semmle.label | password |
+| test_logging.rs:168:27:168:32 | expect | semmle.label | expect |
+| test_logging.rs:168:34:168:66 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:168:34:168:66 | res | semmle.label | res |
+| test_logging.rs:168:34:168:75 | ... .as_str(...) | semmle.label | ... .as_str(...) |
+| test_logging.rs:168:42:168:65 | ...::format(...) | semmle.label | ...::format(...) |
+| test_logging.rs:168:42:168:65 | ...::must_use(...) | semmle.label | ...::must_use(...) |
+| test_logging.rs:168:42:168:65 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:168:42:168:65 | { ... } | semmle.label | { ... } |
+| test_logging.rs:168:58:168:65 | password | semmle.label | password |
subpaths
diff --git a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
index c015bdb24d4c..0b1e55a1815a 100644
--- a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
+++ b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
@@ -39,51 +39,51 @@ impl std::fmt::Display for MyStruct2 {
fn test_log(harmless: String, password: String, encrypted_password: String) {
// logging macros
- debug!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
- error!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
- info!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
- trace!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
- warn!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
- log!(Level::Error, "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ debug!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
+ error!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
+ info!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
+ trace!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
+ warn!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
+ log!(Level::Error, "message = {}", password); // $ Source Alert[rust/cleartext-logging]
// debug! macro, various formatting
debug!("message");
debug!("message = {}", harmless);
- debug!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ debug!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
debug!("message = {}", encrypted_password);
- debug!("message = {} {}", harmless, password); // $ MISSING: Alert[rust/cleartext-logging]
+ debug!("message = {} {}", harmless, password); // $ Source Alert[rust/cleartext-logging]
debug!("message = {harmless}");
- debug!("message = {harmless} {}", password); // $ MISSING: Alert[rust/cleartext-logging]
- debug!("message = {password}"); // $ MISSING: Alert[rust/cleartext-logging]
- debug!("message = {password:?}"); // $ MISSING: Alert[rust/cleartext-logging]
+ debug!("message = {harmless} {}", password); // $ Source Alert[rust/cleartext-logging]
+ debug!("message = {password}"); // $ Source Alert[rust/cleartext-logging]
+ debug!("message = {password:?}"); // $ Source Alert[rust/cleartext-logging]
debug!(target: "target", "message = {}", harmless);
- debug!(target: "target", "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ debug!(target: "target", "message = {}", password); // $ Source Alert[rust/cleartext-logging]
debug!(target: &password, "message = {}", harmless); // $ MISSING: Alert[rust/cleartext-logging]
// log! macro, various formatting
log!(Level::Error, "message = {}", harmless);
- log!(Level::Error, "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ log!(Level::Error, "message = {}", password); // $ Source Alert[rust/cleartext-logging]
log!(target: "target", Level::Error, "message = {}", harmless);
- log!(target: "target", Level::Error, "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ log!(target: "target", Level::Error, "message = {}", password); // $ Source Alert[rust/cleartext-logging]
log!(target: &password, Level::Error, "message = {}", harmless); // $ MISSING: Alert[rust/cleartext-logging]
// structured logging
error!(value = 1; "message = {}", harmless);
- error!(value = 1; "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(value = 1; "message = {}", password); // $ Source Alert[rust/cleartext-logging]
error!(target: "target", value = 1; "message");
- error!(target: "target", value = 1; "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(target: "target", value = 1; "message = {}", password); // $ Source Alert[rust/cleartext-logging]
error!(target: &password, value = 1; "message"); // $ MISSING: Alert[rust/cleartext-logging]
- error!(value = 1; "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(value = 1; "message = {}", password); // $ Source Alert[rust/cleartext-logging]
error!(value = password.as_str(); "message"); // $ MISSING: Alert[rust/cleartext-logging]
error!(value:? = password.as_str(); "message"); // $ MISSING: Alert[rust/cleartext-logging]
let value1 = 1;
error!(value1; "message = {}", harmless);
- error!(value1; "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(value1; "message = {}", password); // $ Source Alert[rust/cleartext-logging]
error!(target: "target", value1; "message");
- error!(target: "target", value1; "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(target: "target", value1; "message = {}", password); // $ Source Alert[rust/cleartext-logging]
error!(target: &password, value1; "message"); // $ MISSING: Alert[rust/cleartext-logging]
- error!(value1; "message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(value1; "message = {}", password); // $ Source Alert[rust/cleartext-logging]
let value2 = password.as_str();
error!(value2; "message"); // $ MISSING: Alert[rust/cleartext-logging]
@@ -96,8 +96,8 @@ fn test_log(harmless: String, password: String, encrypted_password: String) {
let m2 = "message = ".to_string() + &password; // $ MISSING: Source=m2
info!("{}", m2); // $ MISSING: Alert[rust/cleartext-logging]=m2
- let m3 = format!("message = {}", password); // $ MISSING:=m3
- info!("{}", m3); // $ MISSING: Alert[rust/cleartext-logging]=m3
+ let m3 = format!("message = {}", password); // $ Source=m3
+ info!("{}", m3); // $ Alert[rust/cleartext-logging]=m3
let mut m4 = String::new();
write!(&mut m4, "message = {}", password); // $ MISSING: Source=m4
@@ -115,7 +115,7 @@ fn test_log(harmless: String, password: String, encrypted_password: String) {
}
// logging with a call
- trace!("message = {}", get_password()); // $ MISSING: Alert[rust/cleartext-logging]
+ trace!("message = {}", get_password()); // $ Source Alert[rust/cleartext-logging]
let str1 = "123456".to_string();
trace!("message = {}", &str1); // $ MISSING: Alert[rust/cleartext-logging]
@@ -126,9 +126,9 @@ fn test_log(harmless: String, password: String, encrypted_password: String) {
trace!("message = {}", &str2);
// logging from a tuple
- let t1 = (harmless, password); // $ MISSING:=t1
+ let t1 = (harmless, password); // $ Source=t1
trace!("message = {}", t1.0);
- trace!("message = {}", t1.1); // $ MISSING: Alert[rust/cleartext-logging]=t1
+ trace!("message = {}", t1.1); // $ Alert[rust/cleartext-logging]=t1
trace!("message = {:?}", t1); // $ MISSING: Alert[rust/cleartext-logging]=t1
trace!("message = {:#?}", t1); // $ MISSING: Alert[rust/cleartext-logging]=t1
@@ -149,23 +149,23 @@ fn test_log(harmless: String, password: String, encrypted_password: String) {
}
fn test_std(password: String, i: i32, opt_i: Option) {
- print!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
- println!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
- eprint!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
- eprintln!("message = {}", password); // $ MISSING: Alert[rust/cleartext-logging]
+ print!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
+ println!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
+ eprint!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
+ eprintln!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
match i {
- 1 => { panic!("message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
- 2 => { todo!("message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
- 3 => { unimplemented!("message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
- 4 => { unreachable!("message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
- 5 => { assert!(false, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 1 => { panic!("message = {}", password); } // $ Source Alert[rust/cleartext-logging]
+ 2 => { todo!("message = {}", password); } // $ Source Alert[rust/cleartext-logging]
+ 3 => { unimplemented!("message = {}", password); } // $ Source Alert[rust/cleartext-logging]
+ 4 => { unreachable!("message = {}", password); } // $ Source Alert[rust/cleartext-logging]
+ 5 => { assert!(false, "message = {}", password); } // $ Source Alert[rust/cleartext-logging]
6 => { assert_eq!(1, 2, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
7 => { assert_ne!(1, 1, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
- 8 => { debug_assert!(false, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 8 => { debug_assert!(false, "message = {}", password); } // $ Source Alert[rust/cleartext-logging]
9 => { debug_assert_eq!(1, 2, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
10 => { debug_assert_ne!(1, 1, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
- 11 => { _ = opt_i.expect(format!("message = {}", password).as_str()); } // $ MISSING: Alert[rust/cleartext-logging]
+ 11 => { _ = opt_i.expect(format!("message = {}", password).as_str()); } // $ Source Alert[rust/cleartext-logging]
_ => {}
}
From 484331c3035f19b0cb5383774ccabdba22fec1a9 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Wed, 22 Jan 2025 17:27:42 +0000
Subject: [PATCH 05/21] Rust: Model StdoutLock, StderrLock methods and
String.as_bytes.
---
.../lib/codeql/rust/frameworks/log.model.yml | 4 +
.../frameworks/stdlib/lang-core.model.yml | 1 +
.../CWE-312/CleartextLogging.expected | 96 ++++++++++++++++---
.../security/CWE-312/test_logging.rs | 8 +-
4 files changed, 93 insertions(+), 16 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/frameworks/log.model.yml b/rust/ql/lib/codeql/rust/frameworks/log.model.yml
index 2dcdb61fb625..fe295141fa7d 100644
--- a/rust/ql/lib/codeql/rust/frameworks/log.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/log.model.yml
@@ -6,5 +6,9 @@ extensions:
- ["repo:https://github.com/rust-lang/log:log", "crate::__private_api::log", "Argument[0]", "log-injection", "manual"]
- ["lang:std", "crate::io::stdio::_print", "Argument[0]", "log-injection", "manual"]
- ["lang:std", "crate::io::stdio::_eprint", "Argument[0]", "log-injection", "manual"]
+ - ["lang:std", "::write", "Argument[0]", "log-injection", "manual"]
+ - ["lang:std", "::write_all", "Argument[0]", "log-injection", "manual"]
+ - ["lang:std", "::write", "Argument[0]", "log-injection", "manual"]
+ - ["lang:std", "::write_all", "Argument[0]", "log-injection", "manual"]
- ["lang:core", "crate::panicking::panic_fmt", "Argument[0]", "log-injection", "manual"]
- ["lang:core", "::expect", "Argument[0]", "log-injection", "manual"]
diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml
index 4cf937e693b8..4fad34e36b5e 100644
--- a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml
@@ -13,6 +13,7 @@ extensions:
- ["lang:core", "::unwrap_or", "Argument[0]", "ReturnValue", "value", "manual"]
# String
- ["lang:alloc", "::as_str", "Argument[self]", "ReturnValue", "taint", "manual"]
+ - ["lang:alloc", "::as_bytes", "Argument[self]", "ReturnValue", "taint", "manual"]
# Hint
- ["lang:core", "crate::hint::must_use", "Argument[0]", "ReturnValue", "value", "manual"]
# Fmt
diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
index 1a60f2884338..fc1e49a3d16f 100644
--- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
+++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
@@ -33,6 +33,10 @@
| test_logging.rs:162:16:162:55 | ...::panic_fmt | test_logging.rs:162:47:162:54 | password | test_logging.rs:162:16:162:55 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:162:47:162:54 | password | password |
| test_logging.rs:165:16:165:61 | ...::panic_fmt | test_logging.rs:165:53:165:60 | password | test_logging.rs:165:16:165:61 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:165:53:165:60 | password | password |
| test_logging.rs:168:27:168:32 | expect | test_logging.rs:168:58:168:65 | password | test_logging.rs:168:27:168:32 | expect | This operation writes 'expect' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:168:58:168:65 | password | password |
+| test_logging.rs:174:30:174:34 | write | test_logging.rs:174:60:174:67 | password | test_logging.rs:174:30:174:34 | write | This operation writes 'write' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:174:60:174:67 | password | password |
+| test_logging.rs:175:30:175:38 | write_all | test_logging.rs:175:64:175:71 | password | test_logging.rs:175:30:175:38 | write_all | This operation writes 'write_all' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:175:64:175:71 | password | password |
+| test_logging.rs:178:9:178:13 | write | test_logging.rs:178:39:178:46 | password | test_logging.rs:178:9:178:13 | write | This operation writes 'write' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:178:39:178:46 | password | password |
+| test_logging.rs:181:9:181:13 | write | test_logging.rs:181:39:181:46 | password | test_logging.rs:181:9:181:13 | write | This operation writes 'write' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:181:39:181:46 | password | password |
edges
| test_logging.rs:42:12:42:35 | MacroExpr | test_logging.rs:42:5:42:36 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:42:28:42:35 | password | test_logging.rs:42:12:42:35 | MacroExpr | provenance | |
@@ -78,8 +82,8 @@ edges
| test_logging.rs:99:14:99:46 | res | test_logging.rs:99:22:99:45 | { ... } | provenance | |
| test_logging.rs:99:22:99:45 | ...::format(...) | test_logging.rs:99:14:99:46 | res | provenance | |
| test_logging.rs:99:22:99:45 | ...::must_use(...) | test_logging.rs:99:9:99:10 | m3 | provenance | |
-| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:19 |
-| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:18 |
+| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:24 |
+| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:23 |
| test_logging.rs:99:38:99:45 | password | test_logging.rs:99:22:99:45 | MacroExpr | provenance | |
| test_logging.rs:100:11:100:18 | MacroExpr | test_logging.rs:100:5:100:19 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:118:12:118:41 | MacroExpr | test_logging.rs:118:5:118:42 | ...::log | provenance | MaD:0 Sink:MaD:0 |
@@ -98,26 +102,58 @@ edges
| test_logging.rs:154:29:154:36 | password | test_logging.rs:154:13:154:36 | MacroExpr | provenance | |
| test_logging.rs:155:15:155:38 | MacroExpr | test_logging.rs:155:5:155:39 | ...::_eprint | provenance | MaD:2 Sink:MaD:2 |
| test_logging.rs:155:31:155:38 | password | test_logging.rs:155:15:155:38 | MacroExpr | provenance | |
-| test_logging.rs:158:23:158:46 | MacroExpr | test_logging.rs:158:16:158:47 | ...::panic_fmt | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:158:23:158:46 | MacroExpr | test_logging.rs:158:16:158:47 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
| test_logging.rs:158:39:158:46 | password | test_logging.rs:158:23:158:46 | MacroExpr | provenance | |
-| test_logging.rs:159:22:159:45 | MacroExpr | test_logging.rs:159:16:159:46 | ...::panic_fmt | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:159:22:159:45 | MacroExpr | test_logging.rs:159:16:159:46 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
| test_logging.rs:159:38:159:45 | password | test_logging.rs:159:22:159:45 | MacroExpr | provenance | |
-| test_logging.rs:160:31:160:54 | MacroExpr | test_logging.rs:160:16:160:55 | ...::panic_fmt | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:160:31:160:54 | MacroExpr | test_logging.rs:160:16:160:55 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
| test_logging.rs:160:47:160:54 | password | test_logging.rs:160:31:160:54 | MacroExpr | provenance | |
-| test_logging.rs:161:29:161:52 | MacroExpr | test_logging.rs:161:16:161:53 | ...::panic_fmt | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:161:29:161:52 | MacroExpr | test_logging.rs:161:16:161:53 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
| test_logging.rs:161:45:161:52 | password | test_logging.rs:161:29:161:52 | MacroExpr | provenance | |
-| test_logging.rs:162:31:162:54 | MacroExpr | test_logging.rs:162:16:162:55 | ...::panic_fmt | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:162:31:162:54 | MacroExpr | test_logging.rs:162:16:162:55 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
| test_logging.rs:162:47:162:54 | password | test_logging.rs:162:31:162:54 | MacroExpr | provenance | |
-| test_logging.rs:165:37:165:60 | MacroExpr | test_logging.rs:165:16:165:61 | ...::panic_fmt | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:165:37:165:60 | MacroExpr | test_logging.rs:165:16:165:61 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
| test_logging.rs:165:53:165:60 | password | test_logging.rs:165:37:165:60 | MacroExpr | provenance | |
-| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:17 |
+| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:21 |
| test_logging.rs:168:34:168:66 | res | test_logging.rs:168:42:168:65 | { ... } | provenance | |
-| test_logging.rs:168:34:168:75 | ... .as_str(...) | test_logging.rs:168:27:168:32 | expect | provenance | MaD:4 Sink:MaD:4 |
+| test_logging.rs:168:34:168:75 | ... .as_str(...) | test_logging.rs:168:27:168:32 | expect | provenance | MaD:8 Sink:MaD:8 |
| test_logging.rs:168:42:168:65 | ...::format(...) | test_logging.rs:168:34:168:66 | res | provenance | |
| test_logging.rs:168:42:168:65 | ...::must_use(...) | test_logging.rs:168:34:168:66 | MacroExpr | provenance | |
-| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:19 |
-| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:18 |
+| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:24 |
+| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:23 |
| test_logging.rs:168:58:168:65 | password | test_logging.rs:168:42:168:65 | MacroExpr | provenance | |
+| test_logging.rs:174:36:174:68 | MacroExpr | test_logging.rs:174:36:174:79 | ... .as_bytes(...) | provenance | MaD:22 |
+| test_logging.rs:174:36:174:68 | res | test_logging.rs:174:44:174:67 | { ... } | provenance | |
+| test_logging.rs:174:36:174:79 | ... .as_bytes(...) | test_logging.rs:174:30:174:34 | write | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:174:44:174:67 | ...::format(...) | test_logging.rs:174:36:174:68 | res | provenance | |
+| test_logging.rs:174:44:174:67 | ...::must_use(...) | test_logging.rs:174:36:174:68 | MacroExpr | provenance | |
+| test_logging.rs:174:44:174:67 | MacroExpr | test_logging.rs:174:44:174:67 | ...::format(...) | provenance | MaD:24 |
+| test_logging.rs:174:44:174:67 | { ... } | test_logging.rs:174:44:174:67 | ...::must_use(...) | provenance | MaD:23 |
+| test_logging.rs:174:60:174:67 | password | test_logging.rs:174:44:174:67 | MacroExpr | provenance | |
+| test_logging.rs:175:40:175:72 | MacroExpr | test_logging.rs:175:40:175:83 | ... .as_bytes(...) | provenance | MaD:22 |
+| test_logging.rs:175:40:175:72 | res | test_logging.rs:175:48:175:71 | { ... } | provenance | |
+| test_logging.rs:175:40:175:83 | ... .as_bytes(...) | test_logging.rs:175:30:175:38 | write_all | provenance | MaD:5 Sink:MaD:5 |
+| test_logging.rs:175:48:175:71 | ...::format(...) | test_logging.rs:175:40:175:72 | res | provenance | |
+| test_logging.rs:175:48:175:71 | ...::must_use(...) | test_logging.rs:175:40:175:72 | MacroExpr | provenance | |
+| test_logging.rs:175:48:175:71 | MacroExpr | test_logging.rs:175:48:175:71 | ...::format(...) | provenance | MaD:24 |
+| test_logging.rs:175:48:175:71 | { ... } | test_logging.rs:175:48:175:71 | ...::must_use(...) | provenance | MaD:23 |
+| test_logging.rs:175:64:175:71 | password | test_logging.rs:175:48:175:71 | MacroExpr | provenance | |
+| test_logging.rs:178:15:178:47 | MacroExpr | test_logging.rs:178:15:178:58 | ... .as_bytes(...) | provenance | MaD:22 |
+| test_logging.rs:178:15:178:47 | res | test_logging.rs:178:23:178:46 | { ... } | provenance | |
+| test_logging.rs:178:15:178:58 | ... .as_bytes(...) | test_logging.rs:178:9:178:13 | write | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:178:23:178:46 | ...::format(...) | test_logging.rs:178:15:178:47 | res | provenance | |
+| test_logging.rs:178:23:178:46 | ...::must_use(...) | test_logging.rs:178:15:178:47 | MacroExpr | provenance | |
+| test_logging.rs:178:23:178:46 | MacroExpr | test_logging.rs:178:23:178:46 | ...::format(...) | provenance | MaD:24 |
+| test_logging.rs:178:23:178:46 | { ... } | test_logging.rs:178:23:178:46 | ...::must_use(...) | provenance | MaD:23 |
+| test_logging.rs:178:39:178:46 | password | test_logging.rs:178:23:178:46 | MacroExpr | provenance | |
+| test_logging.rs:181:15:181:47 | MacroExpr | test_logging.rs:181:15:181:58 | ... .as_bytes(...) | provenance | MaD:22 |
+| test_logging.rs:181:15:181:47 | res | test_logging.rs:181:23:181:46 | { ... } | provenance | |
+| test_logging.rs:181:15:181:58 | ... .as_bytes(...) | test_logging.rs:181:9:181:13 | write | provenance | MaD:4 Sink:MaD:4 |
+| test_logging.rs:181:23:181:46 | ...::format(...) | test_logging.rs:181:15:181:47 | res | provenance | |
+| test_logging.rs:181:23:181:46 | ...::must_use(...) | test_logging.rs:181:15:181:47 | MacroExpr | provenance | |
+| test_logging.rs:181:23:181:46 | MacroExpr | test_logging.rs:181:23:181:46 | ...::format(...) | provenance | MaD:24 |
+| test_logging.rs:181:23:181:46 | { ... } | test_logging.rs:181:23:181:46 | ...::must_use(...) | provenance | MaD:23 |
+| test_logging.rs:181:39:181:46 | password | test_logging.rs:181:23:181:46 | MacroExpr | provenance | |
nodes
| test_logging.rs:42:5:42:36 | ...::log | semmle.label | ...::log |
| test_logging.rs:42:12:42:35 | MacroExpr | semmle.label | MacroExpr |
@@ -237,4 +273,40 @@ nodes
| test_logging.rs:168:42:168:65 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:168:42:168:65 | { ... } | semmle.label | { ... } |
| test_logging.rs:168:58:168:65 | password | semmle.label | password |
+| test_logging.rs:174:30:174:34 | write | semmle.label | write |
+| test_logging.rs:174:36:174:68 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:174:36:174:68 | res | semmle.label | res |
+| test_logging.rs:174:36:174:79 | ... .as_bytes(...) | semmle.label | ... .as_bytes(...) |
+| test_logging.rs:174:44:174:67 | ...::format(...) | semmle.label | ...::format(...) |
+| test_logging.rs:174:44:174:67 | ...::must_use(...) | semmle.label | ...::must_use(...) |
+| test_logging.rs:174:44:174:67 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:174:44:174:67 | { ... } | semmle.label | { ... } |
+| test_logging.rs:174:60:174:67 | password | semmle.label | password |
+| test_logging.rs:175:30:175:38 | write_all | semmle.label | write_all |
+| test_logging.rs:175:40:175:72 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:175:40:175:72 | res | semmle.label | res |
+| test_logging.rs:175:40:175:83 | ... .as_bytes(...) | semmle.label | ... .as_bytes(...) |
+| test_logging.rs:175:48:175:71 | ...::format(...) | semmle.label | ...::format(...) |
+| test_logging.rs:175:48:175:71 | ...::must_use(...) | semmle.label | ...::must_use(...) |
+| test_logging.rs:175:48:175:71 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:175:48:175:71 | { ... } | semmle.label | { ... } |
+| test_logging.rs:175:64:175:71 | password | semmle.label | password |
+| test_logging.rs:178:9:178:13 | write | semmle.label | write |
+| test_logging.rs:178:15:178:47 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:178:15:178:47 | res | semmle.label | res |
+| test_logging.rs:178:15:178:58 | ... .as_bytes(...) | semmle.label | ... .as_bytes(...) |
+| test_logging.rs:178:23:178:46 | ...::format(...) | semmle.label | ...::format(...) |
+| test_logging.rs:178:23:178:46 | ...::must_use(...) | semmle.label | ...::must_use(...) |
+| test_logging.rs:178:23:178:46 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:178:23:178:46 | { ... } | semmle.label | { ... } |
+| test_logging.rs:178:39:178:46 | password | semmle.label | password |
+| test_logging.rs:181:9:181:13 | write | semmle.label | write |
+| test_logging.rs:181:15:181:47 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:181:15:181:47 | res | semmle.label | res |
+| test_logging.rs:181:15:181:58 | ... .as_bytes(...) | semmle.label | ... .as_bytes(...) |
+| test_logging.rs:181:23:181:46 | ...::format(...) | semmle.label | ...::format(...) |
+| test_logging.rs:181:23:181:46 | ...::must_use(...) | semmle.label | ...::must_use(...) |
+| test_logging.rs:181:23:181:46 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:181:23:181:46 | { ... } | semmle.label | { ... } |
+| test_logging.rs:181:39:181:46 | password | semmle.label | password |
subpaths
diff --git a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
index 0b1e55a1815a..f7aeb8c19905 100644
--- a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
+++ b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
@@ -171,12 +171,12 @@ fn test_std(password: String, i: i32, opt_i: Option) {
std::io::stdout().lock().write_fmt(format_args!("message = {}", password)); // $ MISSING: Alert[rust/cleartext-logging]
std::io::stderr().lock().write_fmt(format_args!("message = {}", password)); // $ MISSING: Alert[rust/cleartext-logging]
- std::io::stdout().lock().write(format!("message = {}", password).as_bytes()); // $ MISSING: Alert[rust/cleartext-logging]
- std::io::stdout().lock().write_all(format!("message = {}", password).as_bytes()); // $ MISSING: Alert[rust/cleartext-logging]
+ std::io::stdout().lock().write(format!("message = {}", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
+ std::io::stdout().lock().write_all(format!("message = {}", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
let mut out = std::io::stdout().lock();
- out.write(format!("message = {}", password).as_bytes()); // $ MISSING: Alert[rust/cleartext-logging]
+ out.write(format!("message = {}", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
let mut err = std::io::stderr().lock();
- err.write(format!("message = {}", password).as_bytes()); // $ MISSING: Alert[rust/cleartext-logging]
+ err.write(format!("message = {}", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
}
From 2bbf493991026229901eefb2b5945461a458bf09 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Wed, 22 Jan 2025 17:58:07 +0000
Subject: [PATCH 06/21] Rust: Model assert_failed.
---
.../lib/codeql/rust/frameworks/log.model.yml | 1 +
.../CWE-312/CleartextLogging.expected | 72 +++++++++++++------
.../security/CWE-312/test_logging.rs | 8 +--
3 files changed, 57 insertions(+), 24 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/frameworks/log.model.yml b/rust/ql/lib/codeql/rust/frameworks/log.model.yml
index fe295141fa7d..43105c601426 100644
--- a/rust/ql/lib/codeql/rust/frameworks/log.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/log.model.yml
@@ -11,4 +11,5 @@ extensions:
- ["lang:std", "::write", "Argument[0]", "log-injection", "manual"]
- ["lang:std", "::write_all", "Argument[0]", "log-injection", "manual"]
- ["lang:core", "crate::panicking::panic_fmt", "Argument[0]", "log-injection", "manual"]
+ - ["lang:core", "crate::panicking::assert_failed", "Argument[3].Variant[crate::option::Option::Some(0)]", "log-injection", "manual"]
- ["lang:core", "::expect", "Argument[0]", "log-injection", "manual"]
diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
index fc1e49a3d16f..7b278bbdb761 100644
--- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
+++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
@@ -31,7 +31,11 @@
| test_logging.rs:160:16:160:55 | ...::panic_fmt | test_logging.rs:160:47:160:54 | password | test_logging.rs:160:16:160:55 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:160:47:160:54 | password | password |
| test_logging.rs:161:16:161:53 | ...::panic_fmt | test_logging.rs:161:45:161:52 | password | test_logging.rs:161:16:161:53 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:161:45:161:52 | password | password |
| test_logging.rs:162:16:162:55 | ...::panic_fmt | test_logging.rs:162:47:162:54 | password | test_logging.rs:162:16:162:55 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:162:47:162:54 | password | password |
+| test_logging.rs:163:16:163:57 | ...::assert_failed | test_logging.rs:163:49:163:56 | password | test_logging.rs:163:16:163:57 | ...::assert_failed | This operation writes '...::assert_failed' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:163:49:163:56 | password | password |
+| test_logging.rs:164:16:164:57 | ...::assert_failed | test_logging.rs:164:49:164:56 | password | test_logging.rs:164:16:164:57 | ...::assert_failed | This operation writes '...::assert_failed' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:164:49:164:56 | password | password |
| test_logging.rs:165:16:165:61 | ...::panic_fmt | test_logging.rs:165:53:165:60 | password | test_logging.rs:165:16:165:61 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:165:53:165:60 | password | password |
+| test_logging.rs:166:16:166:63 | ...::assert_failed | test_logging.rs:166:55:166:62 | password | test_logging.rs:166:16:166:63 | ...::assert_failed | This operation writes '...::assert_failed' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:166:55:166:62 | password | password |
+| test_logging.rs:167:17:167:64 | ...::assert_failed | test_logging.rs:167:56:167:63 | password | test_logging.rs:167:17:167:64 | ...::assert_failed | This operation writes '...::assert_failed' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:167:56:167:63 | password | password |
| test_logging.rs:168:27:168:32 | expect | test_logging.rs:168:58:168:65 | password | test_logging.rs:168:27:168:32 | expect | This operation writes 'expect' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:168:58:168:65 | password | password |
| test_logging.rs:174:30:174:34 | write | test_logging.rs:174:60:174:67 | password | test_logging.rs:174:30:174:34 | write | This operation writes 'write' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:174:60:174:67 | password | password |
| test_logging.rs:175:30:175:38 | write_all | test_logging.rs:175:64:175:71 | password | test_logging.rs:175:30:175:38 | write_all | This operation writes 'write_all' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:175:64:175:71 | password | password |
@@ -82,8 +86,8 @@ edges
| test_logging.rs:99:14:99:46 | res | test_logging.rs:99:22:99:45 | { ... } | provenance | |
| test_logging.rs:99:22:99:45 | ...::format(...) | test_logging.rs:99:14:99:46 | res | provenance | |
| test_logging.rs:99:22:99:45 | ...::must_use(...) | test_logging.rs:99:9:99:10 | m3 | provenance | |
-| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:24 |
-| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:23 |
+| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:25 |
+| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:24 |
| test_logging.rs:99:38:99:45 | password | test_logging.rs:99:22:99:45 | MacroExpr | provenance | |
| test_logging.rs:100:11:100:18 | MacroExpr | test_logging.rs:100:5:100:19 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:118:12:118:41 | MacroExpr | test_logging.rs:118:5:118:42 | ...::log | provenance | MaD:0 Sink:MaD:0 |
@@ -112,47 +116,59 @@ edges
| test_logging.rs:161:45:161:52 | password | test_logging.rs:161:29:161:52 | MacroExpr | provenance | |
| test_logging.rs:162:31:162:54 | MacroExpr | test_logging.rs:162:16:162:55 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
| test_logging.rs:162:47:162:54 | password | test_logging.rs:162:31:162:54 | MacroExpr | provenance | |
+| test_logging.rs:163:33:163:56 | ...::Some(...) [Some] | test_logging.rs:163:16:163:57 | ...::assert_failed | provenance | MaD:8 Sink:MaD:8 |
+| test_logging.rs:163:33:163:56 | MacroExpr | test_logging.rs:163:33:163:56 | ...::Some(...) [Some] | provenance | |
+| test_logging.rs:163:49:163:56 | password | test_logging.rs:163:33:163:56 | MacroExpr | provenance | |
+| test_logging.rs:164:33:164:56 | ...::Some(...) [Some] | test_logging.rs:164:16:164:57 | ...::assert_failed | provenance | MaD:8 Sink:MaD:8 |
+| test_logging.rs:164:33:164:56 | MacroExpr | test_logging.rs:164:33:164:56 | ...::Some(...) [Some] | provenance | |
+| test_logging.rs:164:49:164:56 | password | test_logging.rs:164:33:164:56 | MacroExpr | provenance | |
| test_logging.rs:165:37:165:60 | MacroExpr | test_logging.rs:165:16:165:61 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
| test_logging.rs:165:53:165:60 | password | test_logging.rs:165:37:165:60 | MacroExpr | provenance | |
-| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:21 |
+| test_logging.rs:166:39:166:62 | ...::Some(...) [Some] | test_logging.rs:166:16:166:63 | ...::assert_failed | provenance | MaD:8 Sink:MaD:8 |
+| test_logging.rs:166:39:166:62 | MacroExpr | test_logging.rs:166:39:166:62 | ...::Some(...) [Some] | provenance | |
+| test_logging.rs:166:55:166:62 | password | test_logging.rs:166:39:166:62 | MacroExpr | provenance | |
+| test_logging.rs:167:40:167:63 | ...::Some(...) [Some] | test_logging.rs:167:17:167:64 | ...::assert_failed | provenance | MaD:8 Sink:MaD:8 |
+| test_logging.rs:167:40:167:63 | MacroExpr | test_logging.rs:167:40:167:63 | ...::Some(...) [Some] | provenance | |
+| test_logging.rs:167:56:167:63 | password | test_logging.rs:167:40:167:63 | MacroExpr | provenance | |
+| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:22 |
| test_logging.rs:168:34:168:66 | res | test_logging.rs:168:42:168:65 | { ... } | provenance | |
-| test_logging.rs:168:34:168:75 | ... .as_str(...) | test_logging.rs:168:27:168:32 | expect | provenance | MaD:8 Sink:MaD:8 |
+| test_logging.rs:168:34:168:75 | ... .as_str(...) | test_logging.rs:168:27:168:32 | expect | provenance | MaD:9 Sink:MaD:9 |
| test_logging.rs:168:42:168:65 | ...::format(...) | test_logging.rs:168:34:168:66 | res | provenance | |
| test_logging.rs:168:42:168:65 | ...::must_use(...) | test_logging.rs:168:34:168:66 | MacroExpr | provenance | |
-| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:24 |
-| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:23 |
+| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:25 |
+| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:24 |
| test_logging.rs:168:58:168:65 | password | test_logging.rs:168:42:168:65 | MacroExpr | provenance | |
-| test_logging.rs:174:36:174:68 | MacroExpr | test_logging.rs:174:36:174:79 | ... .as_bytes(...) | provenance | MaD:22 |
+| test_logging.rs:174:36:174:68 | MacroExpr | test_logging.rs:174:36:174:79 | ... .as_bytes(...) | provenance | MaD:23 |
| test_logging.rs:174:36:174:68 | res | test_logging.rs:174:44:174:67 | { ... } | provenance | |
| test_logging.rs:174:36:174:79 | ... .as_bytes(...) | test_logging.rs:174:30:174:34 | write | provenance | MaD:3 Sink:MaD:3 |
| test_logging.rs:174:44:174:67 | ...::format(...) | test_logging.rs:174:36:174:68 | res | provenance | |
| test_logging.rs:174:44:174:67 | ...::must_use(...) | test_logging.rs:174:36:174:68 | MacroExpr | provenance | |
-| test_logging.rs:174:44:174:67 | MacroExpr | test_logging.rs:174:44:174:67 | ...::format(...) | provenance | MaD:24 |
-| test_logging.rs:174:44:174:67 | { ... } | test_logging.rs:174:44:174:67 | ...::must_use(...) | provenance | MaD:23 |
+| test_logging.rs:174:44:174:67 | MacroExpr | test_logging.rs:174:44:174:67 | ...::format(...) | provenance | MaD:25 |
+| test_logging.rs:174:44:174:67 | { ... } | test_logging.rs:174:44:174:67 | ...::must_use(...) | provenance | MaD:24 |
| test_logging.rs:174:60:174:67 | password | test_logging.rs:174:44:174:67 | MacroExpr | provenance | |
-| test_logging.rs:175:40:175:72 | MacroExpr | test_logging.rs:175:40:175:83 | ... .as_bytes(...) | provenance | MaD:22 |
+| test_logging.rs:175:40:175:72 | MacroExpr | test_logging.rs:175:40:175:83 | ... .as_bytes(...) | provenance | MaD:23 |
| test_logging.rs:175:40:175:72 | res | test_logging.rs:175:48:175:71 | { ... } | provenance | |
-| test_logging.rs:175:40:175:83 | ... .as_bytes(...) | test_logging.rs:175:30:175:38 | write_all | provenance | MaD:5 Sink:MaD:5 |
+| test_logging.rs:175:40:175:83 | ... .as_bytes(...) | test_logging.rs:175:30:175:38 | write_all | provenance | MaD:4 Sink:MaD:4 |
| test_logging.rs:175:48:175:71 | ...::format(...) | test_logging.rs:175:40:175:72 | res | provenance | |
| test_logging.rs:175:48:175:71 | ...::must_use(...) | test_logging.rs:175:40:175:72 | MacroExpr | provenance | |
-| test_logging.rs:175:48:175:71 | MacroExpr | test_logging.rs:175:48:175:71 | ...::format(...) | provenance | MaD:24 |
-| test_logging.rs:175:48:175:71 | { ... } | test_logging.rs:175:48:175:71 | ...::must_use(...) | provenance | MaD:23 |
+| test_logging.rs:175:48:175:71 | MacroExpr | test_logging.rs:175:48:175:71 | ...::format(...) | provenance | MaD:25 |
+| test_logging.rs:175:48:175:71 | { ... } | test_logging.rs:175:48:175:71 | ...::must_use(...) | provenance | MaD:24 |
| test_logging.rs:175:64:175:71 | password | test_logging.rs:175:48:175:71 | MacroExpr | provenance | |
-| test_logging.rs:178:15:178:47 | MacroExpr | test_logging.rs:178:15:178:58 | ... .as_bytes(...) | provenance | MaD:22 |
+| test_logging.rs:178:15:178:47 | MacroExpr | test_logging.rs:178:15:178:58 | ... .as_bytes(...) | provenance | MaD:23 |
| test_logging.rs:178:15:178:47 | res | test_logging.rs:178:23:178:46 | { ... } | provenance | |
| test_logging.rs:178:15:178:58 | ... .as_bytes(...) | test_logging.rs:178:9:178:13 | write | provenance | MaD:3 Sink:MaD:3 |
| test_logging.rs:178:23:178:46 | ...::format(...) | test_logging.rs:178:15:178:47 | res | provenance | |
| test_logging.rs:178:23:178:46 | ...::must_use(...) | test_logging.rs:178:15:178:47 | MacroExpr | provenance | |
-| test_logging.rs:178:23:178:46 | MacroExpr | test_logging.rs:178:23:178:46 | ...::format(...) | provenance | MaD:24 |
-| test_logging.rs:178:23:178:46 | { ... } | test_logging.rs:178:23:178:46 | ...::must_use(...) | provenance | MaD:23 |
+| test_logging.rs:178:23:178:46 | MacroExpr | test_logging.rs:178:23:178:46 | ...::format(...) | provenance | MaD:25 |
+| test_logging.rs:178:23:178:46 | { ... } | test_logging.rs:178:23:178:46 | ...::must_use(...) | provenance | MaD:24 |
| test_logging.rs:178:39:178:46 | password | test_logging.rs:178:23:178:46 | MacroExpr | provenance | |
-| test_logging.rs:181:15:181:47 | MacroExpr | test_logging.rs:181:15:181:58 | ... .as_bytes(...) | provenance | MaD:22 |
+| test_logging.rs:181:15:181:47 | MacroExpr | test_logging.rs:181:15:181:58 | ... .as_bytes(...) | provenance | MaD:23 |
| test_logging.rs:181:15:181:47 | res | test_logging.rs:181:23:181:46 | { ... } | provenance | |
-| test_logging.rs:181:15:181:58 | ... .as_bytes(...) | test_logging.rs:181:9:181:13 | write | provenance | MaD:4 Sink:MaD:4 |
+| test_logging.rs:181:15:181:58 | ... .as_bytes(...) | test_logging.rs:181:9:181:13 | write | provenance | MaD:5 Sink:MaD:5 |
| test_logging.rs:181:23:181:46 | ...::format(...) | test_logging.rs:181:15:181:47 | res | provenance | |
| test_logging.rs:181:23:181:46 | ...::must_use(...) | test_logging.rs:181:15:181:47 | MacroExpr | provenance | |
-| test_logging.rs:181:23:181:46 | MacroExpr | test_logging.rs:181:23:181:46 | ...::format(...) | provenance | MaD:24 |
-| test_logging.rs:181:23:181:46 | { ... } | test_logging.rs:181:23:181:46 | ...::must_use(...) | provenance | MaD:23 |
+| test_logging.rs:181:23:181:46 | MacroExpr | test_logging.rs:181:23:181:46 | ...::format(...) | provenance | MaD:25 |
+| test_logging.rs:181:23:181:46 | { ... } | test_logging.rs:181:23:181:46 | ...::must_use(...) | provenance | MaD:24 |
| test_logging.rs:181:39:181:46 | password | test_logging.rs:181:23:181:46 | MacroExpr | provenance | |
nodes
| test_logging.rs:42:5:42:36 | ...::log | semmle.label | ...::log |
@@ -261,9 +277,25 @@ nodes
| test_logging.rs:162:16:162:55 | ...::panic_fmt | semmle.label | ...::panic_fmt |
| test_logging.rs:162:31:162:54 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:162:47:162:54 | password | semmle.label | password |
+| test_logging.rs:163:16:163:57 | ...::assert_failed | semmle.label | ...::assert_failed |
+| test_logging.rs:163:33:163:56 | ...::Some(...) [Some] | semmle.label | ...::Some(...) [Some] |
+| test_logging.rs:163:33:163:56 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:163:49:163:56 | password | semmle.label | password |
+| test_logging.rs:164:16:164:57 | ...::assert_failed | semmle.label | ...::assert_failed |
+| test_logging.rs:164:33:164:56 | ...::Some(...) [Some] | semmle.label | ...::Some(...) [Some] |
+| test_logging.rs:164:33:164:56 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:164:49:164:56 | password | semmle.label | password |
| test_logging.rs:165:16:165:61 | ...::panic_fmt | semmle.label | ...::panic_fmt |
| test_logging.rs:165:37:165:60 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:165:53:165:60 | password | semmle.label | password |
+| test_logging.rs:166:16:166:63 | ...::assert_failed | semmle.label | ...::assert_failed |
+| test_logging.rs:166:39:166:62 | ...::Some(...) [Some] | semmle.label | ...::Some(...) [Some] |
+| test_logging.rs:166:39:166:62 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:166:55:166:62 | password | semmle.label | password |
+| test_logging.rs:167:17:167:64 | ...::assert_failed | semmle.label | ...::assert_failed |
+| test_logging.rs:167:40:167:63 | ...::Some(...) [Some] | semmle.label | ...::Some(...) [Some] |
+| test_logging.rs:167:40:167:63 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:167:56:167:63 | password | semmle.label | password |
| test_logging.rs:168:27:168:32 | expect | semmle.label | expect |
| test_logging.rs:168:34:168:66 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:168:34:168:66 | res | semmle.label | res |
diff --git a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
index f7aeb8c19905..e674ddec8149 100644
--- a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
+++ b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
@@ -160,11 +160,11 @@ fn test_std(password: String, i: i32, opt_i: Option) {
3 => { unimplemented!("message = {}", password); } // $ Source Alert[rust/cleartext-logging]
4 => { unreachable!("message = {}", password); } // $ Source Alert[rust/cleartext-logging]
5 => { assert!(false, "message = {}", password); } // $ Source Alert[rust/cleartext-logging]
- 6 => { assert_eq!(1, 2, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
- 7 => { assert_ne!(1, 1, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 6 => { assert_eq!(1, 2, "message = {}", password); } // $ Source Alert[rust/cleartext-logging]
+ 7 => { assert_ne!(1, 1, "message = {}", password); } // $ Source Alert[rust/cleartext-logging]
8 => { debug_assert!(false, "message = {}", password); } // $ Source Alert[rust/cleartext-logging]
- 9 => { debug_assert_eq!(1, 2, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
- 10 => { debug_assert_ne!(1, 1, "message = {}", password); } // $ MISSING: Alert[rust/cleartext-logging]
+ 9 => { debug_assert_eq!(1, 2, "message = {}", password); } // $ Source Alert[rust/cleartext-logging]
+ 10 => { debug_assert_ne!(1, 1, "message = {}", password); } // $ Source Alert[rust/cleartext-logging]
11 => { _ = opt_i.expect(format!("message = {}", password).as_str()); } // $ Source Alert[rust/cleartext-logging]
_ => {}
}
From 64444940a68203a746d3862c5f346d3809a59f85 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Wed, 22 Jan 2025 18:02:48 +0000
Subject: [PATCH 07/21] Rust: Add taint sinks for target and key-value
arguments.
---
.../lib/codeql/rust/frameworks/log.model.yml | 4 +-
.../CWE-312/CleartextLogging.expected | 72 +++++++++----------
2 files changed, 39 insertions(+), 37 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/frameworks/log.model.yml b/rust/ql/lib/codeql/rust/frameworks/log.model.yml
index 43105c601426..10a530ab8f86 100644
--- a/rust/ql/lib/codeql/rust/frameworks/log.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/log.model.yml
@@ -3,7 +3,9 @@ extensions:
pack: codeql/rust-all
extensible: sinkModel
data:
- - ["repo:https://github.com/rust-lang/log:log", "crate::__private_api::log", "Argument[0]", "log-injection", "manual"]
+ - ["repo:https://github.com/rust-lang/log:log", "crate::__private_api::log", "Argument[0]", "log-injection", "manual"] # args
+ - ["repo:https://github.com/rust-lang/log:log", "crate::__private_api::log", "Argument[2]", "log-injection", "manual"] # target
+ - ["repo:https://github.com/rust-lang/log:log", "crate::__private_api::log", "Argument[3]", "log-injection", "manual"] # key value
- ["lang:std", "crate::io::stdio::_print", "Argument[0]", "log-injection", "manual"]
- ["lang:std", "crate::io::stdio::_eprint", "Argument[0]", "log-injection", "manual"]
- ["lang:std", "::write", "Argument[0]", "log-injection", "manual"]
diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
index 7b278bbdb761..b683d9406001 100644
--- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
+++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
@@ -86,8 +86,8 @@ edges
| test_logging.rs:99:14:99:46 | res | test_logging.rs:99:22:99:45 | { ... } | provenance | |
| test_logging.rs:99:22:99:45 | ...::format(...) | test_logging.rs:99:14:99:46 | res | provenance | |
| test_logging.rs:99:22:99:45 | ...::must_use(...) | test_logging.rs:99:9:99:10 | m3 | provenance | |
-| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:25 |
-| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:24 |
+| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:27 |
+| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:26 |
| test_logging.rs:99:38:99:45 | password | test_logging.rs:99:22:99:45 | MacroExpr | provenance | |
| test_logging.rs:100:11:100:18 | MacroExpr | test_logging.rs:100:5:100:19 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:118:12:118:41 | MacroExpr | test_logging.rs:118:5:118:42 | ...::log | provenance | MaD:0 Sink:MaD:0 |
@@ -98,77 +98,77 @@ edges
| test_logging.rs:131:12:131:31 | MacroExpr | test_logging.rs:131:5:131:32 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:131:28:131:29 | t1 [tuple.1] | test_logging.rs:131:28:131:31 | t1.1 | provenance | |
| test_logging.rs:131:28:131:31 | t1.1 | test_logging.rs:131:12:131:31 | MacroExpr | provenance | |
-| test_logging.rs:152:12:152:35 | MacroExpr | test_logging.rs:152:5:152:36 | ...::_print | provenance | MaD:1 Sink:MaD:1 |
+| test_logging.rs:152:12:152:35 | MacroExpr | test_logging.rs:152:5:152:36 | ...::_print | provenance | MaD:3 Sink:MaD:3 |
| test_logging.rs:152:28:152:35 | password | test_logging.rs:152:12:152:35 | MacroExpr | provenance | |
-| test_logging.rs:153:14:153:37 | MacroExpr | test_logging.rs:153:5:153:38 | ...::_print | provenance | MaD:1 Sink:MaD:1 |
+| test_logging.rs:153:14:153:37 | MacroExpr | test_logging.rs:153:5:153:38 | ...::_print | provenance | MaD:3 Sink:MaD:3 |
| test_logging.rs:153:30:153:37 | password | test_logging.rs:153:14:153:37 | MacroExpr | provenance | |
-| test_logging.rs:154:13:154:36 | MacroExpr | test_logging.rs:154:5:154:37 | ...::_eprint | provenance | MaD:2 Sink:MaD:2 |
+| test_logging.rs:154:13:154:36 | MacroExpr | test_logging.rs:154:5:154:37 | ...::_eprint | provenance | MaD:4 Sink:MaD:4 |
| test_logging.rs:154:29:154:36 | password | test_logging.rs:154:13:154:36 | MacroExpr | provenance | |
-| test_logging.rs:155:15:155:38 | MacroExpr | test_logging.rs:155:5:155:39 | ...::_eprint | provenance | MaD:2 Sink:MaD:2 |
+| test_logging.rs:155:15:155:38 | MacroExpr | test_logging.rs:155:5:155:39 | ...::_eprint | provenance | MaD:4 Sink:MaD:4 |
| test_logging.rs:155:31:155:38 | password | test_logging.rs:155:15:155:38 | MacroExpr | provenance | |
-| test_logging.rs:158:23:158:46 | MacroExpr | test_logging.rs:158:16:158:47 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
+| test_logging.rs:158:23:158:46 | MacroExpr | test_logging.rs:158:16:158:47 | ...::panic_fmt | provenance | MaD:9 Sink:MaD:9 |
| test_logging.rs:158:39:158:46 | password | test_logging.rs:158:23:158:46 | MacroExpr | provenance | |
-| test_logging.rs:159:22:159:45 | MacroExpr | test_logging.rs:159:16:159:46 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
+| test_logging.rs:159:22:159:45 | MacroExpr | test_logging.rs:159:16:159:46 | ...::panic_fmt | provenance | MaD:9 Sink:MaD:9 |
| test_logging.rs:159:38:159:45 | password | test_logging.rs:159:22:159:45 | MacroExpr | provenance | |
-| test_logging.rs:160:31:160:54 | MacroExpr | test_logging.rs:160:16:160:55 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
+| test_logging.rs:160:31:160:54 | MacroExpr | test_logging.rs:160:16:160:55 | ...::panic_fmt | provenance | MaD:9 Sink:MaD:9 |
| test_logging.rs:160:47:160:54 | password | test_logging.rs:160:31:160:54 | MacroExpr | provenance | |
-| test_logging.rs:161:29:161:52 | MacroExpr | test_logging.rs:161:16:161:53 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
+| test_logging.rs:161:29:161:52 | MacroExpr | test_logging.rs:161:16:161:53 | ...::panic_fmt | provenance | MaD:9 Sink:MaD:9 |
| test_logging.rs:161:45:161:52 | password | test_logging.rs:161:29:161:52 | MacroExpr | provenance | |
-| test_logging.rs:162:31:162:54 | MacroExpr | test_logging.rs:162:16:162:55 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
+| test_logging.rs:162:31:162:54 | MacroExpr | test_logging.rs:162:16:162:55 | ...::panic_fmt | provenance | MaD:9 Sink:MaD:9 |
| test_logging.rs:162:47:162:54 | password | test_logging.rs:162:31:162:54 | MacroExpr | provenance | |
-| test_logging.rs:163:33:163:56 | ...::Some(...) [Some] | test_logging.rs:163:16:163:57 | ...::assert_failed | provenance | MaD:8 Sink:MaD:8 |
+| test_logging.rs:163:33:163:56 | ...::Some(...) [Some] | test_logging.rs:163:16:163:57 | ...::assert_failed | provenance | MaD:10 Sink:MaD:10 |
| test_logging.rs:163:33:163:56 | MacroExpr | test_logging.rs:163:33:163:56 | ...::Some(...) [Some] | provenance | |
| test_logging.rs:163:49:163:56 | password | test_logging.rs:163:33:163:56 | MacroExpr | provenance | |
-| test_logging.rs:164:33:164:56 | ...::Some(...) [Some] | test_logging.rs:164:16:164:57 | ...::assert_failed | provenance | MaD:8 Sink:MaD:8 |
+| test_logging.rs:164:33:164:56 | ...::Some(...) [Some] | test_logging.rs:164:16:164:57 | ...::assert_failed | provenance | MaD:10 Sink:MaD:10 |
| test_logging.rs:164:33:164:56 | MacroExpr | test_logging.rs:164:33:164:56 | ...::Some(...) [Some] | provenance | |
| test_logging.rs:164:49:164:56 | password | test_logging.rs:164:33:164:56 | MacroExpr | provenance | |
-| test_logging.rs:165:37:165:60 | MacroExpr | test_logging.rs:165:16:165:61 | ...::panic_fmt | provenance | MaD:7 Sink:MaD:7 |
+| test_logging.rs:165:37:165:60 | MacroExpr | test_logging.rs:165:16:165:61 | ...::panic_fmt | provenance | MaD:9 Sink:MaD:9 |
| test_logging.rs:165:53:165:60 | password | test_logging.rs:165:37:165:60 | MacroExpr | provenance | |
-| test_logging.rs:166:39:166:62 | ...::Some(...) [Some] | test_logging.rs:166:16:166:63 | ...::assert_failed | provenance | MaD:8 Sink:MaD:8 |
+| test_logging.rs:166:39:166:62 | ...::Some(...) [Some] | test_logging.rs:166:16:166:63 | ...::assert_failed | provenance | MaD:10 Sink:MaD:10 |
| test_logging.rs:166:39:166:62 | MacroExpr | test_logging.rs:166:39:166:62 | ...::Some(...) [Some] | provenance | |
| test_logging.rs:166:55:166:62 | password | test_logging.rs:166:39:166:62 | MacroExpr | provenance | |
-| test_logging.rs:167:40:167:63 | ...::Some(...) [Some] | test_logging.rs:167:17:167:64 | ...::assert_failed | provenance | MaD:8 Sink:MaD:8 |
+| test_logging.rs:167:40:167:63 | ...::Some(...) [Some] | test_logging.rs:167:17:167:64 | ...::assert_failed | provenance | MaD:10 Sink:MaD:10 |
| test_logging.rs:167:40:167:63 | MacroExpr | test_logging.rs:167:40:167:63 | ...::Some(...) [Some] | provenance | |
| test_logging.rs:167:56:167:63 | password | test_logging.rs:167:40:167:63 | MacroExpr | provenance | |
-| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:22 |
+| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:24 |
| test_logging.rs:168:34:168:66 | res | test_logging.rs:168:42:168:65 | { ... } | provenance | |
-| test_logging.rs:168:34:168:75 | ... .as_str(...) | test_logging.rs:168:27:168:32 | expect | provenance | MaD:9 Sink:MaD:9 |
+| test_logging.rs:168:34:168:75 | ... .as_str(...) | test_logging.rs:168:27:168:32 | expect | provenance | MaD:11 Sink:MaD:11 |
| test_logging.rs:168:42:168:65 | ...::format(...) | test_logging.rs:168:34:168:66 | res | provenance | |
| test_logging.rs:168:42:168:65 | ...::must_use(...) | test_logging.rs:168:34:168:66 | MacroExpr | provenance | |
-| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:25 |
-| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:24 |
+| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:27 |
+| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:26 |
| test_logging.rs:168:58:168:65 | password | test_logging.rs:168:42:168:65 | MacroExpr | provenance | |
-| test_logging.rs:174:36:174:68 | MacroExpr | test_logging.rs:174:36:174:79 | ... .as_bytes(...) | provenance | MaD:23 |
+| test_logging.rs:174:36:174:68 | MacroExpr | test_logging.rs:174:36:174:79 | ... .as_bytes(...) | provenance | MaD:25 |
| test_logging.rs:174:36:174:68 | res | test_logging.rs:174:44:174:67 | { ... } | provenance | |
-| test_logging.rs:174:36:174:79 | ... .as_bytes(...) | test_logging.rs:174:30:174:34 | write | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:174:36:174:79 | ... .as_bytes(...) | test_logging.rs:174:30:174:34 | write | provenance | MaD:5 Sink:MaD:5 |
| test_logging.rs:174:44:174:67 | ...::format(...) | test_logging.rs:174:36:174:68 | res | provenance | |
| test_logging.rs:174:44:174:67 | ...::must_use(...) | test_logging.rs:174:36:174:68 | MacroExpr | provenance | |
-| test_logging.rs:174:44:174:67 | MacroExpr | test_logging.rs:174:44:174:67 | ...::format(...) | provenance | MaD:25 |
-| test_logging.rs:174:44:174:67 | { ... } | test_logging.rs:174:44:174:67 | ...::must_use(...) | provenance | MaD:24 |
+| test_logging.rs:174:44:174:67 | MacroExpr | test_logging.rs:174:44:174:67 | ...::format(...) | provenance | MaD:27 |
+| test_logging.rs:174:44:174:67 | { ... } | test_logging.rs:174:44:174:67 | ...::must_use(...) | provenance | MaD:26 |
| test_logging.rs:174:60:174:67 | password | test_logging.rs:174:44:174:67 | MacroExpr | provenance | |
-| test_logging.rs:175:40:175:72 | MacroExpr | test_logging.rs:175:40:175:83 | ... .as_bytes(...) | provenance | MaD:23 |
+| test_logging.rs:175:40:175:72 | MacroExpr | test_logging.rs:175:40:175:83 | ... .as_bytes(...) | provenance | MaD:25 |
| test_logging.rs:175:40:175:72 | res | test_logging.rs:175:48:175:71 | { ... } | provenance | |
-| test_logging.rs:175:40:175:83 | ... .as_bytes(...) | test_logging.rs:175:30:175:38 | write_all | provenance | MaD:4 Sink:MaD:4 |
+| test_logging.rs:175:40:175:83 | ... .as_bytes(...) | test_logging.rs:175:30:175:38 | write_all | provenance | MaD:6 Sink:MaD:6 |
| test_logging.rs:175:48:175:71 | ...::format(...) | test_logging.rs:175:40:175:72 | res | provenance | |
| test_logging.rs:175:48:175:71 | ...::must_use(...) | test_logging.rs:175:40:175:72 | MacroExpr | provenance | |
-| test_logging.rs:175:48:175:71 | MacroExpr | test_logging.rs:175:48:175:71 | ...::format(...) | provenance | MaD:25 |
-| test_logging.rs:175:48:175:71 | { ... } | test_logging.rs:175:48:175:71 | ...::must_use(...) | provenance | MaD:24 |
+| test_logging.rs:175:48:175:71 | MacroExpr | test_logging.rs:175:48:175:71 | ...::format(...) | provenance | MaD:27 |
+| test_logging.rs:175:48:175:71 | { ... } | test_logging.rs:175:48:175:71 | ...::must_use(...) | provenance | MaD:26 |
| test_logging.rs:175:64:175:71 | password | test_logging.rs:175:48:175:71 | MacroExpr | provenance | |
-| test_logging.rs:178:15:178:47 | MacroExpr | test_logging.rs:178:15:178:58 | ... .as_bytes(...) | provenance | MaD:23 |
+| test_logging.rs:178:15:178:47 | MacroExpr | test_logging.rs:178:15:178:58 | ... .as_bytes(...) | provenance | MaD:25 |
| test_logging.rs:178:15:178:47 | res | test_logging.rs:178:23:178:46 | { ... } | provenance | |
-| test_logging.rs:178:15:178:58 | ... .as_bytes(...) | test_logging.rs:178:9:178:13 | write | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:178:15:178:58 | ... .as_bytes(...) | test_logging.rs:178:9:178:13 | write | provenance | MaD:5 Sink:MaD:5 |
| test_logging.rs:178:23:178:46 | ...::format(...) | test_logging.rs:178:15:178:47 | res | provenance | |
| test_logging.rs:178:23:178:46 | ...::must_use(...) | test_logging.rs:178:15:178:47 | MacroExpr | provenance | |
-| test_logging.rs:178:23:178:46 | MacroExpr | test_logging.rs:178:23:178:46 | ...::format(...) | provenance | MaD:25 |
-| test_logging.rs:178:23:178:46 | { ... } | test_logging.rs:178:23:178:46 | ...::must_use(...) | provenance | MaD:24 |
+| test_logging.rs:178:23:178:46 | MacroExpr | test_logging.rs:178:23:178:46 | ...::format(...) | provenance | MaD:27 |
+| test_logging.rs:178:23:178:46 | { ... } | test_logging.rs:178:23:178:46 | ...::must_use(...) | provenance | MaD:26 |
| test_logging.rs:178:39:178:46 | password | test_logging.rs:178:23:178:46 | MacroExpr | provenance | |
-| test_logging.rs:181:15:181:47 | MacroExpr | test_logging.rs:181:15:181:58 | ... .as_bytes(...) | provenance | MaD:23 |
+| test_logging.rs:181:15:181:47 | MacroExpr | test_logging.rs:181:15:181:58 | ... .as_bytes(...) | provenance | MaD:25 |
| test_logging.rs:181:15:181:47 | res | test_logging.rs:181:23:181:46 | { ... } | provenance | |
-| test_logging.rs:181:15:181:58 | ... .as_bytes(...) | test_logging.rs:181:9:181:13 | write | provenance | MaD:5 Sink:MaD:5 |
+| test_logging.rs:181:15:181:58 | ... .as_bytes(...) | test_logging.rs:181:9:181:13 | write | provenance | MaD:7 Sink:MaD:7 |
| test_logging.rs:181:23:181:46 | ...::format(...) | test_logging.rs:181:15:181:47 | res | provenance | |
| test_logging.rs:181:23:181:46 | ...::must_use(...) | test_logging.rs:181:15:181:47 | MacroExpr | provenance | |
-| test_logging.rs:181:23:181:46 | MacroExpr | test_logging.rs:181:23:181:46 | ...::format(...) | provenance | MaD:25 |
-| test_logging.rs:181:23:181:46 | { ... } | test_logging.rs:181:23:181:46 | ...::must_use(...) | provenance | MaD:24 |
+| test_logging.rs:181:23:181:46 | MacroExpr | test_logging.rs:181:23:181:46 | ...::format(...) | provenance | MaD:27 |
+| test_logging.rs:181:23:181:46 | { ... } | test_logging.rs:181:23:181:46 | ...::must_use(...) | provenance | MaD:26 |
| test_logging.rs:181:39:181:46 | password | test_logging.rs:181:23:181:46 | MacroExpr | provenance | |
nodes
| test_logging.rs:42:5:42:36 | ...::log | semmle.label | ...::log |
From 78c58aa5f11a5c349ecc952521c8315fa1527b3c Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Wed, 22 Jan 2025 18:20:28 +0000
Subject: [PATCH 08/21] Rust: Allow implicit taint reads from tuple contents at
sinks.
---
.../rust/dataflow/internal/DataFlowImpl.qll | 2 +-
.../security/CWE-312/CleartextLogging.ql | 7 +++
.../CWE-312/CleartextLogging.expected | 44 +++++++++++++++++++
.../security/CWE-312/test_logging.rs | 8 ++--
4 files changed, 56 insertions(+), 5 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll
index b4346babb53b..aa2262ab7cdc 100644
--- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll
+++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll
@@ -773,7 +773,7 @@ final class ArrayElementContent extends Content, TArrayElement {
* NOTE: Unlike `struct`s and `enum`s tuples are structural and not nominal,
* hence we don't store a canonical path for them.
*/
-private class TuplePositionContent extends Content, TTuplePositionContent {
+final class TuplePositionContent extends Content, TTuplePositionContent {
private int pos;
TuplePositionContent() { this = TTuplePositionContent(pos) }
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
index b9a1a80b3cf8..8450f7dd93cd 100644
--- a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
@@ -17,6 +17,7 @@ import rust
import codeql.rust.security.CleartextLoggingExtensions
import codeql.rust.dataflow.DataFlow
import codeql.rust.dataflow.TaintTracking
+import codeql.rust.dataflow.internal.DataFlowImpl
/**
* A taint-tracking configuration for cleartext logging vulnerabilities.
@@ -34,6 +35,12 @@ module CleartextLoggingConfig implements DataFlow::ConfigSig {
// make sources barriers so that we only report the closest instance
isSource(node)
}
+
+ predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
+ // flow out from tuple content at sinks.
+ isSink(node) and
+ c.getAReadContent() instanceof TuplePositionContent
+ }
}
module CleartextLoggingFlow = TaintTracking::Global;
diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
index b683d9406001..f64b127956f7 100644
--- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
+++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
@@ -11,13 +11,17 @@
| test_logging.rs:57:5:57:34 | ...::log | test_logging.rs:57:24:57:31 | password | test_logging.rs:57:5:57:34 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:57:24:57:31 | password | password |
| test_logging.rs:58:5:58:36 | ...::log | test_logging.rs:58:24:58:31 | password | test_logging.rs:58:5:58:36 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:58:24:58:31 | password | password |
| test_logging.rs:60:5:60:54 | ...::log | test_logging.rs:60:46:60:53 | password | test_logging.rs:60:5:60:54 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:60:46:60:53 | password | password |
+| test_logging.rs:61:5:61:55 | ...::log | test_logging.rs:61:21:61:28 | password | test_logging.rs:61:5:61:55 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:61:21:61:28 | password | password |
| test_logging.rs:65:5:65:48 | ...::log | test_logging.rs:65:40:65:47 | password | test_logging.rs:65:5:65:48 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:65:40:65:47 | password | password |
| test_logging.rs:67:5:67:66 | ...::log | test_logging.rs:67:58:67:65 | password | test_logging.rs:67:5:67:66 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:67:58:67:65 | password | password |
+| test_logging.rs:68:5:68:67 | ...::log | test_logging.rs:68:19:68:26 | password | test_logging.rs:68:5:68:67 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:68:19:68:26 | password | password |
| test_logging.rs:72:5:72:47 | ...::log::<...> | test_logging.rs:72:39:72:46 | password | test_logging.rs:72:5:72:47 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:72:39:72:46 | password | password |
| test_logging.rs:74:5:74:65 | ...::log::<...> | test_logging.rs:74:57:74:64 | password | test_logging.rs:74:5:74:65 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:74:57:74:64 | password | password |
+| test_logging.rs:75:5:75:51 | ...::log::<...> | test_logging.rs:75:21:75:28 | password | test_logging.rs:75:5:75:51 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:75:21:75:28 | password | password |
| test_logging.rs:76:5:76:47 | ...::log::<...> | test_logging.rs:76:39:76:46 | password | test_logging.rs:76:5:76:47 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:76:39:76:46 | password | password |
| test_logging.rs:82:5:82:44 | ...::log::<...> | test_logging.rs:82:36:82:43 | password | test_logging.rs:82:5:82:44 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:82:36:82:43 | password | password |
| test_logging.rs:84:5:84:62 | ...::log::<...> | test_logging.rs:84:54:84:61 | password | test_logging.rs:84:5:84:62 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:84:54:84:61 | password | password |
+| test_logging.rs:85:5:85:48 | ...::log::<...> | test_logging.rs:85:21:85:28 | password | test_logging.rs:85:5:85:48 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:85:21:85:28 | password | password |
| test_logging.rs:86:5:86:44 | ...::log::<...> | test_logging.rs:86:36:86:43 | password | test_logging.rs:86:5:86:44 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:86:36:86:43 | password | password |
| test_logging.rs:100:5:100:19 | ...::log | test_logging.rs:99:38:99:45 | password | test_logging.rs:100:5:100:19 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:99:38:99:45 | password | password |
| test_logging.rs:118:5:118:42 | ...::log | test_logging.rs:118:28:118:41 | get_password(...) | test_logging.rs:118:5:118:42 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:118:28:118:41 | get_password(...) | get_password(...) |
@@ -66,20 +70,40 @@ edges
| test_logging.rs:58:24:58:31 | password | test_logging.rs:58:12:58:35 | MacroExpr | provenance | |
| test_logging.rs:60:30:60:53 | MacroExpr | test_logging.rs:60:5:60:54 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:60:46:60:53 | password | test_logging.rs:60:30:60:53 | MacroExpr | provenance | |
+| test_logging.rs:61:20:61:28 | &... [&ref, tuple.0, &ref] | test_logging.rs:61:5:61:55 | ...::log | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:61:20:61:28 | &... [&ref, tuple.0, &ref] | test_logging.rs:61:5:61:55 | ...::log | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:61:20:61:28 | &password [&ref] | test_logging.rs:61:20:61:28 | TupleExpr [tuple.0, &ref] | provenance | |
+| test_logging.rs:61:20:61:28 | TupleExpr [tuple.0, &ref] | test_logging.rs:61:20:61:28 | &... [&ref, tuple.0, &ref] | provenance | |
+| test_logging.rs:61:21:61:28 | password | test_logging.rs:61:20:61:28 | &password [&ref] | provenance | |
| test_logging.rs:65:24:65:47 | MacroExpr | test_logging.rs:65:5:65:48 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:65:40:65:47 | password | test_logging.rs:65:24:65:47 | MacroExpr | provenance | |
| test_logging.rs:67:42:67:65 | MacroExpr | test_logging.rs:67:5:67:66 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:67:58:67:65 | password | test_logging.rs:67:42:67:65 | MacroExpr | provenance | |
+| test_logging.rs:68:18:68:26 | &... [&ref, tuple.0, &ref] | test_logging.rs:68:5:68:67 | ...::log | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:68:18:68:26 | &... [&ref, tuple.0, &ref] | test_logging.rs:68:5:68:67 | ...::log | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:68:18:68:26 | &password [&ref] | test_logging.rs:68:18:68:26 | TupleExpr [tuple.0, &ref] | provenance | |
+| test_logging.rs:68:18:68:26 | TupleExpr [tuple.0, &ref] | test_logging.rs:68:18:68:26 | &... [&ref, tuple.0, &ref] | provenance | |
+| test_logging.rs:68:19:68:26 | password | test_logging.rs:68:18:68:26 | &password [&ref] | provenance | |
| test_logging.rs:72:23:72:46 | MacroExpr | test_logging.rs:72:5:72:47 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:72:39:72:46 | password | test_logging.rs:72:23:72:46 | MacroExpr | provenance | |
| test_logging.rs:74:41:74:64 | MacroExpr | test_logging.rs:74:5:74:65 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:74:57:74:64 | password | test_logging.rs:74:41:74:64 | MacroExpr | provenance | |
+| test_logging.rs:75:20:75:28 | &... [&ref, tuple.0, &ref] | test_logging.rs:75:5:75:51 | ...::log::<...> | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:75:20:75:28 | &... [&ref, tuple.0, &ref] | test_logging.rs:75:5:75:51 | ...::log::<...> | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:75:20:75:28 | &password [&ref] | test_logging.rs:75:20:75:28 | TupleExpr [tuple.0, &ref] | provenance | |
+| test_logging.rs:75:20:75:28 | TupleExpr [tuple.0, &ref] | test_logging.rs:75:20:75:28 | &... [&ref, tuple.0, &ref] | provenance | |
+| test_logging.rs:75:21:75:28 | password | test_logging.rs:75:20:75:28 | &password [&ref] | provenance | |
| test_logging.rs:76:23:76:46 | MacroExpr | test_logging.rs:76:5:76:47 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:76:39:76:46 | password | test_logging.rs:76:23:76:46 | MacroExpr | provenance | |
| test_logging.rs:82:20:82:43 | MacroExpr | test_logging.rs:82:5:82:44 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:82:36:82:43 | password | test_logging.rs:82:20:82:43 | MacroExpr | provenance | |
| test_logging.rs:84:38:84:61 | MacroExpr | test_logging.rs:84:5:84:62 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:84:54:84:61 | password | test_logging.rs:84:38:84:61 | MacroExpr | provenance | |
+| test_logging.rs:85:20:85:28 | &... [&ref, tuple.0, &ref] | test_logging.rs:85:5:85:48 | ...::log::<...> | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:85:20:85:28 | &... [&ref, tuple.0, &ref] | test_logging.rs:85:5:85:48 | ...::log::<...> | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:85:20:85:28 | &password [&ref] | test_logging.rs:85:20:85:28 | TupleExpr [tuple.0, &ref] | provenance | |
+| test_logging.rs:85:20:85:28 | TupleExpr [tuple.0, &ref] | test_logging.rs:85:20:85:28 | &... [&ref, tuple.0, &ref] | provenance | |
+| test_logging.rs:85:21:85:28 | password | test_logging.rs:85:20:85:28 | &password [&ref] | provenance | |
| test_logging.rs:86:20:86:43 | MacroExpr | test_logging.rs:86:5:86:44 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:86:36:86:43 | password | test_logging.rs:86:20:86:43 | MacroExpr | provenance | |
| test_logging.rs:99:9:99:10 | m3 | test_logging.rs:100:11:100:18 | MacroExpr | provenance | |
@@ -207,18 +231,33 @@ nodes
| test_logging.rs:60:5:60:54 | ...::log | semmle.label | ...::log |
| test_logging.rs:60:30:60:53 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:60:46:60:53 | password | semmle.label | password |
+| test_logging.rs:61:5:61:55 | ...::log | semmle.label | ...::log |
+| test_logging.rs:61:20:61:28 | &... [&ref, tuple.0, &ref] | semmle.label | &... [&ref, tuple.0, &ref] |
+| test_logging.rs:61:20:61:28 | &password [&ref] | semmle.label | &password [&ref] |
+| test_logging.rs:61:20:61:28 | TupleExpr [tuple.0, &ref] | semmle.label | TupleExpr [tuple.0, &ref] |
+| test_logging.rs:61:21:61:28 | password | semmle.label | password |
| test_logging.rs:65:5:65:48 | ...::log | semmle.label | ...::log |
| test_logging.rs:65:24:65:47 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:65:40:65:47 | password | semmle.label | password |
| test_logging.rs:67:5:67:66 | ...::log | semmle.label | ...::log |
| test_logging.rs:67:42:67:65 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:67:58:67:65 | password | semmle.label | password |
+| test_logging.rs:68:5:68:67 | ...::log | semmle.label | ...::log |
+| test_logging.rs:68:18:68:26 | &... [&ref, tuple.0, &ref] | semmle.label | &... [&ref, tuple.0, &ref] |
+| test_logging.rs:68:18:68:26 | &password [&ref] | semmle.label | &password [&ref] |
+| test_logging.rs:68:18:68:26 | TupleExpr [tuple.0, &ref] | semmle.label | TupleExpr [tuple.0, &ref] |
+| test_logging.rs:68:19:68:26 | password | semmle.label | password |
| test_logging.rs:72:5:72:47 | ...::log::<...> | semmle.label | ...::log::<...> |
| test_logging.rs:72:23:72:46 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:72:39:72:46 | password | semmle.label | password |
| test_logging.rs:74:5:74:65 | ...::log::<...> | semmle.label | ...::log::<...> |
| test_logging.rs:74:41:74:64 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:74:57:74:64 | password | semmle.label | password |
+| test_logging.rs:75:5:75:51 | ...::log::<...> | semmle.label | ...::log::<...> |
+| test_logging.rs:75:20:75:28 | &... [&ref, tuple.0, &ref] | semmle.label | &... [&ref, tuple.0, &ref] |
+| test_logging.rs:75:20:75:28 | &password [&ref] | semmle.label | &password [&ref] |
+| test_logging.rs:75:20:75:28 | TupleExpr [tuple.0, &ref] | semmle.label | TupleExpr [tuple.0, &ref] |
+| test_logging.rs:75:21:75:28 | password | semmle.label | password |
| test_logging.rs:76:5:76:47 | ...::log::<...> | semmle.label | ...::log::<...> |
| test_logging.rs:76:23:76:46 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:76:39:76:46 | password | semmle.label | password |
@@ -228,6 +267,11 @@ nodes
| test_logging.rs:84:5:84:62 | ...::log::<...> | semmle.label | ...::log::<...> |
| test_logging.rs:84:38:84:61 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:84:54:84:61 | password | semmle.label | password |
+| test_logging.rs:85:5:85:48 | ...::log::<...> | semmle.label | ...::log::<...> |
+| test_logging.rs:85:20:85:28 | &... [&ref, tuple.0, &ref] | semmle.label | &... [&ref, tuple.0, &ref] |
+| test_logging.rs:85:20:85:28 | &password [&ref] | semmle.label | &password [&ref] |
+| test_logging.rs:85:20:85:28 | TupleExpr [tuple.0, &ref] | semmle.label | TupleExpr [tuple.0, &ref] |
+| test_logging.rs:85:21:85:28 | password | semmle.label | password |
| test_logging.rs:86:5:86:44 | ...::log::<...> | semmle.label | ...::log::<...> |
| test_logging.rs:86:20:86:43 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:86:36:86:43 | password | semmle.label | password |
diff --git a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
index e674ddec8149..128e314c90b8 100644
--- a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
+++ b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
@@ -58,21 +58,21 @@ fn test_log(harmless: String, password: String, encrypted_password: String) {
debug!("message = {password:?}"); // $ Source Alert[rust/cleartext-logging]
debug!(target: "target", "message = {}", harmless);
debug!(target: "target", "message = {}", password); // $ Source Alert[rust/cleartext-logging]
- debug!(target: &password, "message = {}", harmless); // $ MISSING: Alert[rust/cleartext-logging]
+ debug!(target: &password, "message = {}", harmless); // $ Source Alert[rust/cleartext-logging]
// log! macro, various formatting
log!(Level::Error, "message = {}", harmless);
log!(Level::Error, "message = {}", password); // $ Source Alert[rust/cleartext-logging]
log!(target: "target", Level::Error, "message = {}", harmless);
log!(target: "target", Level::Error, "message = {}", password); // $ Source Alert[rust/cleartext-logging]
- log!(target: &password, Level::Error, "message = {}", harmless); // $ MISSING: Alert[rust/cleartext-logging]
+ log!(target: &password, Level::Error, "message = {}", harmless); // $ Source Alert[rust/cleartext-logging]
// structured logging
error!(value = 1; "message = {}", harmless);
error!(value = 1; "message = {}", password); // $ Source Alert[rust/cleartext-logging]
error!(target: "target", value = 1; "message");
error!(target: "target", value = 1; "message = {}", password); // $ Source Alert[rust/cleartext-logging]
- error!(target: &password, value = 1; "message"); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(target: &password, value = 1; "message"); // $ Source Alert[rust/cleartext-logging]
error!(value = 1; "message = {}", password); // $ Source Alert[rust/cleartext-logging]
error!(value = password.as_str(); "message"); // $ MISSING: Alert[rust/cleartext-logging]
error!(value:? = password.as_str(); "message"); // $ MISSING: Alert[rust/cleartext-logging]
@@ -82,7 +82,7 @@ fn test_log(harmless: String, password: String, encrypted_password: String) {
error!(value1; "message = {}", password); // $ Source Alert[rust/cleartext-logging]
error!(target: "target", value1; "message");
error!(target: "target", value1; "message = {}", password); // $ Source Alert[rust/cleartext-logging]
- error!(target: &password, value1; "message"); // $ MISSING: Alert[rust/cleartext-logging]
+ error!(target: &password, value1; "message"); // $ Source Alert[rust/cleartext-logging]
error!(value1; "message = {}", password); // $ Source Alert[rust/cleartext-logging]
let value2 = password.as_str();
From 59c3ac6f801e55f6b8ee7ca5533f40003052764b Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 23 Jan 2025 09:47:48 +0000
Subject: [PATCH 09/21] Rust: Allow flow through reference taking (&).
---
.../security/CWE-312/CleartextLogging.ql | 6 +++
.../CWE-312/CleartextLogging.expected | 48 +++++++++++++++++++
.../security/CWE-312/test_logging.rs | 8 ++--
3 files changed, 58 insertions(+), 4 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
index 8450f7dd93cd..3c1587ab0110 100644
--- a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
@@ -36,6 +36,12 @@ module CleartextLoggingConfig implements DataFlow::ConfigSig {
isSource(node)
}
+ predicate isAdditionalFlowStep(Node node1, Node node2) {
+ // flow from `a` to `&a`
+ node2.(Node::ExprNode).asExpr().getExpr().(RefExpr).getExpr() =
+ node1.(Node::ExprNode).asExpr().getExpr()
+ }
+
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
// flow out from tuple content at sinks.
isSink(node) and
diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
index f64b127956f7..85e4783aabc5 100644
--- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
+++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
@@ -23,6 +23,8 @@
| test_logging.rs:84:5:84:62 | ...::log::<...> | test_logging.rs:84:54:84:61 | password | test_logging.rs:84:5:84:62 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:84:54:84:61 | password | password |
| test_logging.rs:85:5:85:48 | ...::log::<...> | test_logging.rs:85:21:85:28 | password | test_logging.rs:85:5:85:48 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:85:21:85:28 | password | password |
| test_logging.rs:86:5:86:44 | ...::log::<...> | test_logging.rs:86:36:86:43 | password | test_logging.rs:86:5:86:44 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:86:36:86:43 | password | password |
+| test_logging.rs:94:5:94:29 | ...::log | test_logging.rs:93:15:93:22 | password | test_logging.rs:94:5:94:29 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:93:15:93:22 | password | password |
+| test_logging.rs:97:5:97:19 | ...::log | test_logging.rs:96:42:96:49 | password | test_logging.rs:97:5:97:19 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:96:42:96:49 | password | password |
| test_logging.rs:100:5:100:19 | ...::log | test_logging.rs:99:38:99:45 | password | test_logging.rs:100:5:100:19 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:99:38:99:45 | password | password |
| test_logging.rs:118:5:118:42 | ...::log | test_logging.rs:118:28:118:41 | get_password(...) | test_logging.rs:118:5:118:42 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:118:28:118:41 | get_password(...) | get_password(...) |
| test_logging.rs:131:5:131:32 | ...::log | test_logging.rs:129:25:129:32 | password | test_logging.rs:131:5:131:32 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:129:25:129:32 | password | password |
@@ -72,8 +74,12 @@ edges
| test_logging.rs:60:46:60:53 | password | test_logging.rs:60:30:60:53 | MacroExpr | provenance | |
| test_logging.rs:61:20:61:28 | &... [&ref, tuple.0, &ref] | test_logging.rs:61:5:61:55 | ...::log | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 |
| test_logging.rs:61:20:61:28 | &... [&ref, tuple.0, &ref] | test_logging.rs:61:5:61:55 | ...::log | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:61:20:61:28 | &... [&ref, tuple.0] | test_logging.rs:61:5:61:55 | ...::log | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:61:20:61:28 | &password | test_logging.rs:61:20:61:28 | TupleExpr [tuple.0] | provenance | |
| test_logging.rs:61:20:61:28 | &password [&ref] | test_logging.rs:61:20:61:28 | TupleExpr [tuple.0, &ref] | provenance | |
| test_logging.rs:61:20:61:28 | TupleExpr [tuple.0, &ref] | test_logging.rs:61:20:61:28 | &... [&ref, tuple.0, &ref] | provenance | |
+| test_logging.rs:61:20:61:28 | TupleExpr [tuple.0] | test_logging.rs:61:20:61:28 | &... [&ref, tuple.0] | provenance | |
+| test_logging.rs:61:21:61:28 | password | test_logging.rs:61:20:61:28 | &password | provenance | Config |
| test_logging.rs:61:21:61:28 | password | test_logging.rs:61:20:61:28 | &password [&ref] | provenance | |
| test_logging.rs:65:24:65:47 | MacroExpr | test_logging.rs:65:5:65:48 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:65:40:65:47 | password | test_logging.rs:65:24:65:47 | MacroExpr | provenance | |
@@ -81,8 +87,12 @@ edges
| test_logging.rs:67:58:67:65 | password | test_logging.rs:67:42:67:65 | MacroExpr | provenance | |
| test_logging.rs:68:18:68:26 | &... [&ref, tuple.0, &ref] | test_logging.rs:68:5:68:67 | ...::log | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 |
| test_logging.rs:68:18:68:26 | &... [&ref, tuple.0, &ref] | test_logging.rs:68:5:68:67 | ...::log | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:68:18:68:26 | &... [&ref, tuple.0] | test_logging.rs:68:5:68:67 | ...::log | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:68:18:68:26 | &password | test_logging.rs:68:18:68:26 | TupleExpr [tuple.0] | provenance | |
| test_logging.rs:68:18:68:26 | &password [&ref] | test_logging.rs:68:18:68:26 | TupleExpr [tuple.0, &ref] | provenance | |
| test_logging.rs:68:18:68:26 | TupleExpr [tuple.0, &ref] | test_logging.rs:68:18:68:26 | &... [&ref, tuple.0, &ref] | provenance | |
+| test_logging.rs:68:18:68:26 | TupleExpr [tuple.0] | test_logging.rs:68:18:68:26 | &... [&ref, tuple.0] | provenance | |
+| test_logging.rs:68:19:68:26 | password | test_logging.rs:68:18:68:26 | &password | provenance | Config |
| test_logging.rs:68:19:68:26 | password | test_logging.rs:68:18:68:26 | &password [&ref] | provenance | |
| test_logging.rs:72:23:72:46 | MacroExpr | test_logging.rs:72:5:72:47 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:72:39:72:46 | password | test_logging.rs:72:23:72:46 | MacroExpr | provenance | |
@@ -90,8 +100,12 @@ edges
| test_logging.rs:74:57:74:64 | password | test_logging.rs:74:41:74:64 | MacroExpr | provenance | |
| test_logging.rs:75:20:75:28 | &... [&ref, tuple.0, &ref] | test_logging.rs:75:5:75:51 | ...::log::<...> | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 |
| test_logging.rs:75:20:75:28 | &... [&ref, tuple.0, &ref] | test_logging.rs:75:5:75:51 | ...::log::<...> | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:75:20:75:28 | &... [&ref, tuple.0] | test_logging.rs:75:5:75:51 | ...::log::<...> | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:75:20:75:28 | &password | test_logging.rs:75:20:75:28 | TupleExpr [tuple.0] | provenance | |
| test_logging.rs:75:20:75:28 | &password [&ref] | test_logging.rs:75:20:75:28 | TupleExpr [tuple.0, &ref] | provenance | |
| test_logging.rs:75:20:75:28 | TupleExpr [tuple.0, &ref] | test_logging.rs:75:20:75:28 | &... [&ref, tuple.0, &ref] | provenance | |
+| test_logging.rs:75:20:75:28 | TupleExpr [tuple.0] | test_logging.rs:75:20:75:28 | &... [&ref, tuple.0] | provenance | |
+| test_logging.rs:75:21:75:28 | password | test_logging.rs:75:20:75:28 | &password | provenance | Config |
| test_logging.rs:75:21:75:28 | password | test_logging.rs:75:20:75:28 | &password [&ref] | provenance | |
| test_logging.rs:76:23:76:46 | MacroExpr | test_logging.rs:76:5:76:47 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:76:39:76:46 | password | test_logging.rs:76:23:76:46 | MacroExpr | provenance | |
@@ -101,11 +115,23 @@ edges
| test_logging.rs:84:54:84:61 | password | test_logging.rs:84:38:84:61 | MacroExpr | provenance | |
| test_logging.rs:85:20:85:28 | &... [&ref, tuple.0, &ref] | test_logging.rs:85:5:85:48 | ...::log::<...> | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 |
| test_logging.rs:85:20:85:28 | &... [&ref, tuple.0, &ref] | test_logging.rs:85:5:85:48 | ...::log::<...> | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:85:20:85:28 | &... [&ref, tuple.0] | test_logging.rs:85:5:85:48 | ...::log::<...> | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 |
+| test_logging.rs:85:20:85:28 | &password | test_logging.rs:85:20:85:28 | TupleExpr [tuple.0] | provenance | |
| test_logging.rs:85:20:85:28 | &password [&ref] | test_logging.rs:85:20:85:28 | TupleExpr [tuple.0, &ref] | provenance | |
| test_logging.rs:85:20:85:28 | TupleExpr [tuple.0, &ref] | test_logging.rs:85:20:85:28 | &... [&ref, tuple.0, &ref] | provenance | |
+| test_logging.rs:85:20:85:28 | TupleExpr [tuple.0] | test_logging.rs:85:20:85:28 | &... [&ref, tuple.0] | provenance | |
+| test_logging.rs:85:21:85:28 | password | test_logging.rs:85:20:85:28 | &password | provenance | Config |
| test_logging.rs:85:21:85:28 | password | test_logging.rs:85:20:85:28 | &password [&ref] | provenance | |
| test_logging.rs:86:20:86:43 | MacroExpr | test_logging.rs:86:5:86:44 | ...::log::<...> | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:86:36:86:43 | password | test_logging.rs:86:20:86:43 | MacroExpr | provenance | |
+| test_logging.rs:93:9:93:10 | m1 | test_logging.rs:94:11:94:28 | MacroExpr | provenance | |
+| test_logging.rs:93:14:93:22 | &password | test_logging.rs:93:9:93:10 | m1 | provenance | |
+| test_logging.rs:93:15:93:22 | password | test_logging.rs:93:14:93:22 | &password | provenance | Config |
+| test_logging.rs:94:11:94:28 | MacroExpr | test_logging.rs:94:5:94:29 | ...::log | provenance | MaD:0 Sink:MaD:0 |
+| test_logging.rs:96:9:96:10 | m2 | test_logging.rs:97:11:97:18 | MacroExpr | provenance | |
+| test_logging.rs:96:41:96:49 | &password | test_logging.rs:96:9:96:10 | m2 | provenance | |
+| test_logging.rs:96:42:96:49 | password | test_logging.rs:96:41:96:49 | &password | provenance | Config |
+| test_logging.rs:97:11:97:18 | MacroExpr | test_logging.rs:97:5:97:19 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:99:9:99:10 | m3 | test_logging.rs:100:11:100:18 | MacroExpr | provenance | |
| test_logging.rs:99:14:99:46 | res | test_logging.rs:99:22:99:45 | { ... } | provenance | |
| test_logging.rs:99:22:99:45 | ...::format(...) | test_logging.rs:99:14:99:46 | res | provenance | |
@@ -233,8 +259,11 @@ nodes
| test_logging.rs:60:46:60:53 | password | semmle.label | password |
| test_logging.rs:61:5:61:55 | ...::log | semmle.label | ...::log |
| test_logging.rs:61:20:61:28 | &... [&ref, tuple.0, &ref] | semmle.label | &... [&ref, tuple.0, &ref] |
+| test_logging.rs:61:20:61:28 | &... [&ref, tuple.0] | semmle.label | &... [&ref, tuple.0] |
+| test_logging.rs:61:20:61:28 | &password | semmle.label | &password |
| test_logging.rs:61:20:61:28 | &password [&ref] | semmle.label | &password [&ref] |
| test_logging.rs:61:20:61:28 | TupleExpr [tuple.0, &ref] | semmle.label | TupleExpr [tuple.0, &ref] |
+| test_logging.rs:61:20:61:28 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] |
| test_logging.rs:61:21:61:28 | password | semmle.label | password |
| test_logging.rs:65:5:65:48 | ...::log | semmle.label | ...::log |
| test_logging.rs:65:24:65:47 | MacroExpr | semmle.label | MacroExpr |
@@ -244,8 +273,11 @@ nodes
| test_logging.rs:67:58:67:65 | password | semmle.label | password |
| test_logging.rs:68:5:68:67 | ...::log | semmle.label | ...::log |
| test_logging.rs:68:18:68:26 | &... [&ref, tuple.0, &ref] | semmle.label | &... [&ref, tuple.0, &ref] |
+| test_logging.rs:68:18:68:26 | &... [&ref, tuple.0] | semmle.label | &... [&ref, tuple.0] |
+| test_logging.rs:68:18:68:26 | &password | semmle.label | &password |
| test_logging.rs:68:18:68:26 | &password [&ref] | semmle.label | &password [&ref] |
| test_logging.rs:68:18:68:26 | TupleExpr [tuple.0, &ref] | semmle.label | TupleExpr [tuple.0, &ref] |
+| test_logging.rs:68:18:68:26 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] |
| test_logging.rs:68:19:68:26 | password | semmle.label | password |
| test_logging.rs:72:5:72:47 | ...::log::<...> | semmle.label | ...::log::<...> |
| test_logging.rs:72:23:72:46 | MacroExpr | semmle.label | MacroExpr |
@@ -255,8 +287,11 @@ nodes
| test_logging.rs:74:57:74:64 | password | semmle.label | password |
| test_logging.rs:75:5:75:51 | ...::log::<...> | semmle.label | ...::log::<...> |
| test_logging.rs:75:20:75:28 | &... [&ref, tuple.0, &ref] | semmle.label | &... [&ref, tuple.0, &ref] |
+| test_logging.rs:75:20:75:28 | &... [&ref, tuple.0] | semmle.label | &... [&ref, tuple.0] |
+| test_logging.rs:75:20:75:28 | &password | semmle.label | &password |
| test_logging.rs:75:20:75:28 | &password [&ref] | semmle.label | &password [&ref] |
| test_logging.rs:75:20:75:28 | TupleExpr [tuple.0, &ref] | semmle.label | TupleExpr [tuple.0, &ref] |
+| test_logging.rs:75:20:75:28 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] |
| test_logging.rs:75:21:75:28 | password | semmle.label | password |
| test_logging.rs:76:5:76:47 | ...::log::<...> | semmle.label | ...::log::<...> |
| test_logging.rs:76:23:76:46 | MacroExpr | semmle.label | MacroExpr |
@@ -269,12 +304,25 @@ nodes
| test_logging.rs:84:54:84:61 | password | semmle.label | password |
| test_logging.rs:85:5:85:48 | ...::log::<...> | semmle.label | ...::log::<...> |
| test_logging.rs:85:20:85:28 | &... [&ref, tuple.0, &ref] | semmle.label | &... [&ref, tuple.0, &ref] |
+| test_logging.rs:85:20:85:28 | &... [&ref, tuple.0] | semmle.label | &... [&ref, tuple.0] |
+| test_logging.rs:85:20:85:28 | &password | semmle.label | &password |
| test_logging.rs:85:20:85:28 | &password [&ref] | semmle.label | &password [&ref] |
| test_logging.rs:85:20:85:28 | TupleExpr [tuple.0, &ref] | semmle.label | TupleExpr [tuple.0, &ref] |
+| test_logging.rs:85:20:85:28 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] |
| test_logging.rs:85:21:85:28 | password | semmle.label | password |
| test_logging.rs:86:5:86:44 | ...::log::<...> | semmle.label | ...::log::<...> |
| test_logging.rs:86:20:86:43 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:86:36:86:43 | password | semmle.label | password |
+| test_logging.rs:93:9:93:10 | m1 | semmle.label | m1 |
+| test_logging.rs:93:14:93:22 | &password | semmle.label | &password |
+| test_logging.rs:93:15:93:22 | password | semmle.label | password |
+| test_logging.rs:94:5:94:29 | ...::log | semmle.label | ...::log |
+| test_logging.rs:94:11:94:28 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:96:9:96:10 | m2 | semmle.label | m2 |
+| test_logging.rs:96:41:96:49 | &password | semmle.label | &password |
+| test_logging.rs:96:42:96:49 | password | semmle.label | password |
+| test_logging.rs:97:5:97:19 | ...::log | semmle.label | ...::log |
+| test_logging.rs:97:11:97:18 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:99:9:99:10 | m3 | semmle.label | m3 |
| test_logging.rs:99:14:99:46 | res | semmle.label | res |
| test_logging.rs:99:22:99:45 | ...::format(...) | semmle.label | ...::format(...) |
diff --git a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
index 128e314c90b8..15ab6c9179bd 100644
--- a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
+++ b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
@@ -90,11 +90,11 @@ fn test_log(harmless: String, password: String, encrypted_password: String) {
error!(value2:?; "message"); // $ MISSING: Alert[rust/cleartext-logging]
// pre-formatted
- let m1 = &password; // $ MISSING: Source=m1
- info!("message = {}", m1); // $ MISSING: Alert[rust/cleartext-logging]=m1
+ let m1 = &password; // $ Source=m1
+ info!("message = {}", m1); // $ Alert[rust/cleartext-logging]=m1
- let m2 = "message = ".to_string() + &password; // $ MISSING: Source=m2
- info!("{}", m2); // $ MISSING: Alert[rust/cleartext-logging]=m2
+ let m2 = "message = ".to_string() + &password; // $ Source=m2
+ info!("{}", m2); // $ Alert[rust/cleartext-logging]=m2
let m3 = format!("message = {}", password); // $ Source=m3
info!("{}", m3); // $ Alert[rust/cleartext-logging]=m3
From e70816727beeffe8816eba70b05951d75aebde9f Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 23 Jan 2025 17:14:11 +0000
Subject: [PATCH 10/21] Rust: Add the sinks to metrics.
---
rust/ql/src/queries/summary/Stats.qll | 5 ++++-
rust/ql/test/query-tests/diagnostics/SummaryStats.expected | 4 ++--
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/rust/ql/src/queries/summary/Stats.qll b/rust/ql/src/queries/summary/Stats.qll
index 8bdb25381bc6..4054b0bc1326 100644
--- a/rust/ql/src/queries/summary/Stats.qll
+++ b/rust/ql/src/queries/summary/Stats.qll
@@ -10,6 +10,7 @@ private import codeql.rust.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.security.CleartextLoggingExtensions
/**
* Gets a count of the total number of lines of code in the database.
@@ -58,7 +59,9 @@ 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")
+ n instanceof SqlInjection::Sink and result = "SqlInjection"
+ or
+ n instanceof CleartextLogging::Sink and result = "CleartextLogging"
}
/**
diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected
index 5223601d625f..1d7193b6b99a 100644
--- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected
+++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected
@@ -14,11 +14,11 @@
| Macro calls - resolved | 8 |
| Macro calls - total | 9 |
| Macro calls - unresolved | 1 |
-| Taint edges - number of edges | 2 |
+| Taint edges - number of edges | 3 |
| Taint reach - nodes tainted | 0 |
| Taint reach - per million nodes | 0 |
| Taint sinks - cryptographic operations | 0 |
-| Taint sinks - query sinks | 0 |
+| Taint sinks - query sinks | 3 |
| Taint sources - active | 0 |
| Taint sources - disabled | 0 |
| Taint sources - sensitive data | 0 |
From ccc124360edde760bcf1d147b3b3363894d138a9 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 23 Jan 2025 17:46:04 +0000
Subject: [PATCH 11/21] Rust: Add .qhelp and examples.
---
.../security/CWE-312/CleartextLogging.qhelp | 38 +++++++++++++++++++
.../security/CWE-312/CleartextLoggingBad.rs | 2 +
.../security/CWE-312/CleartextLoggingGood.rs | 2 +
3 files changed, 42 insertions(+)
create mode 100644 rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp
create mode 100644 rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs
create mode 100644 rust/ql/src/queries/security/CWE-312/CleartextLoggingGood.rs
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp b/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp
new file mode 100644
index 000000000000..29ffeb4be6dc
--- /dev/null
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp
@@ -0,0 +1,38 @@
+
+
+
+
+
+Sensitive user data and system information that is logged could be seen by an attacker when it is
+displayed. Also, external processes often store the standard output and standard error streams of
+an application, which will include logged sensitive information.
+
+
+
+
+
+Do not log sensitive data. If it is necessary to log sensitive data, encrypt it before logging.
+
+
+
+
+
+The following example code logs user credentials (in this case, their password) in plaintext:
+
+
+
+Instead, you should encrypt the credentials, or better still omit them entirely:
+
+
+
+
+
+
+M. Dowd, J. McDonald and J. Schuhm, The Art of Software Security Assessment, 1st Edition, Chapter 2 - 'Common Vulnerabilities of Encryption', p. 43. Addison Wesley, 2006.
+M. Howard and D. LeBlanc, Writing Secure Code, 2nd Edition, Chapter 9 - 'Protecting Secret Data', p. 299. Microsoft, 2002.
+OWASP: Logging Cheat Sheet - Data to exclude.
+
+
+
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs b/rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs
new file mode 100644
index 000000000000..dd51bf617533
--- /dev/null
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs
@@ -0,0 +1,2 @@
+let password = "P@ssw0rd"
+info!("User password changed to {password}")
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLoggingGood.rs b/rust/ql/src/queries/security/CWE-312/CleartextLoggingGood.rs
new file mode 100644
index 000000000000..f2af0ce9e6b7
--- /dev/null
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLoggingGood.rs
@@ -0,0 +1,2 @@
+let password = "P@ssw0rd"
+info!("User password changed")
From 4214c837b89bf72a9f1822e6e89ad10e4e456364 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 23 Jan 2025 18:03:25 +0000
Subject: [PATCH 12/21] Rust: Clean up the query message.
---
.../security/CWE-312/CleartextLogging.ql | 4 +-
.../CWE-312/CleartextLogging.expected | 130 +++++++++---------
2 files changed, 66 insertions(+), 68 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
index 3c1587ab0110..16f4b3d4c7a5 100644
--- a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
@@ -55,7 +55,5 @@ import CleartextLoggingFlow::PathGraph
from CleartextLoggingFlow::PathNode source, CleartextLoggingFlow::PathNode sink
where CleartextLoggingFlow::flowPath(source, sink)
-select sink.getNode(), source, sink,
- "This operation writes '" + sink.toString() +
- "' to a log file. It may contain unencrypted sensitive data from $@.", source,
+select sink.getNode(), source, sink, "This operation writes $@ to a log file.", source,
source.getNode().toString()
diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
index 85e4783aabc5..b7a2dae6f653 100644
--- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
+++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
@@ -1,52 +1,52 @@
#select
-| test_logging.rs:42:5:42:36 | ...::log | test_logging.rs:42:28:42:35 | password | test_logging.rs:42:5:42:36 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:42:28:42:35 | password | password |
-| test_logging.rs:43:5:43:36 | ...::log | test_logging.rs:43:28:43:35 | password | test_logging.rs:43:5:43:36 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:43:28:43:35 | password | password |
-| test_logging.rs:44:5:44:35 | ...::log | test_logging.rs:44:27:44:34 | password | test_logging.rs:44:5:44:35 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:44:27:44:34 | password | password |
-| test_logging.rs:45:5:45:36 | ...::log | test_logging.rs:45:28:45:35 | password | test_logging.rs:45:5:45:36 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:45:28:45:35 | password | password |
-| test_logging.rs:46:5:46:35 | ...::log | test_logging.rs:46:27:46:34 | password | test_logging.rs:46:5:46:35 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:46:27:46:34 | password | password |
-| test_logging.rs:47:5:47:48 | ...::log | test_logging.rs:47:40:47:47 | password | test_logging.rs:47:5:47:48 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:47:40:47:47 | password | password |
-| test_logging.rs:52:5:52:36 | ...::log | test_logging.rs:52:28:52:35 | password | test_logging.rs:52:5:52:36 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:52:28:52:35 | password | password |
-| test_logging.rs:54:5:54:49 | ...::log | test_logging.rs:54:41:54:48 | password | test_logging.rs:54:5:54:49 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:54:41:54:48 | password | password |
-| test_logging.rs:56:5:56:47 | ...::log | test_logging.rs:56:39:56:46 | password | test_logging.rs:56:5:56:47 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:56:39:56:46 | password | password |
-| test_logging.rs:57:5:57:34 | ...::log | test_logging.rs:57:24:57:31 | password | test_logging.rs:57:5:57:34 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:57:24:57:31 | password | password |
-| test_logging.rs:58:5:58:36 | ...::log | test_logging.rs:58:24:58:31 | password | test_logging.rs:58:5:58:36 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:58:24:58:31 | password | password |
-| test_logging.rs:60:5:60:54 | ...::log | test_logging.rs:60:46:60:53 | password | test_logging.rs:60:5:60:54 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:60:46:60:53 | password | password |
-| test_logging.rs:61:5:61:55 | ...::log | test_logging.rs:61:21:61:28 | password | test_logging.rs:61:5:61:55 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:61:21:61:28 | password | password |
-| test_logging.rs:65:5:65:48 | ...::log | test_logging.rs:65:40:65:47 | password | test_logging.rs:65:5:65:48 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:65:40:65:47 | password | password |
-| test_logging.rs:67:5:67:66 | ...::log | test_logging.rs:67:58:67:65 | password | test_logging.rs:67:5:67:66 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:67:58:67:65 | password | password |
-| test_logging.rs:68:5:68:67 | ...::log | test_logging.rs:68:19:68:26 | password | test_logging.rs:68:5:68:67 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:68:19:68:26 | password | password |
-| test_logging.rs:72:5:72:47 | ...::log::<...> | test_logging.rs:72:39:72:46 | password | test_logging.rs:72:5:72:47 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:72:39:72:46 | password | password |
-| test_logging.rs:74:5:74:65 | ...::log::<...> | test_logging.rs:74:57:74:64 | password | test_logging.rs:74:5:74:65 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:74:57:74:64 | password | password |
-| test_logging.rs:75:5:75:51 | ...::log::<...> | test_logging.rs:75:21:75:28 | password | test_logging.rs:75:5:75:51 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:75:21:75:28 | password | password |
-| test_logging.rs:76:5:76:47 | ...::log::<...> | test_logging.rs:76:39:76:46 | password | test_logging.rs:76:5:76:47 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:76:39:76:46 | password | password |
-| test_logging.rs:82:5:82:44 | ...::log::<...> | test_logging.rs:82:36:82:43 | password | test_logging.rs:82:5:82:44 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:82:36:82:43 | password | password |
-| test_logging.rs:84:5:84:62 | ...::log::<...> | test_logging.rs:84:54:84:61 | password | test_logging.rs:84:5:84:62 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:84:54:84:61 | password | password |
-| test_logging.rs:85:5:85:48 | ...::log::<...> | test_logging.rs:85:21:85:28 | password | test_logging.rs:85:5:85:48 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:85:21:85:28 | password | password |
-| test_logging.rs:86:5:86:44 | ...::log::<...> | test_logging.rs:86:36:86:43 | password | test_logging.rs:86:5:86:44 | ...::log::<...> | This operation writes '...::log::<...>' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:86:36:86:43 | password | password |
-| test_logging.rs:94:5:94:29 | ...::log | test_logging.rs:93:15:93:22 | password | test_logging.rs:94:5:94:29 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:93:15:93:22 | password | password |
-| test_logging.rs:97:5:97:19 | ...::log | test_logging.rs:96:42:96:49 | password | test_logging.rs:97:5:97:19 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:96:42:96:49 | password | password |
-| test_logging.rs:100:5:100:19 | ...::log | test_logging.rs:99:38:99:45 | password | test_logging.rs:100:5:100:19 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:99:38:99:45 | password | password |
-| test_logging.rs:118:5:118:42 | ...::log | test_logging.rs:118:28:118:41 | get_password(...) | test_logging.rs:118:5:118:42 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:118:28:118:41 | get_password(...) | get_password(...) |
-| test_logging.rs:131:5:131:32 | ...::log | test_logging.rs:129:25:129:32 | password | test_logging.rs:131:5:131:32 | ...::log | This operation writes '...::log' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:129:25:129:32 | password | password |
-| test_logging.rs:152:5:152:36 | ...::_print | test_logging.rs:152:28:152:35 | password | test_logging.rs:152:5:152:36 | ...::_print | This operation writes '...::_print' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:152:28:152:35 | password | password |
-| test_logging.rs:153:5:153:38 | ...::_print | test_logging.rs:153:30:153:37 | password | test_logging.rs:153:5:153:38 | ...::_print | This operation writes '...::_print' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:153:30:153:37 | password | password |
-| test_logging.rs:154:5:154:37 | ...::_eprint | test_logging.rs:154:29:154:36 | password | test_logging.rs:154:5:154:37 | ...::_eprint | This operation writes '...::_eprint' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:154:29:154:36 | password | password |
-| test_logging.rs:155:5:155:39 | ...::_eprint | test_logging.rs:155:31:155:38 | password | test_logging.rs:155:5:155:39 | ...::_eprint | This operation writes '...::_eprint' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:155:31:155:38 | password | password |
-| test_logging.rs:158:16:158:47 | ...::panic_fmt | test_logging.rs:158:39:158:46 | password | test_logging.rs:158:16:158:47 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:158:39:158:46 | password | password |
-| test_logging.rs:159:16:159:46 | ...::panic_fmt | test_logging.rs:159:38:159:45 | password | test_logging.rs:159:16:159:46 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:159:38:159:45 | password | password |
-| test_logging.rs:160:16:160:55 | ...::panic_fmt | test_logging.rs:160:47:160:54 | password | test_logging.rs:160:16:160:55 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:160:47:160:54 | password | password |
-| test_logging.rs:161:16:161:53 | ...::panic_fmt | test_logging.rs:161:45:161:52 | password | test_logging.rs:161:16:161:53 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:161:45:161:52 | password | password |
-| test_logging.rs:162:16:162:55 | ...::panic_fmt | test_logging.rs:162:47:162:54 | password | test_logging.rs:162:16:162:55 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:162:47:162:54 | password | password |
-| test_logging.rs:163:16:163:57 | ...::assert_failed | test_logging.rs:163:49:163:56 | password | test_logging.rs:163:16:163:57 | ...::assert_failed | This operation writes '...::assert_failed' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:163:49:163:56 | password | password |
-| test_logging.rs:164:16:164:57 | ...::assert_failed | test_logging.rs:164:49:164:56 | password | test_logging.rs:164:16:164:57 | ...::assert_failed | This operation writes '...::assert_failed' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:164:49:164:56 | password | password |
-| test_logging.rs:165:16:165:61 | ...::panic_fmt | test_logging.rs:165:53:165:60 | password | test_logging.rs:165:16:165:61 | ...::panic_fmt | This operation writes '...::panic_fmt' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:165:53:165:60 | password | password |
-| test_logging.rs:166:16:166:63 | ...::assert_failed | test_logging.rs:166:55:166:62 | password | test_logging.rs:166:16:166:63 | ...::assert_failed | This operation writes '...::assert_failed' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:166:55:166:62 | password | password |
-| test_logging.rs:167:17:167:64 | ...::assert_failed | test_logging.rs:167:56:167:63 | password | test_logging.rs:167:17:167:64 | ...::assert_failed | This operation writes '...::assert_failed' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:167:56:167:63 | password | password |
-| test_logging.rs:168:27:168:32 | expect | test_logging.rs:168:58:168:65 | password | test_logging.rs:168:27:168:32 | expect | This operation writes 'expect' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:168:58:168:65 | password | password |
-| test_logging.rs:174:30:174:34 | write | test_logging.rs:174:60:174:67 | password | test_logging.rs:174:30:174:34 | write | This operation writes 'write' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:174:60:174:67 | password | password |
-| test_logging.rs:175:30:175:38 | write_all | test_logging.rs:175:64:175:71 | password | test_logging.rs:175:30:175:38 | write_all | This operation writes 'write_all' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:175:64:175:71 | password | password |
-| test_logging.rs:178:9:178:13 | write | test_logging.rs:178:39:178:46 | password | test_logging.rs:178:9:178:13 | write | This operation writes 'write' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:178:39:178:46 | password | password |
-| test_logging.rs:181:9:181:13 | write | test_logging.rs:181:39:181:46 | password | test_logging.rs:181:9:181:13 | write | This operation writes 'write' to a log file. It may contain unencrypted sensitive data from $@. | test_logging.rs:181:39:181:46 | password | password |
+| test_logging.rs:42:5:42:36 | ...::log | test_logging.rs:42:28:42:35 | password | test_logging.rs:42:5:42:36 | ...::log | This operation writes $@ to a log file. | test_logging.rs:42:28:42:35 | password | password |
+| test_logging.rs:43:5:43:36 | ...::log | test_logging.rs:43:28:43:35 | password | test_logging.rs:43:5:43:36 | ...::log | This operation writes $@ to a log file. | test_logging.rs:43:28:43:35 | password | password |
+| test_logging.rs:44:5:44:35 | ...::log | test_logging.rs:44:27:44:34 | password | test_logging.rs:44:5:44:35 | ...::log | This operation writes $@ to a log file. | test_logging.rs:44:27:44:34 | password | password |
+| test_logging.rs:45:5:45:36 | ...::log | test_logging.rs:45:28:45:35 | password | test_logging.rs:45:5:45:36 | ...::log | This operation writes $@ to a log file. | test_logging.rs:45:28:45:35 | password | password |
+| test_logging.rs:46:5:46:35 | ...::log | test_logging.rs:46:27:46:34 | password | test_logging.rs:46:5:46:35 | ...::log | This operation writes $@ to a log file. | test_logging.rs:46:27:46:34 | password | password |
+| test_logging.rs:47:5:47:48 | ...::log | test_logging.rs:47:40:47:47 | password | test_logging.rs:47:5:47:48 | ...::log | This operation writes $@ to a log file. | test_logging.rs:47:40:47:47 | password | password |
+| test_logging.rs:52:5:52:36 | ...::log | test_logging.rs:52:28:52:35 | password | test_logging.rs:52:5:52:36 | ...::log | This operation writes $@ to a log file. | test_logging.rs:52:28:52:35 | password | password |
+| test_logging.rs:54:5:54:49 | ...::log | test_logging.rs:54:41:54:48 | password | test_logging.rs:54:5:54:49 | ...::log | This operation writes $@ to a log file. | test_logging.rs:54:41:54:48 | password | password |
+| test_logging.rs:56:5:56:47 | ...::log | test_logging.rs:56:39:56:46 | password | test_logging.rs:56:5:56:47 | ...::log | This operation writes $@ to a log file. | test_logging.rs:56:39:56:46 | password | password |
+| test_logging.rs:57:5:57:34 | ...::log | test_logging.rs:57:24:57:31 | password | test_logging.rs:57:5:57:34 | ...::log | This operation writes $@ to a log file. | test_logging.rs:57:24:57:31 | password | password |
+| test_logging.rs:58:5:58:36 | ...::log | test_logging.rs:58:24:58:31 | password | test_logging.rs:58:5:58:36 | ...::log | This operation writes $@ to a log file. | test_logging.rs:58:24:58:31 | password | password |
+| test_logging.rs:60:5:60:54 | ...::log | test_logging.rs:60:46:60:53 | password | test_logging.rs:60:5:60:54 | ...::log | This operation writes $@ to a log file. | test_logging.rs:60:46:60:53 | password | password |
+| test_logging.rs:61:5:61:55 | ...::log | test_logging.rs:61:21:61:28 | password | test_logging.rs:61:5:61:55 | ...::log | This operation writes $@ to a log file. | test_logging.rs:61:21:61:28 | password | password |
+| test_logging.rs:65:5:65:48 | ...::log | test_logging.rs:65:40:65:47 | password | test_logging.rs:65:5:65:48 | ...::log | This operation writes $@ to a log file. | test_logging.rs:65:40:65:47 | password | password |
+| test_logging.rs:67:5:67:66 | ...::log | test_logging.rs:67:58:67:65 | password | test_logging.rs:67:5:67:66 | ...::log | This operation writes $@ to a log file. | test_logging.rs:67:58:67:65 | password | password |
+| test_logging.rs:68:5:68:67 | ...::log | test_logging.rs:68:19:68:26 | password | test_logging.rs:68:5:68:67 | ...::log | This operation writes $@ to a log file. | test_logging.rs:68:19:68:26 | password | password |
+| test_logging.rs:72:5:72:47 | ...::log::<...> | test_logging.rs:72:39:72:46 | password | test_logging.rs:72:5:72:47 | ...::log::<...> | This operation writes $@ to a log file. | test_logging.rs:72:39:72:46 | password | password |
+| test_logging.rs:74:5:74:65 | ...::log::<...> | test_logging.rs:74:57:74:64 | password | test_logging.rs:74:5:74:65 | ...::log::<...> | This operation writes $@ to a log file. | test_logging.rs:74:57:74:64 | password | password |
+| test_logging.rs:75:5:75:51 | ...::log::<...> | test_logging.rs:75:21:75:28 | password | test_logging.rs:75:5:75:51 | ...::log::<...> | This operation writes $@ to a log file. | test_logging.rs:75:21:75:28 | password | password |
+| test_logging.rs:76:5:76:47 | ...::log::<...> | test_logging.rs:76:39:76:46 | password | test_logging.rs:76:5:76:47 | ...::log::<...> | This operation writes $@ to a log file. | test_logging.rs:76:39:76:46 | password | password |
+| test_logging.rs:82:5:82:44 | ...::log::<...> | test_logging.rs:82:36:82:43 | password | test_logging.rs:82:5:82:44 | ...::log::<...> | This operation writes $@ to a log file. | test_logging.rs:82:36:82:43 | password | password |
+| test_logging.rs:84:5:84:62 | ...::log::<...> | test_logging.rs:84:54:84:61 | password | test_logging.rs:84:5:84:62 | ...::log::<...> | This operation writes $@ to a log file. | test_logging.rs:84:54:84:61 | password | password |
+| test_logging.rs:85:5:85:48 | ...::log::<...> | test_logging.rs:85:21:85:28 | password | test_logging.rs:85:5:85:48 | ...::log::<...> | This operation writes $@ to a log file. | test_logging.rs:85:21:85:28 | password | password |
+| test_logging.rs:86:5:86:44 | ...::log::<...> | test_logging.rs:86:36:86:43 | password | test_logging.rs:86:5:86:44 | ...::log::<...> | This operation writes $@ to a log file. | test_logging.rs:86:36:86:43 | password | password |
+| test_logging.rs:94:5:94:29 | ...::log | test_logging.rs:93:15:93:22 | password | test_logging.rs:94:5:94:29 | ...::log | This operation writes $@ to a log file. | test_logging.rs:93:15:93:22 | password | password |
+| test_logging.rs:97:5:97:19 | ...::log | test_logging.rs:96:42:96:49 | password | test_logging.rs:97:5:97:19 | ...::log | This operation writes $@ to a log file. | test_logging.rs:96:42:96:49 | password | password |
+| test_logging.rs:100:5:100:19 | ...::log | test_logging.rs:99:38:99:45 | password | test_logging.rs:100:5:100:19 | ...::log | This operation writes $@ to a log file. | test_logging.rs:99:38:99:45 | password | password |
+| test_logging.rs:118:5:118:42 | ...::log | test_logging.rs:118:28:118:41 | get_password(...) | test_logging.rs:118:5:118:42 | ...::log | This operation writes $@ to a log file. | test_logging.rs:118:28:118:41 | get_password(...) | get_password(...) |
+| test_logging.rs:131:5:131:32 | ...::log | test_logging.rs:129:25:129:32 | password | test_logging.rs:131:5:131:32 | ...::log | This operation writes $@ to a log file. | test_logging.rs:129:25:129:32 | password | password |
+| test_logging.rs:152:5:152:36 | ...::_print | test_logging.rs:152:28:152:35 | password | test_logging.rs:152:5:152:36 | ...::_print | This operation writes $@ to a log file. | test_logging.rs:152:28:152:35 | password | password |
+| test_logging.rs:153:5:153:38 | ...::_print | test_logging.rs:153:30:153:37 | password | test_logging.rs:153:5:153:38 | ...::_print | This operation writes $@ to a log file. | test_logging.rs:153:30:153:37 | password | password |
+| test_logging.rs:154:5:154:37 | ...::_eprint | test_logging.rs:154:29:154:36 | password | test_logging.rs:154:5:154:37 | ...::_eprint | This operation writes $@ to a log file. | test_logging.rs:154:29:154:36 | password | password |
+| test_logging.rs:155:5:155:39 | ...::_eprint | test_logging.rs:155:31:155:38 | password | test_logging.rs:155:5:155:39 | ...::_eprint | This operation writes $@ to a log file. | test_logging.rs:155:31:155:38 | password | password |
+| test_logging.rs:158:16:158:47 | ...::panic_fmt | test_logging.rs:158:39:158:46 | password | test_logging.rs:158:16:158:47 | ...::panic_fmt | This operation writes $@ to a log file. | test_logging.rs:158:39:158:46 | password | password |
+| test_logging.rs:159:16:159:46 | ...::panic_fmt | test_logging.rs:159:38:159:45 | password | test_logging.rs:159:16:159:46 | ...::panic_fmt | This operation writes $@ to a log file. | test_logging.rs:159:38:159:45 | password | password |
+| test_logging.rs:160:16:160:55 | ...::panic_fmt | test_logging.rs:160:47:160:54 | password | test_logging.rs:160:16:160:55 | ...::panic_fmt | This operation writes $@ to a log file. | test_logging.rs:160:47:160:54 | password | password |
+| test_logging.rs:161:16:161:53 | ...::panic_fmt | test_logging.rs:161:45:161:52 | password | test_logging.rs:161:16:161:53 | ...::panic_fmt | This operation writes $@ to a log file. | test_logging.rs:161:45:161:52 | password | password |
+| test_logging.rs:162:16:162:55 | ...::panic_fmt | test_logging.rs:162:47:162:54 | password | test_logging.rs:162:16:162:55 | ...::panic_fmt | This operation writes $@ to a log file. | test_logging.rs:162:47:162:54 | password | password |
+| test_logging.rs:163:16:163:57 | ...::assert_failed | test_logging.rs:163:49:163:56 | password | test_logging.rs:163:16:163:57 | ...::assert_failed | This operation writes $@ to a log file. | test_logging.rs:163:49:163:56 | password | password |
+| test_logging.rs:164:16:164:57 | ...::assert_failed | test_logging.rs:164:49:164:56 | password | test_logging.rs:164:16:164:57 | ...::assert_failed | This operation writes $@ to a log file. | test_logging.rs:164:49:164:56 | password | password |
+| test_logging.rs:165:16:165:61 | ...::panic_fmt | test_logging.rs:165:53:165:60 | password | test_logging.rs:165:16:165:61 | ...::panic_fmt | This operation writes $@ to a log file. | test_logging.rs:165:53:165:60 | password | password |
+| test_logging.rs:166:16:166:63 | ...::assert_failed | test_logging.rs:166:55:166:62 | password | test_logging.rs:166:16:166:63 | ...::assert_failed | This operation writes $@ to a log file. | test_logging.rs:166:55:166:62 | password | password |
+| test_logging.rs:167:17:167:64 | ...::assert_failed | test_logging.rs:167:56:167:63 | password | test_logging.rs:167:17:167:64 | ...::assert_failed | This operation writes $@ to a log file. | test_logging.rs:167:56:167:63 | password | password |
+| test_logging.rs:168:27:168:32 | expect | test_logging.rs:168:58:168:65 | password | test_logging.rs:168:27:168:32 | expect | This operation writes $@ to a log file. | test_logging.rs:168:58:168:65 | password | password |
+| test_logging.rs:174:30:174:34 | write | test_logging.rs:174:60:174:67 | password | test_logging.rs:174:30:174:34 | write | This operation writes $@ to a log file. | test_logging.rs:174:60:174:67 | password | password |
+| test_logging.rs:175:30:175:38 | write_all | test_logging.rs:175:64:175:71 | password | test_logging.rs:175:30:175:38 | write_all | This operation writes $@ to a log file. | test_logging.rs:175:64:175:71 | password | password |
+| test_logging.rs:178:9:178:13 | write | test_logging.rs:178:39:178:46 | password | test_logging.rs:178:9:178:13 | write | This operation writes $@ to a log file. | test_logging.rs:178:39:178:46 | password | password |
+| test_logging.rs:181:9:181:13 | write | test_logging.rs:181:39:181:46 | password | test_logging.rs:181:9:181:13 | write | This operation writes $@ to a log file. | test_logging.rs:181:39:181:46 | password | password |
edges
| test_logging.rs:42:12:42:35 | MacroExpr | test_logging.rs:42:5:42:36 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:42:28:42:35 | password | test_logging.rs:42:12:42:35 | MacroExpr | provenance | |
@@ -136,8 +136,8 @@ edges
| test_logging.rs:99:14:99:46 | res | test_logging.rs:99:22:99:45 | { ... } | provenance | |
| test_logging.rs:99:22:99:45 | ...::format(...) | test_logging.rs:99:14:99:46 | res | provenance | |
| test_logging.rs:99:22:99:45 | ...::must_use(...) | test_logging.rs:99:9:99:10 | m3 | provenance | |
-| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:27 |
-| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:26 |
+| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:37 |
+| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:36 |
| test_logging.rs:99:38:99:45 | password | test_logging.rs:99:22:99:45 | MacroExpr | provenance | |
| test_logging.rs:100:11:100:18 | MacroExpr | test_logging.rs:100:5:100:19 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:118:12:118:41 | MacroExpr | test_logging.rs:118:5:118:42 | ...::log | provenance | MaD:0 Sink:MaD:0 |
@@ -180,45 +180,45 @@ edges
| test_logging.rs:167:40:167:63 | ...::Some(...) [Some] | test_logging.rs:167:17:167:64 | ...::assert_failed | provenance | MaD:10 Sink:MaD:10 |
| test_logging.rs:167:40:167:63 | MacroExpr | test_logging.rs:167:40:167:63 | ...::Some(...) [Some] | provenance | |
| test_logging.rs:167:56:167:63 | password | test_logging.rs:167:40:167:63 | MacroExpr | provenance | |
-| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:24 |
+| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:34 |
| test_logging.rs:168:34:168:66 | res | test_logging.rs:168:42:168:65 | { ... } | provenance | |
| test_logging.rs:168:34:168:75 | ... .as_str(...) | test_logging.rs:168:27:168:32 | expect | provenance | MaD:11 Sink:MaD:11 |
| test_logging.rs:168:42:168:65 | ...::format(...) | test_logging.rs:168:34:168:66 | res | provenance | |
| test_logging.rs:168:42:168:65 | ...::must_use(...) | test_logging.rs:168:34:168:66 | MacroExpr | provenance | |
-| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:27 |
-| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:26 |
+| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:37 |
+| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:36 |
| test_logging.rs:168:58:168:65 | password | test_logging.rs:168:42:168:65 | MacroExpr | provenance | |
-| test_logging.rs:174:36:174:68 | MacroExpr | test_logging.rs:174:36:174:79 | ... .as_bytes(...) | provenance | MaD:25 |
+| test_logging.rs:174:36:174:68 | MacroExpr | test_logging.rs:174:36:174:79 | ... .as_bytes(...) | provenance | MaD:35 |
| test_logging.rs:174:36:174:68 | res | test_logging.rs:174:44:174:67 | { ... } | provenance | |
| test_logging.rs:174:36:174:79 | ... .as_bytes(...) | test_logging.rs:174:30:174:34 | write | provenance | MaD:5 Sink:MaD:5 |
| test_logging.rs:174:44:174:67 | ...::format(...) | test_logging.rs:174:36:174:68 | res | provenance | |
| test_logging.rs:174:44:174:67 | ...::must_use(...) | test_logging.rs:174:36:174:68 | MacroExpr | provenance | |
-| test_logging.rs:174:44:174:67 | MacroExpr | test_logging.rs:174:44:174:67 | ...::format(...) | provenance | MaD:27 |
-| test_logging.rs:174:44:174:67 | { ... } | test_logging.rs:174:44:174:67 | ...::must_use(...) | provenance | MaD:26 |
+| test_logging.rs:174:44:174:67 | MacroExpr | test_logging.rs:174:44:174:67 | ...::format(...) | provenance | MaD:37 |
+| test_logging.rs:174:44:174:67 | { ... } | test_logging.rs:174:44:174:67 | ...::must_use(...) | provenance | MaD:36 |
| test_logging.rs:174:60:174:67 | password | test_logging.rs:174:44:174:67 | MacroExpr | provenance | |
-| test_logging.rs:175:40:175:72 | MacroExpr | test_logging.rs:175:40:175:83 | ... .as_bytes(...) | provenance | MaD:25 |
+| test_logging.rs:175:40:175:72 | MacroExpr | test_logging.rs:175:40:175:83 | ... .as_bytes(...) | provenance | MaD:35 |
| test_logging.rs:175:40:175:72 | res | test_logging.rs:175:48:175:71 | { ... } | provenance | |
| test_logging.rs:175:40:175:83 | ... .as_bytes(...) | test_logging.rs:175:30:175:38 | write_all | provenance | MaD:6 Sink:MaD:6 |
| test_logging.rs:175:48:175:71 | ...::format(...) | test_logging.rs:175:40:175:72 | res | provenance | |
| test_logging.rs:175:48:175:71 | ...::must_use(...) | test_logging.rs:175:40:175:72 | MacroExpr | provenance | |
-| test_logging.rs:175:48:175:71 | MacroExpr | test_logging.rs:175:48:175:71 | ...::format(...) | provenance | MaD:27 |
-| test_logging.rs:175:48:175:71 | { ... } | test_logging.rs:175:48:175:71 | ...::must_use(...) | provenance | MaD:26 |
+| test_logging.rs:175:48:175:71 | MacroExpr | test_logging.rs:175:48:175:71 | ...::format(...) | provenance | MaD:37 |
+| test_logging.rs:175:48:175:71 | { ... } | test_logging.rs:175:48:175:71 | ...::must_use(...) | provenance | MaD:36 |
| test_logging.rs:175:64:175:71 | password | test_logging.rs:175:48:175:71 | MacroExpr | provenance | |
-| test_logging.rs:178:15:178:47 | MacroExpr | test_logging.rs:178:15:178:58 | ... .as_bytes(...) | provenance | MaD:25 |
+| test_logging.rs:178:15:178:47 | MacroExpr | test_logging.rs:178:15:178:58 | ... .as_bytes(...) | provenance | MaD:35 |
| test_logging.rs:178:15:178:47 | res | test_logging.rs:178:23:178:46 | { ... } | provenance | |
| test_logging.rs:178:15:178:58 | ... .as_bytes(...) | test_logging.rs:178:9:178:13 | write | provenance | MaD:5 Sink:MaD:5 |
| test_logging.rs:178:23:178:46 | ...::format(...) | test_logging.rs:178:15:178:47 | res | provenance | |
| test_logging.rs:178:23:178:46 | ...::must_use(...) | test_logging.rs:178:15:178:47 | MacroExpr | provenance | |
-| test_logging.rs:178:23:178:46 | MacroExpr | test_logging.rs:178:23:178:46 | ...::format(...) | provenance | MaD:27 |
-| test_logging.rs:178:23:178:46 | { ... } | test_logging.rs:178:23:178:46 | ...::must_use(...) | provenance | MaD:26 |
+| test_logging.rs:178:23:178:46 | MacroExpr | test_logging.rs:178:23:178:46 | ...::format(...) | provenance | MaD:37 |
+| test_logging.rs:178:23:178:46 | { ... } | test_logging.rs:178:23:178:46 | ...::must_use(...) | provenance | MaD:36 |
| test_logging.rs:178:39:178:46 | password | test_logging.rs:178:23:178:46 | MacroExpr | provenance | |
-| test_logging.rs:181:15:181:47 | MacroExpr | test_logging.rs:181:15:181:58 | ... .as_bytes(...) | provenance | MaD:25 |
+| test_logging.rs:181:15:181:47 | MacroExpr | test_logging.rs:181:15:181:58 | ... .as_bytes(...) | provenance | MaD:35 |
| test_logging.rs:181:15:181:47 | res | test_logging.rs:181:23:181:46 | { ... } | provenance | |
| test_logging.rs:181:15:181:58 | ... .as_bytes(...) | test_logging.rs:181:9:181:13 | write | provenance | MaD:7 Sink:MaD:7 |
| test_logging.rs:181:23:181:46 | ...::format(...) | test_logging.rs:181:15:181:47 | res | provenance | |
| test_logging.rs:181:23:181:46 | ...::must_use(...) | test_logging.rs:181:15:181:47 | MacroExpr | provenance | |
-| test_logging.rs:181:23:181:46 | MacroExpr | test_logging.rs:181:23:181:46 | ...::format(...) | provenance | MaD:27 |
-| test_logging.rs:181:23:181:46 | { ... } | test_logging.rs:181:23:181:46 | ...::must_use(...) | provenance | MaD:26 |
+| test_logging.rs:181:23:181:46 | MacroExpr | test_logging.rs:181:23:181:46 | ...::format(...) | provenance | MaD:37 |
+| test_logging.rs:181:23:181:46 | { ... } | test_logging.rs:181:23:181:46 | ...::must_use(...) | provenance | MaD:36 |
| test_logging.rs:181:39:181:46 | password | test_logging.rs:181:23:181:46 | MacroExpr | provenance | |
nodes
| test_logging.rs:42:5:42:36 | ...::log | semmle.label | ...::log |
From 613a1656f3cbd067395f3a0f5920e42d6bea4f32 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 23 Jan 2025 18:13:59 +0000
Subject: [PATCH 13/21] Rust: Simplify QL slightly.
---
rust/ql/src/queries/security/CWE-312/CleartextLogging.ql | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
index 16f4b3d4c7a5..d9a3fb9bc5a6 100644
--- a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
@@ -38,8 +38,7 @@ module CleartextLoggingConfig implements DataFlow::ConfigSig {
predicate isAdditionalFlowStep(Node node1, Node node2) {
// flow from `a` to `&a`
- node2.(Node::ExprNode).asExpr().getExpr().(RefExpr).getExpr() =
- node1.(Node::ExprNode).asExpr().getExpr()
+ node2.asExpr().getExpr().(RefExpr).getExpr() = node1.asExpr().getExpr()
}
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
From 55705232f64fdf194c29fdbf67765e24d9c9359b Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 23 Jan 2025 18:18:05 +0000
Subject: [PATCH 14/21] Update
rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs b/rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs
index dd51bf617533..f031d03a2b07 100644
--- a/rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs
@@ -1,2 +1,2 @@
-let password = "P@ssw0rd"
+let password = "P@ssw0rd";
info!("User password changed to {password}")
From d27a71eaafd749072d536078da134f6674ed0be7 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 23 Jan 2025 18:21:27 +0000
Subject: [PATCH 15/21] Rust: Minor fixes.
---
rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp | 2 +-
rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs | 2 +-
rust/ql/src/queries/security/CWE-312/CleartextLoggingGood.rs | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp b/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp
index 29ffeb4be6dc..d545d0158528 100644
--- a/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp
@@ -7,7 +7,7 @@
Sensitive user data and system information that is logged could be seen by an attacker when it is
displayed. Also, external processes often store the standard output and standard error streams of
-an application, which will include logged sensitive information.
+an application, which will include logged sensitive information.
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs b/rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs
index f031d03a2b07..15008f19c4c5 100644
--- a/rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLoggingBad.rs
@@ -1,2 +1,2 @@
let password = "P@ssw0rd";
-info!("User password changed to {password}")
+info!("User password changed to {password}");
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLoggingGood.rs b/rust/ql/src/queries/security/CWE-312/CleartextLoggingGood.rs
index f2af0ce9e6b7..ba5fc5dac77e 100644
--- a/rust/ql/src/queries/security/CWE-312/CleartextLoggingGood.rs
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLoggingGood.rs
@@ -1,2 +1,2 @@
-let password = "P@ssw0rd"
-info!("User password changed")
+let password = "P@ssw0rd";
+info!("User password changed");
From 951d1fc9e0110a81fd31a896c51fa621e35297e7 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 23 Jan 2025 18:38:48 +0000
Subject: [PATCH 16/21] Rust: Add missing file.
---
.../security/CleartextLoggingExtensions.qll | 40 +++++++++++++++++++
1 file changed, 40 insertions(+)
create mode 100644 rust/ql/lib/codeql/rust/security/CleartextLoggingExtensions.qll
diff --git a/rust/ql/lib/codeql/rust/security/CleartextLoggingExtensions.qll b/rust/ql/lib/codeql/rust/security/CleartextLoggingExtensions.qll
new file mode 100644
index 000000000000..bfe6da7ac82c
--- /dev/null
+++ b/rust/ql/lib/codeql/rust/security/CleartextLoggingExtensions.qll
@@ -0,0 +1,40 @@
+/**
+ * Provides classes and predicates for reasoning about cleartext logging
+ * of sensitive information vulnerabilities.
+ */
+
+import rust
+private import codeql.rust.dataflow.DataFlow
+private import codeql.rust.dataflow.internal.DataFlowImpl
+private import codeql.rust.security.SensitiveData
+
+/**
+ * Provides default sources, sinks and barriers for detecting cleartext logging
+ * vulnerabilities, as well as extension points for adding your own.
+ */
+module CleartextLogging {
+ /**
+ * A data flow source for cleartext logging vulnerabilities.
+ */
+ abstract class Source extends DataFlow::Node { }
+
+ /**
+ * A data flow sink for cleartext logging vulnerabilities.
+ */
+ abstract class Sink extends DataFlow::Node { }
+
+ /**
+ * A barrier for cleartext logging vulnerabilities.
+ */
+ abstract class Barrier extends DataFlow::Node { }
+
+ /**
+ * Sensitive data, considered as a flow source.
+ */
+ private class SensitiveDataAsSource extends Source instanceof SensitiveData { }
+
+ /** A sink for logging from model data. */
+ private class ModelsAsDataSinks extends Sink {
+ ModelsAsDataSinks() { exists(string s | sinkNode(this, s) and s.matches("log-injection%")) }
+ }
+}
From 44b9a1188b2f1ce10a6f72247dcf7d3f02479a82 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 23 Jan 2025 18:46:35 +0000
Subject: [PATCH 17/21] Rust: Another .qhelp fix.
---
rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp b/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp
index d545d0158528..b2e495f0818f 100644
--- a/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp
@@ -32,7 +32,7 @@ Instead, you should encrypt the credentials, or better still omit them entirely:
M. Dowd, J. McDonald and J. Schuhm, The Art of Software Security Assessment, 1st Edition, Chapter 2 - 'Common Vulnerabilities of Encryption', p. 43. Addison Wesley, 2006.
M. Howard and D. LeBlanc, Writing Secure Code, 2nd Edition, Chapter 9 - 'Protecting Secret Data', p. 299. Microsoft, 2002.
-OWASP: Logging Cheat Sheet - Data to exclude.
+OWASP: Logging Cheat Sheet - Data to exclude.
From f5459d7ba8f51b2d976c71486a59a8c349a7714d Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 23 Jan 2025 18:48:51 +0000
Subject: [PATCH 18/21] Rust: Accept changes to integration test results.
---
rust/ql/integration-tests/hello-project/summary.expected | 4 ++--
.../integration-tests/hello-workspace/summary.cargo.expected | 4 ++--
.../hello-workspace/summary.rust-project.expected | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/rust/ql/integration-tests/hello-project/summary.expected b/rust/ql/integration-tests/hello-project/summary.expected
index 20f4b216b64c..343b06a93b4c 100644
--- a/rust/ql/integration-tests/hello-project/summary.expected
+++ b/rust/ql/integration-tests/hello-project/summary.expected
@@ -14,11 +14,11 @@
| Macro calls - resolved | 2 |
| Macro calls - total | 2 |
| Macro calls - unresolved | 0 |
-| Taint edges - number of edges | 2 |
+| Taint edges - number of edges | 3 |
| Taint reach - nodes tainted | 0 |
| Taint reach - per million nodes | 0 |
| Taint sinks - cryptographic operations | 0 |
-| Taint sinks - query sinks | 0 |
+| Taint sinks - query sinks | 1 |
| Taint sources - active | 0 |
| Taint sources - disabled | 0 |
| Taint sources - sensitive data | 0 |
diff --git a/rust/ql/integration-tests/hello-workspace/summary.cargo.expected b/rust/ql/integration-tests/hello-workspace/summary.cargo.expected
index e0d5ce240a39..24a7bbf392fe 100644
--- a/rust/ql/integration-tests/hello-workspace/summary.cargo.expected
+++ b/rust/ql/integration-tests/hello-workspace/summary.cargo.expected
@@ -14,11 +14,11 @@
| Macro calls - resolved | 2 |
| Macro calls - total | 2 |
| Macro calls - unresolved | 0 |
-| Taint edges - number of edges | 2 |
+| Taint edges - number of edges | 3 |
| Taint reach - nodes tainted | 0 |
| Taint reach - per million nodes | 0 |
| Taint sinks - cryptographic operations | 0 |
-| Taint sinks - query sinks | 0 |
+| Taint sinks - query sinks | 1 |
| Taint sources - active | 0 |
| Taint sources - disabled | 0 |
| Taint sources - sensitive data | 0 |
diff --git a/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected b/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected
index e0d5ce240a39..24a7bbf392fe 100644
--- a/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected
+++ b/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected
@@ -14,11 +14,11 @@
| Macro calls - resolved | 2 |
| Macro calls - total | 2 |
| Macro calls - unresolved | 0 |
-| Taint edges - number of edges | 2 |
+| Taint edges - number of edges | 3 |
| Taint reach - nodes tainted | 0 |
| Taint reach - per million nodes | 0 |
| Taint sinks - cryptographic operations | 0 |
-| Taint sinks - query sinks | 0 |
+| Taint sinks - query sinks | 1 |
| Taint sources - active | 0 |
| Taint sources - disabled | 0 |
| Taint sources - sensitive data | 0 |
From 037d496a6860c224ca83f2462f1dc4b40ba29dd8 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 23 Jan 2025 19:14:12 +0000
Subject: [PATCH 19/21] Rust: Fix some more tests (MaD ID changes and
extraction consistency issues).
---
.../dataflow/local/DataFlowStep.expected | 30 ++++++++--------
.../dataflow/taint/TaintFlowStep.expected | 14 ++++----
.../ExtractionConsistency.expected | 3 ++
.../CWE-312/CleartextLogging.expected | 34 +++++++++----------
4 files changed, 44 insertions(+), 37 deletions(-)
create mode 100644 rust/ql/test/query-tests/security/CWE-312/CONSISTENCY/ExtractionConsistency.expected
diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected
index fdb81065a0eb..776cb29c3d55 100644
--- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected
+++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected
@@ -1,11 +1,11 @@
localStep
-| file://:0:0:0:0 | [summary param] 0 in lang:core::_::::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap_or | MaD:2 |
-| file://:0:0:0:0 | [summary param] 0 in lang:core::_::::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap_or | MaD:5 |
-| file://:0:0:0:0 | [summary param] 0 in lang:core::_::crate::hint::must_use | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::crate::hint::must_use | MaD:7 |
-| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::option::Option::Some(0)] in lang:core::_::::unwrap | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap | MaD:1 |
-| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::option::Option::Some(0)] in lang:core::_::::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap_or | MaD:3 |
-| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::result::Result::Ok(0)] in lang:core::_::::unwrap | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap | MaD:4 |
-| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::result::Result::Ok(0)] in lang:core::_::::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap_or | MaD:6 |
+| file://:0:0:0:0 | [summary param] 0 in lang:core::_::::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap_or | MaD:3 |
+| file://:0:0:0:0 | [summary param] 0 in lang:core::_::::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap_or | MaD:6 |
+| file://:0:0:0:0 | [summary param] 0 in lang:core::_::crate::hint::must_use | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::crate::hint::must_use | MaD:8 |
+| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::option::Option::Some(0)] in lang:core::_::::unwrap | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap | MaD:2 |
+| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::option::Option::Some(0)] in lang:core::_::::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap_or | MaD:4 |
+| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::result::Result::Ok(0)] in lang:core::_::::unwrap | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap | MaD:5 |
+| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::result::Result::Ok(0)] in lang:core::_::::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap_or | MaD:7 |
| main.rs:3:11:3:11 | [SSA] i | main.rs:4:12:4:12 | i | |
| main.rs:3:11:3:11 | i | main.rs:3:11:3:11 | [SSA] i | |
| main.rs:3:11:3:16 | ...: i64 | main.rs:3:11:3:11 | i | |
@@ -14,6 +14,7 @@ localStep
| main.rs:7:9:7:9 | s | main.rs:7:9:7:9 | [SSA] s | |
| main.rs:7:9:7:14 | ...: i64 | main.rs:7:9:7:9 | s | |
| main.rs:8:14:8:20 | FormatArgsExpr | main.rs:8:14:8:20 | MacroExpr | |
+| main.rs:8:14:8:20 | MacroExpr | main.rs:8:5:8:21 | ...::_print | MaD:1 |
| main.rs:19:9:19:9 | [SSA] s | main.rs:20:10:20:10 | s | |
| main.rs:19:9:19:9 | s | main.rs:19:9:19:9 | [SSA] s | |
| main.rs:19:13:19:21 | source(...) | main.rs:19:9:19:9 | s | |
@@ -468,13 +469,14 @@ localStep
| main.rs:436:13:436:33 | result_questionmark(...) | main.rs:436:9:436:9 | _ | |
| main.rs:448:36:448:41 | ...::new(...) | main.rs:448:36:448:41 | MacroExpr | |
models
-| 1 | Summary: lang:core; ::unwrap; Argument[self].Variant[crate::option::Option::Some(0)]; ReturnValue; value |
-| 2 | Summary: lang:core; ::unwrap_or; Argument[0]; ReturnValue; value |
-| 3 | Summary: lang:core; ::unwrap_or; Argument[self].Variant[crate::option::Option::Some(0)]; ReturnValue; value |
-| 4 | Summary: lang:core; ::unwrap; Argument[self].Variant[crate::result::Result::Ok(0)]; ReturnValue; value |
-| 5 | Summary: lang:core; ::unwrap_or; Argument[0]; ReturnValue; value |
-| 6 | Summary: lang:core; ::unwrap_or; Argument[self].Variant[crate::result::Result::Ok(0)]; ReturnValue; value |
-| 7 | Summary: lang:core; crate::hint::must_use; Argument[0]; ReturnValue; value |
+| 1 | Sink: lang:std; crate::io::stdio::_print; log-injection; Argument[0] |
+| 2 | Summary: lang:core; ::unwrap; Argument[self].Variant[crate::option::Option::Some(0)]; ReturnValue; value |
+| 3 | Summary: lang:core; ::unwrap_or; Argument[0]; ReturnValue; value |
+| 4 | Summary: lang:core; ::unwrap_or; Argument[self].Variant[crate::option::Option::Some(0)]; ReturnValue; value |
+| 5 | Summary: lang:core; ::unwrap; Argument[self].Variant[crate::result::Result::Ok(0)]; ReturnValue; value |
+| 6 | Summary: lang:core; ::unwrap_or; Argument[0]; ReturnValue; value |
+| 7 | Summary: lang:core; ::unwrap_or; Argument[self].Variant[crate::result::Result::Ok(0)]; ReturnValue; value |
+| 8 | Summary: lang:core; crate::hint::must_use; Argument[0]; ReturnValue; value |
storeStep
| file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text |
| main.rs:94:14:94:22 | source(...) | tuple.0 | main.rs:94:13:94:26 | TupleExpr |
diff --git a/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected b/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected
index c42c4d0e9fc5..4ca0f8199314 100644
--- a/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected
+++ b/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected
@@ -1,7 +1,8 @@
additionalTaintStep
-| file://:0:0:0:0 | [summary param] 0 in lang:alloc::_::crate::fmt::format | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::crate::fmt::format | MaD:2 |
-| file://:0:0:0:0 | [summary param] self in lang:alloc::_::::as_str | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_str | MaD:1 |
-| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | MaD:3 |
+| file://:0:0:0:0 | [summary param] 0 in lang:alloc::_::crate::fmt::format | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::crate::fmt::format | MaD:3 |
+| file://:0:0:0:0 | [summary param] self in lang:alloc::_::::as_bytes | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_bytes | MaD:1 |
+| file://:0:0:0:0 | [summary param] self in lang:alloc::_::::as_str | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_str | MaD:2 |
+| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | MaD:4 |
| main.rs:4:5:4:8 | 1000 | main.rs:4:5:4:12 | ... + ... | |
| main.rs:4:12:4:12 | i | main.rs:4:5:4:12 | ... + ... | |
| main.rs:8:20:8:20 | s | main.rs:8:14:8:20 | FormatArgsExpr | |
@@ -19,6 +20,7 @@ additionalTaintStep
| main.rs:64:24:64:27 | s[1] | main.rs:64:18:64:27 | FormatArgsExpr | |
| main.rs:69:9:69:12 | arr2 | main.rs:69:9:69:15 | arr2[1] | |
models
-| 1 | Summary: lang:alloc; ::as_str; Argument[self]; ReturnValue; taint |
-| 2 | Summary: lang:alloc; crate::fmt::format; Argument[0]; ReturnValue; taint |
-| 3 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint |
+| 1 | Summary: lang:alloc; ::as_bytes; Argument[self]; ReturnValue; taint |
+| 2 | Summary: lang:alloc; ::as_str; Argument[self]; ReturnValue; taint |
+| 3 | Summary: lang:alloc; crate::fmt::format; Argument[0]; ReturnValue; taint |
+| 4 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint |
diff --git a/rust/ql/test/query-tests/security/CWE-312/CONSISTENCY/ExtractionConsistency.expected b/rust/ql/test/query-tests/security/CWE-312/CONSISTENCY/ExtractionConsistency.expected
new file mode 100644
index 000000000000..bd41fe2245ab
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-312/CONSISTENCY/ExtractionConsistency.expected
@@ -0,0 +1,3 @@
+extractionWarning
+| test_logging.rs:90:12:90:30 | expected R_PAREN |
+| test_logging.rs:90:12:90:30 | macro expansion failed: the macro '$crate::__private_api::format_args' expands to ERROR but a Expr was expected |
\ No newline at end of file
diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
index b7a2dae6f653..0e61f2898dd6 100644
--- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
+++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
@@ -136,8 +136,8 @@ edges
| test_logging.rs:99:14:99:46 | res | test_logging.rs:99:22:99:45 | { ... } | provenance | |
| test_logging.rs:99:22:99:45 | ...::format(...) | test_logging.rs:99:14:99:46 | res | provenance | |
| test_logging.rs:99:22:99:45 | ...::must_use(...) | test_logging.rs:99:9:99:10 | m3 | provenance | |
-| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:37 |
-| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:36 |
+| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:48 |
+| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:47 |
| test_logging.rs:99:38:99:45 | password | test_logging.rs:99:22:99:45 | MacroExpr | provenance | |
| test_logging.rs:100:11:100:18 | MacroExpr | test_logging.rs:100:5:100:19 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:118:12:118:41 | MacroExpr | test_logging.rs:118:5:118:42 | ...::log | provenance | MaD:0 Sink:MaD:0 |
@@ -180,45 +180,45 @@ edges
| test_logging.rs:167:40:167:63 | ...::Some(...) [Some] | test_logging.rs:167:17:167:64 | ...::assert_failed | provenance | MaD:10 Sink:MaD:10 |
| test_logging.rs:167:40:167:63 | MacroExpr | test_logging.rs:167:40:167:63 | ...::Some(...) [Some] | provenance | |
| test_logging.rs:167:56:167:63 | password | test_logging.rs:167:40:167:63 | MacroExpr | provenance | |
-| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:34 |
+| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:45 |
| test_logging.rs:168:34:168:66 | res | test_logging.rs:168:42:168:65 | { ... } | provenance | |
| test_logging.rs:168:34:168:75 | ... .as_str(...) | test_logging.rs:168:27:168:32 | expect | provenance | MaD:11 Sink:MaD:11 |
| test_logging.rs:168:42:168:65 | ...::format(...) | test_logging.rs:168:34:168:66 | res | provenance | |
| test_logging.rs:168:42:168:65 | ...::must_use(...) | test_logging.rs:168:34:168:66 | MacroExpr | provenance | |
-| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:37 |
-| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:36 |
+| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:48 |
+| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:47 |
| test_logging.rs:168:58:168:65 | password | test_logging.rs:168:42:168:65 | MacroExpr | provenance | |
-| test_logging.rs:174:36:174:68 | MacroExpr | test_logging.rs:174:36:174:79 | ... .as_bytes(...) | provenance | MaD:35 |
+| test_logging.rs:174:36:174:68 | MacroExpr | test_logging.rs:174:36:174:79 | ... .as_bytes(...) | provenance | MaD:46 |
| test_logging.rs:174:36:174:68 | res | test_logging.rs:174:44:174:67 | { ... } | provenance | |
| test_logging.rs:174:36:174:79 | ... .as_bytes(...) | test_logging.rs:174:30:174:34 | write | provenance | MaD:5 Sink:MaD:5 |
| test_logging.rs:174:44:174:67 | ...::format(...) | test_logging.rs:174:36:174:68 | res | provenance | |
| test_logging.rs:174:44:174:67 | ...::must_use(...) | test_logging.rs:174:36:174:68 | MacroExpr | provenance | |
-| test_logging.rs:174:44:174:67 | MacroExpr | test_logging.rs:174:44:174:67 | ...::format(...) | provenance | MaD:37 |
-| test_logging.rs:174:44:174:67 | { ... } | test_logging.rs:174:44:174:67 | ...::must_use(...) | provenance | MaD:36 |
+| test_logging.rs:174:44:174:67 | MacroExpr | test_logging.rs:174:44:174:67 | ...::format(...) | provenance | MaD:48 |
+| test_logging.rs:174:44:174:67 | { ... } | test_logging.rs:174:44:174:67 | ...::must_use(...) | provenance | MaD:47 |
| test_logging.rs:174:60:174:67 | password | test_logging.rs:174:44:174:67 | MacroExpr | provenance | |
-| test_logging.rs:175:40:175:72 | MacroExpr | test_logging.rs:175:40:175:83 | ... .as_bytes(...) | provenance | MaD:35 |
+| test_logging.rs:175:40:175:72 | MacroExpr | test_logging.rs:175:40:175:83 | ... .as_bytes(...) | provenance | MaD:46 |
| test_logging.rs:175:40:175:72 | res | test_logging.rs:175:48:175:71 | { ... } | provenance | |
| test_logging.rs:175:40:175:83 | ... .as_bytes(...) | test_logging.rs:175:30:175:38 | write_all | provenance | MaD:6 Sink:MaD:6 |
| test_logging.rs:175:48:175:71 | ...::format(...) | test_logging.rs:175:40:175:72 | res | provenance | |
| test_logging.rs:175:48:175:71 | ...::must_use(...) | test_logging.rs:175:40:175:72 | MacroExpr | provenance | |
-| test_logging.rs:175:48:175:71 | MacroExpr | test_logging.rs:175:48:175:71 | ...::format(...) | provenance | MaD:37 |
-| test_logging.rs:175:48:175:71 | { ... } | test_logging.rs:175:48:175:71 | ...::must_use(...) | provenance | MaD:36 |
+| test_logging.rs:175:48:175:71 | MacroExpr | test_logging.rs:175:48:175:71 | ...::format(...) | provenance | MaD:48 |
+| test_logging.rs:175:48:175:71 | { ... } | test_logging.rs:175:48:175:71 | ...::must_use(...) | provenance | MaD:47 |
| test_logging.rs:175:64:175:71 | password | test_logging.rs:175:48:175:71 | MacroExpr | provenance | |
-| test_logging.rs:178:15:178:47 | MacroExpr | test_logging.rs:178:15:178:58 | ... .as_bytes(...) | provenance | MaD:35 |
+| test_logging.rs:178:15:178:47 | MacroExpr | test_logging.rs:178:15:178:58 | ... .as_bytes(...) | provenance | MaD:46 |
| test_logging.rs:178:15:178:47 | res | test_logging.rs:178:23:178:46 | { ... } | provenance | |
| test_logging.rs:178:15:178:58 | ... .as_bytes(...) | test_logging.rs:178:9:178:13 | write | provenance | MaD:5 Sink:MaD:5 |
| test_logging.rs:178:23:178:46 | ...::format(...) | test_logging.rs:178:15:178:47 | res | provenance | |
| test_logging.rs:178:23:178:46 | ...::must_use(...) | test_logging.rs:178:15:178:47 | MacroExpr | provenance | |
-| test_logging.rs:178:23:178:46 | MacroExpr | test_logging.rs:178:23:178:46 | ...::format(...) | provenance | MaD:37 |
-| test_logging.rs:178:23:178:46 | { ... } | test_logging.rs:178:23:178:46 | ...::must_use(...) | provenance | MaD:36 |
+| test_logging.rs:178:23:178:46 | MacroExpr | test_logging.rs:178:23:178:46 | ...::format(...) | provenance | MaD:48 |
+| test_logging.rs:178:23:178:46 | { ... } | test_logging.rs:178:23:178:46 | ...::must_use(...) | provenance | MaD:47 |
| test_logging.rs:178:39:178:46 | password | test_logging.rs:178:23:178:46 | MacroExpr | provenance | |
-| test_logging.rs:181:15:181:47 | MacroExpr | test_logging.rs:181:15:181:58 | ... .as_bytes(...) | provenance | MaD:35 |
+| test_logging.rs:181:15:181:47 | MacroExpr | test_logging.rs:181:15:181:58 | ... .as_bytes(...) | provenance | MaD:46 |
| test_logging.rs:181:15:181:47 | res | test_logging.rs:181:23:181:46 | { ... } | provenance | |
| test_logging.rs:181:15:181:58 | ... .as_bytes(...) | test_logging.rs:181:9:181:13 | write | provenance | MaD:7 Sink:MaD:7 |
| test_logging.rs:181:23:181:46 | ...::format(...) | test_logging.rs:181:15:181:47 | res | provenance | |
| test_logging.rs:181:23:181:46 | ...::must_use(...) | test_logging.rs:181:15:181:47 | MacroExpr | provenance | |
-| test_logging.rs:181:23:181:46 | MacroExpr | test_logging.rs:181:23:181:46 | ...::format(...) | provenance | MaD:37 |
-| test_logging.rs:181:23:181:46 | { ... } | test_logging.rs:181:23:181:46 | ...::must_use(...) | provenance | MaD:36 |
+| test_logging.rs:181:23:181:46 | MacroExpr | test_logging.rs:181:23:181:46 | ...::format(...) | provenance | MaD:48 |
+| test_logging.rs:181:23:181:46 | { ... } | test_logging.rs:181:23:181:46 | ...::must_use(...) | provenance | MaD:47 |
| test_logging.rs:181:39:181:46 | password | test_logging.rs:181:23:181:46 | MacroExpr | provenance | |
nodes
| test_logging.rs:42:5:42:36 | ...::log | semmle.label | ...::log |
From 117db8a9b2ac3f6c84464d81a647948031d49676 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 24 Jan 2025 17:19:33 +0000
Subject: [PATCH 20/21] Rust: Make the test runnable.
---
.../CWE-312/CleartextLogging.expected | 160 +++++++++---------
.../query-tests/security/CWE-312/options.yml | 1 +
.../security/CWE-312/test_logging.rs | 23 ++-
3 files changed, 96 insertions(+), 88 deletions(-)
diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
index 0e61f2898dd6..e4feee0fd55d 100644
--- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
+++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected
@@ -28,9 +28,9 @@
| test_logging.rs:100:5:100:19 | ...::log | test_logging.rs:99:38:99:45 | password | test_logging.rs:100:5:100:19 | ...::log | This operation writes $@ to a log file. | test_logging.rs:99:38:99:45 | password | password |
| test_logging.rs:118:5:118:42 | ...::log | test_logging.rs:118:28:118:41 | get_password(...) | test_logging.rs:118:5:118:42 | ...::log | This operation writes $@ to a log file. | test_logging.rs:118:28:118:41 | get_password(...) | get_password(...) |
| test_logging.rs:131:5:131:32 | ...::log | test_logging.rs:129:25:129:32 | password | test_logging.rs:131:5:131:32 | ...::log | This operation writes $@ to a log file. | test_logging.rs:129:25:129:32 | password | password |
-| test_logging.rs:152:5:152:36 | ...::_print | test_logging.rs:152:28:152:35 | password | test_logging.rs:152:5:152:36 | ...::_print | This operation writes $@ to a log file. | test_logging.rs:152:28:152:35 | password | password |
+| test_logging.rs:152:5:152:38 | ...::_print | test_logging.rs:152:30:152:37 | password | test_logging.rs:152:5:152:38 | ...::_print | This operation writes $@ to a log file. | test_logging.rs:152:30:152:37 | password | password |
| test_logging.rs:153:5:153:38 | ...::_print | test_logging.rs:153:30:153:37 | password | test_logging.rs:153:5:153:38 | ...::_print | This operation writes $@ to a log file. | test_logging.rs:153:30:153:37 | password | password |
-| test_logging.rs:154:5:154:37 | ...::_eprint | test_logging.rs:154:29:154:36 | password | test_logging.rs:154:5:154:37 | ...::_eprint | This operation writes $@ to a log file. | test_logging.rs:154:29:154:36 | password | password |
+| test_logging.rs:154:5:154:39 | ...::_eprint | test_logging.rs:154:31:154:38 | password | test_logging.rs:154:5:154:39 | ...::_eprint | This operation writes $@ to a log file. | test_logging.rs:154:31:154:38 | password | password |
| test_logging.rs:155:5:155:39 | ...::_eprint | test_logging.rs:155:31:155:38 | password | test_logging.rs:155:5:155:39 | ...::_eprint | This operation writes $@ to a log file. | test_logging.rs:155:31:155:38 | password | password |
| test_logging.rs:158:16:158:47 | ...::panic_fmt | test_logging.rs:158:39:158:46 | password | test_logging.rs:158:16:158:47 | ...::panic_fmt | This operation writes $@ to a log file. | test_logging.rs:158:39:158:46 | password | password |
| test_logging.rs:159:16:159:46 | ...::panic_fmt | test_logging.rs:159:38:159:45 | password | test_logging.rs:159:16:159:46 | ...::panic_fmt | This operation writes $@ to a log file. | test_logging.rs:159:38:159:45 | password | password |
@@ -43,10 +43,10 @@
| test_logging.rs:166:16:166:63 | ...::assert_failed | test_logging.rs:166:55:166:62 | password | test_logging.rs:166:16:166:63 | ...::assert_failed | This operation writes $@ to a log file. | test_logging.rs:166:55:166:62 | password | password |
| test_logging.rs:167:17:167:64 | ...::assert_failed | test_logging.rs:167:56:167:63 | password | test_logging.rs:167:17:167:64 | ...::assert_failed | This operation writes $@ to a log file. | test_logging.rs:167:56:167:63 | password | password |
| test_logging.rs:168:27:168:32 | expect | test_logging.rs:168:58:168:65 | password | test_logging.rs:168:27:168:32 | expect | This operation writes $@ to a log file. | test_logging.rs:168:58:168:65 | password | password |
-| test_logging.rs:174:30:174:34 | write | test_logging.rs:174:60:174:67 | password | test_logging.rs:174:30:174:34 | write | This operation writes $@ to a log file. | test_logging.rs:174:60:174:67 | password | password |
-| test_logging.rs:175:30:175:38 | write_all | test_logging.rs:175:64:175:71 | password | test_logging.rs:175:30:175:38 | write_all | This operation writes $@ to a log file. | test_logging.rs:175:64:175:71 | password | password |
-| test_logging.rs:178:9:178:13 | write | test_logging.rs:178:39:178:46 | password | test_logging.rs:178:9:178:13 | write | This operation writes $@ to a log file. | test_logging.rs:178:39:178:46 | password | password |
-| test_logging.rs:181:9:181:13 | write | test_logging.rs:181:39:181:46 | password | test_logging.rs:181:9:181:13 | write | This operation writes $@ to a log file. | test_logging.rs:181:39:181:46 | password | password |
+| test_logging.rs:174:30:174:34 | write | test_logging.rs:174:62:174:69 | password | test_logging.rs:174:30:174:34 | write | This operation writes $@ to a log file. | test_logging.rs:174:62:174:69 | password | password |
+| test_logging.rs:175:30:175:38 | write_all | test_logging.rs:175:66:175:73 | password | test_logging.rs:175:30:175:38 | write_all | This operation writes $@ to a log file. | test_logging.rs:175:66:175:73 | password | password |
+| test_logging.rs:178:9:178:13 | write | test_logging.rs:178:41:178:48 | password | test_logging.rs:178:9:178:13 | write | This operation writes $@ to a log file. | test_logging.rs:178:41:178:48 | password | password |
+| test_logging.rs:181:9:181:13 | write | test_logging.rs:181:41:181:48 | password | test_logging.rs:181:9:181:13 | write | This operation writes $@ to a log file. | test_logging.rs:181:41:181:48 | password | password |
edges
| test_logging.rs:42:12:42:35 | MacroExpr | test_logging.rs:42:5:42:36 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:42:28:42:35 | password | test_logging.rs:42:12:42:35 | MacroExpr | provenance | |
@@ -148,12 +148,12 @@ edges
| test_logging.rs:131:12:131:31 | MacroExpr | test_logging.rs:131:5:131:32 | ...::log | provenance | MaD:0 Sink:MaD:0 |
| test_logging.rs:131:28:131:29 | t1 [tuple.1] | test_logging.rs:131:28:131:31 | t1.1 | provenance | |
| test_logging.rs:131:28:131:31 | t1.1 | test_logging.rs:131:12:131:31 | MacroExpr | provenance | |
-| test_logging.rs:152:12:152:35 | MacroExpr | test_logging.rs:152:5:152:36 | ...::_print | provenance | MaD:3 Sink:MaD:3 |
-| test_logging.rs:152:28:152:35 | password | test_logging.rs:152:12:152:35 | MacroExpr | provenance | |
+| test_logging.rs:152:12:152:37 | MacroExpr | test_logging.rs:152:5:152:38 | ...::_print | provenance | MaD:3 Sink:MaD:3 |
+| test_logging.rs:152:30:152:37 | password | test_logging.rs:152:12:152:37 | MacroExpr | provenance | |
| test_logging.rs:153:14:153:37 | MacroExpr | test_logging.rs:153:5:153:38 | ...::_print | provenance | MaD:3 Sink:MaD:3 |
| test_logging.rs:153:30:153:37 | password | test_logging.rs:153:14:153:37 | MacroExpr | provenance | |
-| test_logging.rs:154:13:154:36 | MacroExpr | test_logging.rs:154:5:154:37 | ...::_eprint | provenance | MaD:4 Sink:MaD:4 |
-| test_logging.rs:154:29:154:36 | password | test_logging.rs:154:13:154:36 | MacroExpr | provenance | |
+| test_logging.rs:154:13:154:38 | MacroExpr | test_logging.rs:154:5:154:39 | ...::_eprint | provenance | MaD:4 Sink:MaD:4 |
+| test_logging.rs:154:31:154:38 | password | test_logging.rs:154:13:154:38 | MacroExpr | provenance | |
| test_logging.rs:155:15:155:38 | MacroExpr | test_logging.rs:155:5:155:39 | ...::_eprint | provenance | MaD:4 Sink:MaD:4 |
| test_logging.rs:155:31:155:38 | password | test_logging.rs:155:15:155:38 | MacroExpr | provenance | |
| test_logging.rs:158:23:158:46 | MacroExpr | test_logging.rs:158:16:158:47 | ...::panic_fmt | provenance | MaD:9 Sink:MaD:9 |
@@ -188,38 +188,38 @@ edges
| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:48 |
| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:47 |
| test_logging.rs:168:58:168:65 | password | test_logging.rs:168:42:168:65 | MacroExpr | provenance | |
-| test_logging.rs:174:36:174:68 | MacroExpr | test_logging.rs:174:36:174:79 | ... .as_bytes(...) | provenance | MaD:46 |
-| test_logging.rs:174:36:174:68 | res | test_logging.rs:174:44:174:67 | { ... } | provenance | |
-| test_logging.rs:174:36:174:79 | ... .as_bytes(...) | test_logging.rs:174:30:174:34 | write | provenance | MaD:5 Sink:MaD:5 |
-| test_logging.rs:174:44:174:67 | ...::format(...) | test_logging.rs:174:36:174:68 | res | provenance | |
-| test_logging.rs:174:44:174:67 | ...::must_use(...) | test_logging.rs:174:36:174:68 | MacroExpr | provenance | |
-| test_logging.rs:174:44:174:67 | MacroExpr | test_logging.rs:174:44:174:67 | ...::format(...) | provenance | MaD:48 |
-| test_logging.rs:174:44:174:67 | { ... } | test_logging.rs:174:44:174:67 | ...::must_use(...) | provenance | MaD:47 |
-| test_logging.rs:174:60:174:67 | password | test_logging.rs:174:44:174:67 | MacroExpr | provenance | |
-| test_logging.rs:175:40:175:72 | MacroExpr | test_logging.rs:175:40:175:83 | ... .as_bytes(...) | provenance | MaD:46 |
-| test_logging.rs:175:40:175:72 | res | test_logging.rs:175:48:175:71 | { ... } | provenance | |
-| test_logging.rs:175:40:175:83 | ... .as_bytes(...) | test_logging.rs:175:30:175:38 | write_all | provenance | MaD:6 Sink:MaD:6 |
-| test_logging.rs:175:48:175:71 | ...::format(...) | test_logging.rs:175:40:175:72 | res | provenance | |
-| test_logging.rs:175:48:175:71 | ...::must_use(...) | test_logging.rs:175:40:175:72 | MacroExpr | provenance | |
-| test_logging.rs:175:48:175:71 | MacroExpr | test_logging.rs:175:48:175:71 | ...::format(...) | provenance | MaD:48 |
-| test_logging.rs:175:48:175:71 | { ... } | test_logging.rs:175:48:175:71 | ...::must_use(...) | provenance | MaD:47 |
-| test_logging.rs:175:64:175:71 | password | test_logging.rs:175:48:175:71 | MacroExpr | provenance | |
-| test_logging.rs:178:15:178:47 | MacroExpr | test_logging.rs:178:15:178:58 | ... .as_bytes(...) | provenance | MaD:46 |
-| test_logging.rs:178:15:178:47 | res | test_logging.rs:178:23:178:46 | { ... } | provenance | |
-| test_logging.rs:178:15:178:58 | ... .as_bytes(...) | test_logging.rs:178:9:178:13 | write | provenance | MaD:5 Sink:MaD:5 |
-| test_logging.rs:178:23:178:46 | ...::format(...) | test_logging.rs:178:15:178:47 | res | provenance | |
-| test_logging.rs:178:23:178:46 | ...::must_use(...) | test_logging.rs:178:15:178:47 | MacroExpr | provenance | |
-| test_logging.rs:178:23:178:46 | MacroExpr | test_logging.rs:178:23:178:46 | ...::format(...) | provenance | MaD:48 |
-| test_logging.rs:178:23:178:46 | { ... } | test_logging.rs:178:23:178:46 | ...::must_use(...) | provenance | MaD:47 |
-| test_logging.rs:178:39:178:46 | password | test_logging.rs:178:23:178:46 | MacroExpr | provenance | |
-| test_logging.rs:181:15:181:47 | MacroExpr | test_logging.rs:181:15:181:58 | ... .as_bytes(...) | provenance | MaD:46 |
-| test_logging.rs:181:15:181:47 | res | test_logging.rs:181:23:181:46 | { ... } | provenance | |
-| test_logging.rs:181:15:181:58 | ... .as_bytes(...) | test_logging.rs:181:9:181:13 | write | provenance | MaD:7 Sink:MaD:7 |
-| test_logging.rs:181:23:181:46 | ...::format(...) | test_logging.rs:181:15:181:47 | res | provenance | |
-| test_logging.rs:181:23:181:46 | ...::must_use(...) | test_logging.rs:181:15:181:47 | MacroExpr | provenance | |
-| test_logging.rs:181:23:181:46 | MacroExpr | test_logging.rs:181:23:181:46 | ...::format(...) | provenance | MaD:48 |
-| test_logging.rs:181:23:181:46 | { ... } | test_logging.rs:181:23:181:46 | ...::must_use(...) | provenance | MaD:47 |
-| test_logging.rs:181:39:181:46 | password | test_logging.rs:181:23:181:46 | MacroExpr | provenance | |
+| test_logging.rs:174:36:174:70 | MacroExpr | test_logging.rs:174:36:174:81 | ... .as_bytes(...) | provenance | MaD:46 |
+| test_logging.rs:174:36:174:70 | res | test_logging.rs:174:44:174:69 | { ... } | provenance | |
+| test_logging.rs:174:36:174:81 | ... .as_bytes(...) | test_logging.rs:174:30:174:34 | write | provenance | MaD:5 Sink:MaD:5 |
+| test_logging.rs:174:44:174:69 | ...::format(...) | test_logging.rs:174:36:174:70 | res | provenance | |
+| test_logging.rs:174:44:174:69 | ...::must_use(...) | test_logging.rs:174:36:174:70 | MacroExpr | provenance | |
+| test_logging.rs:174:44:174:69 | MacroExpr | test_logging.rs:174:44:174:69 | ...::format(...) | provenance | MaD:48 |
+| test_logging.rs:174:44:174:69 | { ... } | test_logging.rs:174:44:174:69 | ...::must_use(...) | provenance | MaD:47 |
+| test_logging.rs:174:62:174:69 | password | test_logging.rs:174:44:174:69 | MacroExpr | provenance | |
+| test_logging.rs:175:40:175:74 | MacroExpr | test_logging.rs:175:40:175:85 | ... .as_bytes(...) | provenance | MaD:46 |
+| test_logging.rs:175:40:175:74 | res | test_logging.rs:175:48:175:73 | { ... } | provenance | |
+| test_logging.rs:175:40:175:85 | ... .as_bytes(...) | test_logging.rs:175:30:175:38 | write_all | provenance | MaD:6 Sink:MaD:6 |
+| test_logging.rs:175:48:175:73 | ...::format(...) | test_logging.rs:175:40:175:74 | res | provenance | |
+| test_logging.rs:175:48:175:73 | ...::must_use(...) | test_logging.rs:175:40:175:74 | MacroExpr | provenance | |
+| test_logging.rs:175:48:175:73 | MacroExpr | test_logging.rs:175:48:175:73 | ...::format(...) | provenance | MaD:48 |
+| test_logging.rs:175:48:175:73 | { ... } | test_logging.rs:175:48:175:73 | ...::must_use(...) | provenance | MaD:47 |
+| test_logging.rs:175:66:175:73 | password | test_logging.rs:175:48:175:73 | MacroExpr | provenance | |
+| test_logging.rs:178:15:178:49 | MacroExpr | test_logging.rs:178:15:178:60 | ... .as_bytes(...) | provenance | MaD:46 |
+| test_logging.rs:178:15:178:49 | res | test_logging.rs:178:23:178:48 | { ... } | provenance | |
+| test_logging.rs:178:15:178:60 | ... .as_bytes(...) | test_logging.rs:178:9:178:13 | write | provenance | MaD:5 Sink:MaD:5 |
+| test_logging.rs:178:23:178:48 | ...::format(...) | test_logging.rs:178:15:178:49 | res | provenance | |
+| test_logging.rs:178:23:178:48 | ...::must_use(...) | test_logging.rs:178:15:178:49 | MacroExpr | provenance | |
+| test_logging.rs:178:23:178:48 | MacroExpr | test_logging.rs:178:23:178:48 | ...::format(...) | provenance | MaD:48 |
+| test_logging.rs:178:23:178:48 | { ... } | test_logging.rs:178:23:178:48 | ...::must_use(...) | provenance | MaD:47 |
+| test_logging.rs:178:41:178:48 | password | test_logging.rs:178:23:178:48 | MacroExpr | provenance | |
+| test_logging.rs:181:15:181:49 | MacroExpr | test_logging.rs:181:15:181:60 | ... .as_bytes(...) | provenance | MaD:46 |
+| test_logging.rs:181:15:181:49 | res | test_logging.rs:181:23:181:48 | { ... } | provenance | |
+| test_logging.rs:181:15:181:60 | ... .as_bytes(...) | test_logging.rs:181:9:181:13 | write | provenance | MaD:7 Sink:MaD:7 |
+| test_logging.rs:181:23:181:48 | ...::format(...) | test_logging.rs:181:15:181:49 | res | provenance | |
+| test_logging.rs:181:23:181:48 | ...::must_use(...) | test_logging.rs:181:15:181:49 | MacroExpr | provenance | |
+| test_logging.rs:181:23:181:48 | MacroExpr | test_logging.rs:181:23:181:48 | ...::format(...) | provenance | MaD:48 |
+| test_logging.rs:181:23:181:48 | { ... } | test_logging.rs:181:23:181:48 | ...::must_use(...) | provenance | MaD:47 |
+| test_logging.rs:181:41:181:48 | password | test_logging.rs:181:23:181:48 | MacroExpr | provenance | |
nodes
| test_logging.rs:42:5:42:36 | ...::log | semmle.label | ...::log |
| test_logging.rs:42:12:42:35 | MacroExpr | semmle.label | MacroExpr |
@@ -342,15 +342,15 @@ nodes
| test_logging.rs:131:12:131:31 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:131:28:131:29 | t1 [tuple.1] | semmle.label | t1 [tuple.1] |
| test_logging.rs:131:28:131:31 | t1.1 | semmle.label | t1.1 |
-| test_logging.rs:152:5:152:36 | ...::_print | semmle.label | ...::_print |
-| test_logging.rs:152:12:152:35 | MacroExpr | semmle.label | MacroExpr |
-| test_logging.rs:152:28:152:35 | password | semmle.label | password |
+| test_logging.rs:152:5:152:38 | ...::_print | semmle.label | ...::_print |
+| test_logging.rs:152:12:152:37 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:152:30:152:37 | password | semmle.label | password |
| test_logging.rs:153:5:153:38 | ...::_print | semmle.label | ...::_print |
| test_logging.rs:153:14:153:37 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:153:30:153:37 | password | semmle.label | password |
-| test_logging.rs:154:5:154:37 | ...::_eprint | semmle.label | ...::_eprint |
-| test_logging.rs:154:13:154:36 | MacroExpr | semmle.label | MacroExpr |
-| test_logging.rs:154:29:154:36 | password | semmle.label | password |
+| test_logging.rs:154:5:154:39 | ...::_eprint | semmle.label | ...::_eprint |
+| test_logging.rs:154:13:154:38 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:154:31:154:38 | password | semmle.label | password |
| test_logging.rs:155:5:155:39 | ...::_eprint | semmle.label | ...::_eprint |
| test_logging.rs:155:15:155:38 | MacroExpr | semmle.label | MacroExpr |
| test_logging.rs:155:31:155:38 | password | semmle.label | password |
@@ -398,39 +398,39 @@ nodes
| test_logging.rs:168:42:168:65 | { ... } | semmle.label | { ... } |
| test_logging.rs:168:58:168:65 | password | semmle.label | password |
| test_logging.rs:174:30:174:34 | write | semmle.label | write |
-| test_logging.rs:174:36:174:68 | MacroExpr | semmle.label | MacroExpr |
-| test_logging.rs:174:36:174:68 | res | semmle.label | res |
-| test_logging.rs:174:36:174:79 | ... .as_bytes(...) | semmle.label | ... .as_bytes(...) |
-| test_logging.rs:174:44:174:67 | ...::format(...) | semmle.label | ...::format(...) |
-| test_logging.rs:174:44:174:67 | ...::must_use(...) | semmle.label | ...::must_use(...) |
-| test_logging.rs:174:44:174:67 | MacroExpr | semmle.label | MacroExpr |
-| test_logging.rs:174:44:174:67 | { ... } | semmle.label | { ... } |
-| test_logging.rs:174:60:174:67 | password | semmle.label | password |
+| test_logging.rs:174:36:174:70 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:174:36:174:70 | res | semmle.label | res |
+| test_logging.rs:174:36:174:81 | ... .as_bytes(...) | semmle.label | ... .as_bytes(...) |
+| test_logging.rs:174:44:174:69 | ...::format(...) | semmle.label | ...::format(...) |
+| test_logging.rs:174:44:174:69 | ...::must_use(...) | semmle.label | ...::must_use(...) |
+| test_logging.rs:174:44:174:69 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:174:44:174:69 | { ... } | semmle.label | { ... } |
+| test_logging.rs:174:62:174:69 | password | semmle.label | password |
| test_logging.rs:175:30:175:38 | write_all | semmle.label | write_all |
-| test_logging.rs:175:40:175:72 | MacroExpr | semmle.label | MacroExpr |
-| test_logging.rs:175:40:175:72 | res | semmle.label | res |
-| test_logging.rs:175:40:175:83 | ... .as_bytes(...) | semmle.label | ... .as_bytes(...) |
-| test_logging.rs:175:48:175:71 | ...::format(...) | semmle.label | ...::format(...) |
-| test_logging.rs:175:48:175:71 | ...::must_use(...) | semmle.label | ...::must_use(...) |
-| test_logging.rs:175:48:175:71 | MacroExpr | semmle.label | MacroExpr |
-| test_logging.rs:175:48:175:71 | { ... } | semmle.label | { ... } |
-| test_logging.rs:175:64:175:71 | password | semmle.label | password |
+| test_logging.rs:175:40:175:74 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:175:40:175:74 | res | semmle.label | res |
+| test_logging.rs:175:40:175:85 | ... .as_bytes(...) | semmle.label | ... .as_bytes(...) |
+| test_logging.rs:175:48:175:73 | ...::format(...) | semmle.label | ...::format(...) |
+| test_logging.rs:175:48:175:73 | ...::must_use(...) | semmle.label | ...::must_use(...) |
+| test_logging.rs:175:48:175:73 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:175:48:175:73 | { ... } | semmle.label | { ... } |
+| test_logging.rs:175:66:175:73 | password | semmle.label | password |
| test_logging.rs:178:9:178:13 | write | semmle.label | write |
-| test_logging.rs:178:15:178:47 | MacroExpr | semmle.label | MacroExpr |
-| test_logging.rs:178:15:178:47 | res | semmle.label | res |
-| test_logging.rs:178:15:178:58 | ... .as_bytes(...) | semmle.label | ... .as_bytes(...) |
-| test_logging.rs:178:23:178:46 | ...::format(...) | semmle.label | ...::format(...) |
-| test_logging.rs:178:23:178:46 | ...::must_use(...) | semmle.label | ...::must_use(...) |
-| test_logging.rs:178:23:178:46 | MacroExpr | semmle.label | MacroExpr |
-| test_logging.rs:178:23:178:46 | { ... } | semmle.label | { ... } |
-| test_logging.rs:178:39:178:46 | password | semmle.label | password |
+| test_logging.rs:178:15:178:49 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:178:15:178:49 | res | semmle.label | res |
+| test_logging.rs:178:15:178:60 | ... .as_bytes(...) | semmle.label | ... .as_bytes(...) |
+| test_logging.rs:178:23:178:48 | ...::format(...) | semmle.label | ...::format(...) |
+| test_logging.rs:178:23:178:48 | ...::must_use(...) | semmle.label | ...::must_use(...) |
+| test_logging.rs:178:23:178:48 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:178:23:178:48 | { ... } | semmle.label | { ... } |
+| test_logging.rs:178:41:178:48 | password | semmle.label | password |
| test_logging.rs:181:9:181:13 | write | semmle.label | write |
-| test_logging.rs:181:15:181:47 | MacroExpr | semmle.label | MacroExpr |
-| test_logging.rs:181:15:181:47 | res | semmle.label | res |
-| test_logging.rs:181:15:181:58 | ... .as_bytes(...) | semmle.label | ... .as_bytes(...) |
-| test_logging.rs:181:23:181:46 | ...::format(...) | semmle.label | ...::format(...) |
-| test_logging.rs:181:23:181:46 | ...::must_use(...) | semmle.label | ...::must_use(...) |
-| test_logging.rs:181:23:181:46 | MacroExpr | semmle.label | MacroExpr |
-| test_logging.rs:181:23:181:46 | { ... } | semmle.label | { ... } |
-| test_logging.rs:181:39:181:46 | password | semmle.label | password |
+| test_logging.rs:181:15:181:49 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:181:15:181:49 | res | semmle.label | res |
+| test_logging.rs:181:15:181:60 | ... .as_bytes(...) | semmle.label | ... .as_bytes(...) |
+| test_logging.rs:181:23:181:48 | ...::format(...) | semmle.label | ...::format(...) |
+| test_logging.rs:181:23:181:48 | ...::must_use(...) | semmle.label | ...::must_use(...) |
+| test_logging.rs:181:23:181:48 | MacroExpr | semmle.label | MacroExpr |
+| test_logging.rs:181:23:181:48 | { ... } | semmle.label | { ... } |
+| test_logging.rs:181:41:181:48 | password | semmle.label | password |
subpaths
diff --git a/rust/ql/test/query-tests/security/CWE-312/options.yml b/rust/ql/test/query-tests/security/CWE-312/options.yml
index 26180d858d8e..439af840b902 100644
--- a/rust/ql/test/query-tests/security/CWE-312/options.yml
+++ b/rust/ql/test/query-tests/security/CWE-312/options.yml
@@ -1,3 +1,4 @@
qltest_cargo_check: true
qltest_dependencies:
- log = { version = "0.4.25", features = ["kv"] }
+ - simple_logger = { version = "5.0.0" }
diff --git a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
index 15ab6c9179bd..a850e38dc09f 100644
--- a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
+++ b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
@@ -149,9 +149,9 @@ fn test_log(harmless: String, password: String, encrypted_password: String) {
}
fn test_std(password: String, i: i32, opt_i: Option) {
- print!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
+ print!("message = {}\n", password); // $ Source Alert[rust/cleartext-logging]
println!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
- eprint!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
+ eprint!("message = {}\n", password); // $ Source Alert[rust/cleartext-logging]
eprintln!("message = {}", password); // $ Source Alert[rust/cleartext-logging]
match i {
@@ -169,14 +169,21 @@ fn test_std(password: String, i: i32, opt_i: Option) {
_ => {}
}
- std::io::stdout().lock().write_fmt(format_args!("message = {}", password)); // $ MISSING: Alert[rust/cleartext-logging]
- std::io::stderr().lock().write_fmt(format_args!("message = {}", password)); // $ MISSING: Alert[rust/cleartext-logging]
- std::io::stdout().lock().write(format!("message = {}", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
- std::io::stdout().lock().write_all(format!("message = {}", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
+ std::io::stdout().lock().write_fmt(format_args!("message = {}\n", password)); // $ MISSING: Alert[rust/cleartext-logging]
+ std::io::stderr().lock().write_fmt(format_args!("message = {}\n", password)); // $ MISSING: Alert[rust/cleartext-logging]
+ std::io::stdout().lock().write(format!("message = {}\n", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
+ std::io::stdout().lock().write_all(format!("message = {}\n", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
let mut out = std::io::stdout().lock();
- out.write(format!("message = {}", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
+ out.write(format!("message = {}\n", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
let mut err = std::io::stderr().lock();
- err.write(format!("message = {}", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
+ err.write(format!("message = {}\n", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
+}
+
+fn main() {
+ simple_logger::SimpleLogger::new().init().unwrap();
+
+ test_log("harmless".to_string(), "123456".to_string(), "[encrypted]".to_string());
+ test_std("123456".to_string(), 0, None);
}
From 0a3d44c44e50603e3fd33237b4b3bfb3075e1e27 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 24 Jan 2025 17:30:06 +0000
Subject: [PATCH 21/21] Rust: Re-apply suggested changes (I accidentally
force-pushed them away).
---
rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp | 4 ++--
rust/ql/test/query-tests/security/CWE-312/test_logging.rs | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp b/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp
index b2e495f0818f..9e30bbf180de 100644
--- a/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp
+++ b/rust/ql/src/queries/security/CWE-312/CleartextLogging.qhelp
@@ -5,7 +5,7 @@
-Sensitive user data and system information that is logged could be seen by an attacker when it is
+Sensitive user data and system information that is logged could be exposed to an attacker when it is
displayed. Also, external processes often store the standard output and standard error streams of
an application, which will include logged sensitive information.
@@ -23,7 +23,7 @@ The following example code logs user credentials (in this case, their password)
-Instead, you should encrypt the credentials, or better still omit them entirely:
+Instead, you should encrypt the credentials, or better still, omit them entirely:
diff --git a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
index a850e38dc09f..ab8013689906 100644
--- a/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
+++ b/rust/ql/test/query-tests/security/CWE-312/test_logging.rs
@@ -6,7 +6,7 @@ use std::fmt::Write as _;
// --- tests ---
fn get_password() -> String {
- return "123456".to_string();
+ "123456".to_string()
}
fn use_password(password: &String) {