Merge pull request #18582 from geoffw0/logging

Rust: Query for cleartext logging of sensitive information
This commit is contained in:
Geoffrey White
2025-01-27 10:37:17 +00:00
committed by GitHub
20 changed files with 830 additions and 30 deletions

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -776,7 +776,7 @@ final class ElementContent extends Content, TElementContent {
* 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) }

View File

@@ -0,0 +1,17 @@
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"] # 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", "<crate::io::stdio::StdoutLock as crate::io::Write>::write", "Argument[0]", "log-injection", "manual"]
- ["lang:std", "<crate::io::stdio::StdoutLock as crate::io::Write>::write_all", "Argument[0]", "log-injection", "manual"]
- ["lang:std", "<crate::io::stdio::StderrLock as crate::io::Write>::write", "Argument[0]", "log-injection", "manual"]
- ["lang:std", "<crate::io::stdio::StderrLock as crate::io::Write>::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", "<crate::option::Option>::expect", "Argument[0]", "log-injection", "manual"]

View File

@@ -13,6 +13,7 @@ extensions:
- ["lang:core", "<crate::result::Result>::unwrap_or", "Argument[0]", "ReturnValue", "value", "manual"]
# String
- ["lang:alloc", "<crate::string::String>::as_str", "Argument[self]", "ReturnValue", "taint", "manual"]
- ["lang:alloc", "<crate::string::String>::as_bytes", "Argument[self]", "ReturnValue", "taint", "manual"]
# Hint
- ["lang:core", "crate::hint::must_use", "Argument[0]", "ReturnValue", "value", "manual"]
# Fmt

View File

@@ -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%")) }
}
}

View File

@@ -0,0 +1,38 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
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.
</p>
</overview>
<recommendation>
<p>
Do not log sensitive data. If it is necessary to log sensitive data, encrypt it before logging.
</p>
</recommendation>
<example>
<p>
The following example code logs user credentials (in this case, their password) in plaintext:
</p>
<sample src="CleartextLoggingBad.rs"/>
<p>
Instead, you should encrypt the credentials, or better still, omit them entirely:
</p>
<sample src="CleartextLoggingGood.rs"/>
</example>
<references>
<li>M. Dowd, J. McDonald and J. Schuhm, <i>The Art of Software Security Assessment</i>, 1st Edition, Chapter 2 - 'Common Vulnerabilities of Encryption', p. 43. Addison Wesley, 2006.</li>
<li>M. Howard and D. LeBlanc, <i>Writing Secure Code</i>, 2nd Edition, Chapter 9 - 'Protecting Secret Data', p. 299. Microsoft, 2002.</li>
<li>OWASP: <a href="https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html#data-to-exclude">Logging Cheat Sheet - Data to exclude</a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,58 @@
/**
* @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
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.
*/
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)
}
predicate isAdditionalFlowStep(Node node1, Node node2) {
// flow from `a` to `&a`
node2.asExpr().getExpr().(RefExpr).getExpr() = node1.asExpr().getExpr()
}
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<CleartextLoggingConfig>;
import CleartextLoggingFlow::PathGraph
from CleartextLoggingFlow::PathNode source, CleartextLoggingFlow::PathNode sink
where CleartextLoggingFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "This operation writes $@ to a log file.", source,
source.getNode().toString()

View File

@@ -0,0 +1,2 @@
let password = "P@ssw0rd";
info!("User password changed to {password}");

View File

@@ -0,0 +1,2 @@
let password = "P@ssw0rd";
info!("User password changed");

View File

@@ -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"
}
/**

View File

@@ -1,11 +1,11 @@
localStep
| file://:0:0:0:0 | [summary param] 0 in lang:core::_::<crate::option::Option>::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::option::Option>::unwrap_or | MaD:2 |
| file://:0:0:0:0 | [summary param] 0 in lang:core::_::<crate::result::Result>::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::result::Result>::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::_::<crate::option::Option>::unwrap | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::option::Option>::unwrap | MaD:1 |
| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::option::Option::Some(0)] in lang:core::_::<crate::option::Option>::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::option::Option>::unwrap_or | MaD:3 |
| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::result::Result::Ok(0)] in lang:core::_::<crate::result::Result>::unwrap | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::result::Result>::unwrap | MaD:4 |
| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::result::Result::Ok(0)] in lang:core::_::<crate::result::Result>::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::result::Result>::unwrap_or | MaD:6 |
| file://:0:0:0:0 | [summary param] 0 in lang:core::_::<crate::option::Option>::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::option::Option>::unwrap_or | MaD:3 |
| file://:0:0:0:0 | [summary param] 0 in lang:core::_::<crate::result::Result>::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::result::Result>::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::_::<crate::option::Option>::unwrap | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::option::Option>::unwrap | MaD:2 |
| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::option::Option::Some(0)] in lang:core::_::<crate::option::Option>::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::option::Option>::unwrap_or | MaD:4 |
| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::result::Result::Ok(0)] in lang:core::_::<crate::result::Result>::unwrap | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::result::Result>::unwrap | MaD:5 |
| file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::result::Result::Ok(0)] in lang:core::_::<crate::result::Result>::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::result::Result>::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; <crate::option::Option>::unwrap; Argument[self].Variant[crate::option::Option::Some(0)]; ReturnValue; value |
| 2 | Summary: lang:core; <crate::option::Option>::unwrap_or; Argument[0]; ReturnValue; value |
| 3 | Summary: lang:core; <crate::option::Option>::unwrap_or; Argument[self].Variant[crate::option::Option::Some(0)]; ReturnValue; value |
| 4 | Summary: lang:core; <crate::result::Result>::unwrap; Argument[self].Variant[crate::result::Result::Ok(0)]; ReturnValue; value |
| 5 | Summary: lang:core; <crate::result::Result>::unwrap_or; Argument[0]; ReturnValue; value |
| 6 | Summary: lang:core; <crate::result::Result>::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; <crate::option::Option>::unwrap; Argument[self].Variant[crate::option::Option::Some(0)]; ReturnValue; value |
| 3 | Summary: lang:core; <crate::option::Option>::unwrap_or; Argument[0]; ReturnValue; value |
| 4 | Summary: lang:core; <crate::option::Option>::unwrap_or; Argument[self].Variant[crate::option::Option::Some(0)]; ReturnValue; value |
| 5 | Summary: lang:core; <crate::result::Result>::unwrap; Argument[self].Variant[crate::result::Result::Ok(0)]; ReturnValue; value |
| 6 | Summary: lang:core; <crate::result::Result>::unwrap_or; Argument[0]; ReturnValue; value |
| 7 | Summary: lang:core; <crate::result::Result>::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::_::<crate::blocking::response::Response>::text | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::blocking::response::Response>::text |
| main.rs:94:14:94:22 | source(...) | tuple.0 | main.rs:94:13:94:26 | TupleExpr |

View File

@@ -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::_::<crate::string::String>::as_str | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::<crate::string::String>::as_str | MaD:1 |
| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::blocking::response::Response>::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::blocking::response::Response>::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::_::<crate::string::String>::as_bytes | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::<crate::string::String>::as_bytes | MaD:1 |
| file://:0:0:0:0 | [summary param] self in lang:alloc::_::<crate::string::String>::as_str | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::<crate::string::String>::as_str | MaD:2 |
| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::blocking::response::Response>::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::blocking::response::Response>::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; <crate::string::String>::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; <crate::blocking::response::Response>::text; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint |
| 1 | Summary: lang:alloc; <crate::string::String>::as_bytes; Argument[self]; ReturnValue; taint |
| 2 | Summary: lang:alloc; <crate::string::String>::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; <crate::blocking::response::Response>::text; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint |

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -0,0 +1,436 @@
#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 $@ 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: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: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 |
| 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: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 | |
| 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: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 | |
| 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 | &... [&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 | |
| 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 | &... [&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 | |
| 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 | &... [&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 | |
| 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: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 |
| 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: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: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 |
| 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: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: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: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: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: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: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: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: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: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: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: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: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 |
| 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: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 |
| 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 | &... [&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 |
| 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 | &... [&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 |
| 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: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(...) |
| 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: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: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 |
| 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: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 |
| 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 |
| test_logging.rs:174:30:174:34 | write | semmle.label | write |
| 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: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: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: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

View File

@@ -0,0 +1,3 @@
query: queries/security/CWE-312/CleartextLogging.ql
postprocess:
- utils/test/InlineExpectationsTestQuery.ql

View File

@@ -0,0 +1,4 @@
qltest_cargo_check: true
qltest_dependencies:
- log = { version = "0.4.25", features = ["kv"] }
- simple_logger = { version = "5.0.0" }

View File

@@ -0,0 +1,189 @@
use log::{debug, error, info, trace, warn, log, Level};
use std::io::Write as _;
use std::fmt::Write as _;
// --- tests ---
fn get_password() -> String {
"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); // $ 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); // $ Source Alert[rust/cleartext-logging]
debug!("message = {}", encrypted_password);
debug!("message = {} {}", harmless, password); // $ Source Alert[rust/cleartext-logging]
debug!("message = {harmless}");
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); // $ Source 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); // $ 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"); // $ 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]
let value1 = 1;
error!(value1; "message = {}", harmless);
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"); // $ Source 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]
error!(value2:?; "message"); // $ MISSING: Alert[rust/cleartext-logging]
// pre-formatted
let m1 = &password; // $ Source=m1
info!("message = {}", m1); // $ Alert[rust/cleartext-logging]=m1
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
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()); // $ Source 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); // $ Source=t1
trace!("message = {}", t1.0);
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
// 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
}
fn test_std(password: String, i: i32, opt_i: Option<i32>) {
print!("message = {}\n", password); // $ Source Alert[rust/cleartext-logging]
println!("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 {
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); } // $ 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); } // $ 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]
_ => {}
}
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 = {}\n", password).as_bytes()); // $ Source Alert[rust/cleartext-logging]
let mut err = std::io::stderr().lock();
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);
}