From aaa3b1bcb45195c3111c4815deec4c035114488c Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 31 Oct 2025 16:20:52 +0000 Subject: [PATCH] Rust: Add a couple of new test cases. --- .../security/CWE-020/RegexInjection.expected | 36 ++++- .../CWE-020/RegexInjectionSink.expected | 1 + .../test/query-tests/security/CWE-020/main.rs | 12 +- .../security/CWE-117/LogInjection.expected | 129 ++++++++++-------- .../test/query-tests/security/CWE-117/main.rs | 6 +- 5 files changed, 119 insertions(+), 65 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-020/RegexInjection.expected b/rust/ql/test/query-tests/security/CWE-020/RegexInjection.expected index 2814af2b5ed..7627221edb1 100644 --- a/rust/ql/test/query-tests/security/CWE-020/RegexInjection.expected +++ b/rust/ql/test/query-tests/security/CWE-020/RegexInjection.expected @@ -1,5 +1,6 @@ #select | main.rs:6:25:6:30 | ®ex | main.rs:4:20:4:32 | ...::var | main.rs:6:25:6:30 | ®ex | This regular expression is constructed from a $@. | main.rs:4:20:4:32 | ...::var | user-provided value | +| main.rs:21:25:21:30 | ®ex | main.rs:19:23:19:35 | ...::var | main.rs:21:25:21:30 | ®ex | This regular expression is constructed from a $@. | main.rs:19:23:19:35 | ...::var | user-provided value | edges | main.rs:4:9:4:16 | username | main.rs:5:25:5:44 | MacroExpr | provenance | | | main.rs:4:20:4:32 | ...::var | main.rs:4:20:4:40 | ...::var(...) [Ok] | provenance | Src:MaD:1 | @@ -8,14 +9,28 @@ edges | main.rs:5:9:5:13 | regex | main.rs:6:26:6:30 | regex | provenance | | | main.rs:5:25:5:44 | ...::format(...) | main.rs:5:25:5:44 | { ... } | provenance | | | main.rs:5:25:5:44 | ...::must_use(...) | main.rs:5:9:5:13 | regex | provenance | | -| main.rs:5:25:5:44 | MacroExpr | main.rs:5:25:5:44 | ...::format(...) | provenance | MaD:3 | -| main.rs:5:25:5:44 | { ... } | main.rs:5:25:5:44 | ...::must_use(...) | provenance | MaD:4 | +| main.rs:5:25:5:44 | MacroExpr | main.rs:5:25:5:44 | ...::format(...) | provenance | MaD:4 | +| main.rs:5:25:5:44 | { ... } | main.rs:5:25:5:44 | ...::must_use(...) | provenance | MaD:5 | | main.rs:6:26:6:30 | regex | main.rs:6:25:6:30 | ®ex | provenance | | +| main.rs:19:9:19:19 | user_number | main.rs:20:25:20:47 | MacroExpr | provenance | | +| main.rs:19:23:19:35 | ...::var | main.rs:19:23:19:43 | ...::var(...) [Ok] | provenance | Src:MaD:1 | +| main.rs:19:23:19:43 | ...::var(...) [Ok] | main.rs:19:23:19:70 | ... .unwrap_or(...) | provenance | MaD:2 | +| main.rs:19:23:19:70 | ... .unwrap_or(...) | main.rs:19:23:19:85 | ... .parse() [Ok] | provenance | MaD:3 | +| main.rs:19:23:19:70 | ... .unwrap_or(...) | main.rs:19:23:19:85 | ... .parse() [Ok] | provenance | MaD:3 | +| main.rs:19:23:19:85 | ... .parse() [Ok] | main.rs:19:23:19:98 | ... .unwrap_or(...) | provenance | MaD:2 | +| main.rs:19:23:19:98 | ... .unwrap_or(...) | main.rs:19:9:19:19 | user_number | provenance | | +| main.rs:20:9:20:13 | regex | main.rs:21:26:21:30 | regex | provenance | | +| main.rs:20:25:20:47 | ...::format(...) | main.rs:20:25:20:47 | { ... } | provenance | | +| main.rs:20:25:20:47 | ...::must_use(...) | main.rs:20:9:20:13 | regex | provenance | | +| main.rs:20:25:20:47 | MacroExpr | main.rs:20:25:20:47 | ...::format(...) | provenance | MaD:4 | +| main.rs:20:25:20:47 | { ... } | main.rs:20:25:20:47 | ...::must_use(...) | provenance | MaD:5 | +| main.rs:21:26:21:30 | regex | main.rs:21:25:21:30 | ®ex | provenance | | models | 1 | Source: std::env::var; ReturnValue.Field[core::result::Result::Ok(0)]; environment | | 2 | Summary: ::unwrap_or; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | -| 3 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | -| 4 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value | +| 3 | Summary: ::parse; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 4 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | +| 5 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value | nodes | main.rs:4:9:4:16 | username | semmle.label | username | | main.rs:4:20:4:32 | ...::var | semmle.label | ...::var | @@ -28,4 +43,17 @@ nodes | main.rs:5:25:5:44 | { ... } | semmle.label | { ... } | | main.rs:6:25:6:30 | ®ex | semmle.label | ®ex | | main.rs:6:26:6:30 | regex | semmle.label | regex | +| main.rs:19:9:19:19 | user_number | semmle.label | user_number | +| main.rs:19:23:19:35 | ...::var | semmle.label | ...::var | +| main.rs:19:23:19:43 | ...::var(...) [Ok] | semmle.label | ...::var(...) [Ok] | +| main.rs:19:23:19:70 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) | +| main.rs:19:23:19:85 | ... .parse() [Ok] | semmle.label | ... .parse() [Ok] | +| main.rs:19:23:19:98 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) | +| main.rs:20:9:20:13 | regex | semmle.label | regex | +| main.rs:20:25:20:47 | ...::format(...) | semmle.label | ...::format(...) | +| main.rs:20:25:20:47 | ...::must_use(...) | semmle.label | ...::must_use(...) | +| main.rs:20:25:20:47 | MacroExpr | semmle.label | MacroExpr | +| main.rs:20:25:20:47 | { ... } | semmle.label | { ... } | +| main.rs:21:25:21:30 | ®ex | semmle.label | ®ex | +| main.rs:21:26:21:30 | regex | semmle.label | regex | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-020/RegexInjectionSink.expected b/rust/ql/test/query-tests/security/CWE-020/RegexInjectionSink.expected index 4ea46a38587..9bbf1a6904f 100644 --- a/rust/ql/test/query-tests/security/CWE-020/RegexInjectionSink.expected +++ b/rust/ql/test/query-tests/security/CWE-020/RegexInjectionSink.expected @@ -1,2 +1,3 @@ | main.rs:6:25:6:30 | ®ex | | main.rs:14:25:14:30 | ®ex | +| main.rs:21:25:21:30 | ®ex | diff --git a/rust/ql/test/query-tests/security/CWE-020/main.rs b/rust/ql/test/query-tests/security/CWE-020/main.rs index a03e5d4b494..fcd66e1e3ce 100644 --- a/rust/ql/test/query-tests/security/CWE-020/main.rs +++ b/rust/ql/test/query-tests/security/CWE-020/main.rs @@ -7,7 +7,7 @@ fn simple_bad(hay: &str) -> Option { Some(re.is_match(hay)) } -fn simple_good(hay: &str) -> Option { +fn simple_good_escaped(hay: &str) -> Option { let username = std::env::var("USER").unwrap_or("".to_string()); let escaped = regex::escape(&username); let regex = format!("foo{}bar", escaped); @@ -15,6 +15,13 @@ fn simple_good(hay: &str) -> Option { Some(re.is_match(hay)) } +fn simple_good_numeric(hay: &str) -> Option { + let user_number = std::env::var("USER").unwrap_or("0".to_string()).parse::().unwrap_or(0); // $ Source=env + let regex = format!("foo{}bar", user_number); + let re = Regex::new(®ex).unwrap(); // $ SPURIOUS: Alert[rust/regex-injection]=env + Some(re.is_match(hay)) +} + fn not_a_sink_literal() -> Option { let username = std::env::var("USER").unwrap_or("".to_string()); let re = Regex::new("literal string").unwrap(); @@ -30,7 +37,8 @@ fn not_a_sink_raw_literal() -> Option { fn main() { let hay = "a string"; simple_bad(hay); - simple_good(hay); + simple_good_escaped(hay); + simple_good_numeric(hay); not_a_sink_literal(); not_a_sink_raw_literal(); } diff --git a/rust/ql/test/query-tests/security/CWE-117/LogInjection.expected b/rust/ql/test/query-tests/security/CWE-117/LogInjection.expected index adc258a886a..6a4995a2728 100644 --- a/rust/ql/test/query-tests/security/CWE-117/LogInjection.expected +++ b/rust/ql/test/query-tests/security/CWE-117/LogInjection.expected @@ -3,14 +3,15 @@ | main.rs:17:5:17:10 | ...::log | main.rs:11:23:11:44 | ...::get | main.rs:17:5:17:10 | ...::log | Log entry depends on a $@. | main.rs:11:23:11:44 | ...::get | user-provided value | | main.rs:19:5:19:10 | ...::log | main.rs:10:22:10:34 | ...::var | main.rs:19:5:19:10 | ...::log | Log entry depends on a $@. | main.rs:10:22:10:34 | ...::var | user-provided value | | main.rs:30:5:30:9 | ...::log | main.rs:11:23:11:44 | ...::get | main.rs:30:5:30:9 | ...::log | Log entry depends on a $@. | main.rs:11:23:11:44 | ...::get | user-provided value | -| main.rs:108:9:108:13 | ...::log | main.rs:105:25:105:38 | ...::args | main.rs:108:9:108:13 | ...::log | Log entry depends on a $@. | main.rs:105:25:105:38 | ...::args | user-provided value | -| main.rs:109:9:109:13 | ...::log | main.rs:105:25:105:38 | ...::args | main.rs:109:9:109:13 | ...::log | Log entry depends on a $@. | main.rs:105:25:105:38 | ...::args | user-provided value | -| main.rs:110:9:110:14 | ...::log | main.rs:105:25:105:38 | ...::args | main.rs:110:9:110:14 | ...::log | Log entry depends on a $@. | main.rs:105:25:105:38 | ...::args | user-provided value | -| main.rs:111:9:111:14 | ...::log | main.rs:105:25:105:38 | ...::args | main.rs:111:9:111:14 | ...::log | Log entry depends on a $@. | main.rs:105:25:105:38 | ...::args | user-provided value | -| main.rs:112:9:112:14 | ...::log | main.rs:105:25:105:38 | ...::args | main.rs:112:9:112:14 | ...::log | Log entry depends on a $@. | main.rs:105:25:105:38 | ...::args | user-provided value | -| main.rs:115:9:115:13 | ...::log | main.rs:105:25:105:38 | ...::args | main.rs:115:9:115:13 | ...::log | Log entry depends on a $@. | main.rs:105:25:105:38 | ...::args | user-provided value | -| main.rs:122:9:122:16 | ...::_print | main.rs:119:25:119:37 | ...::var | main.rs:122:9:122:16 | ...::_print | Log entry depends on a $@. | main.rs:119:25:119:37 | ...::var | user-provided value | -| main.rs:123:9:123:17 | ...::_eprint | main.rs:119:25:119:37 | ...::var | main.rs:123:9:123:17 | ...::_eprint | Log entry depends on a $@. | main.rs:119:25:119:37 | ...::var | user-provided value | +| main.rs:49:5:49:9 | ...::log | main.rs:11:23:11:44 | ...::get | main.rs:49:5:49:9 | ...::log | Log entry depends on a $@. | main.rs:11:23:11:44 | ...::get | user-provided value | +| main.rs:112:9:112:13 | ...::log | main.rs:109:25:109:38 | ...::args | main.rs:112:9:112:13 | ...::log | Log entry depends on a $@. | main.rs:109:25:109:38 | ...::args | user-provided value | +| main.rs:113:9:113:13 | ...::log | main.rs:109:25:109:38 | ...::args | main.rs:113:9:113:13 | ...::log | Log entry depends on a $@. | main.rs:109:25:109:38 | ...::args | user-provided value | +| main.rs:114:9:114:14 | ...::log | main.rs:109:25:109:38 | ...::args | main.rs:114:9:114:14 | ...::log | Log entry depends on a $@. | main.rs:109:25:109:38 | ...::args | user-provided value | +| main.rs:115:9:115:14 | ...::log | main.rs:109:25:109:38 | ...::args | main.rs:115:9:115:14 | ...::log | Log entry depends on a $@. | main.rs:109:25:109:38 | ...::args | user-provided value | +| main.rs:116:9:116:14 | ...::log | main.rs:109:25:109:38 | ...::args | main.rs:116:9:116:14 | ...::log | Log entry depends on a $@. | main.rs:109:25:109:38 | ...::args | user-provided value | +| main.rs:119:9:119:13 | ...::log | main.rs:109:25:109:38 | ...::args | main.rs:119:9:119:13 | ...::log | Log entry depends on a $@. | main.rs:109:25:109:38 | ...::args | user-provided value | +| main.rs:126:9:126:16 | ...::_print | main.rs:123:25:123:37 | ...::var | main.rs:126:9:126:16 | ...::_print | Log entry depends on a $@. | main.rs:123:25:123:37 | ...::var | user-provided value | +| main.rs:127:9:127:17 | ...::_eprint | main.rs:123:25:123:37 | ...::var | main.rs:127:9:127:17 | ...::_eprint | Log entry depends on a $@. | main.rs:123:25:123:37 | ...::var | user-provided value | edges | main.rs:10:9:10:18 | user_input | main.rs:16:11:16:44 | MacroExpr | provenance | | | main.rs:10:9:10:18 | user_input | main.rs:19:12:19:39 | MacroExpr | provenance | | @@ -19,38 +20,44 @@ edges | main.rs:10:22:10:81 | ... .unwrap_or(...) | main.rs:10:9:10:18 | user_input | provenance | | | main.rs:11:9:11:19 | remote_data | main.rs:17:12:17:46 | MacroExpr | provenance | | | main.rs:11:9:11:19 | remote_data | main.rs:30:11:30:66 | MacroExpr | provenance | | +| main.rs:11:9:11:19 | remote_data | main.rs:48:18:48:43 | remote_data.parse() [Ok] | provenance | MaD:12 | +| main.rs:11:9:11:19 | remote_data | main.rs:48:18:48:43 | remote_data.parse() [Ok] | provenance | MaD:12 | | main.rs:11:23:11:44 | ...::get | main.rs:11:23:11:71 | ...::get(...) [Ok] | provenance | Src:MaD:4 | | main.rs:11:23:11:71 | ...::get(...) [Ok] | main.rs:11:23:12:17 | ... .unwrap() | provenance | MaD:9 | -| main.rs:11:23:12:17 | ... .unwrap() | main.rs:11:23:12:24 | ... .text() [Ok] | provenance | MaD:12 | +| main.rs:11:23:12:17 | ... .unwrap() | main.rs:11:23:12:24 | ... .text() [Ok] | provenance | MaD:13 | | main.rs:11:23:12:24 | ... .text() [Ok] | main.rs:11:23:12:61 | ... .unwrap_or(...) | provenance | MaD:10 | | main.rs:11:23:12:61 | ... .unwrap_or(...) | main.rs:11:9:11:19 | remote_data | provenance | | | main.rs:16:11:16:44 | MacroExpr | main.rs:16:5:16:9 | ...::log | provenance | MaD:1 Sink:MaD:1 | | main.rs:17:12:17:46 | MacroExpr | main.rs:17:5:17:10 | ...::log | provenance | MaD:1 Sink:MaD:1 | | main.rs:19:12:19:39 | MacroExpr | main.rs:19:5:19:10 | ...::log | provenance | MaD:1 Sink:MaD:1 | | main.rs:30:11:30:66 | MacroExpr | main.rs:30:5:30:9 | ...::log | provenance | MaD:1 Sink:MaD:1 | -| main.rs:105:13:105:21 | user_data | main.rs:108:15:108:35 | MacroExpr | provenance | | -| main.rs:105:13:105:21 | user_data | main.rs:109:15:109:38 | MacroExpr | provenance | | -| main.rs:105:13:105:21 | user_data | main.rs:110:16:110:37 | MacroExpr | provenance | | -| main.rs:105:13:105:21 | user_data | main.rs:111:16:111:37 | MacroExpr | provenance | | -| main.rs:105:13:105:21 | user_data | main.rs:112:16:112:37 | MacroExpr | provenance | | -| main.rs:105:13:105:21 | user_data | main.rs:115:15:115:75 | MacroExpr | provenance | | -| main.rs:105:25:105:38 | ...::args | main.rs:105:25:105:40 | ...::args(...) [element] | provenance | Src:MaD:5 | -| main.rs:105:25:105:40 | ...::args(...) [element] | main.rs:105:25:105:47 | ... .nth(...) [Some] | provenance | MaD:7 | -| main.rs:105:25:105:47 | ... .nth(...) [Some] | main.rs:105:25:105:67 | ... .unwrap_or_default() | provenance | MaD:8 | -| main.rs:105:25:105:67 | ... .unwrap_or_default() | main.rs:105:13:105:21 | user_data | provenance | | -| main.rs:108:15:108:35 | MacroExpr | main.rs:108:9:108:13 | ...::log | provenance | MaD:1 Sink:MaD:1 | -| main.rs:109:15:109:38 | MacroExpr | main.rs:109:9:109:13 | ...::log | provenance | MaD:1 Sink:MaD:1 | -| main.rs:110:16:110:37 | MacroExpr | main.rs:110:9:110:14 | ...::log | provenance | MaD:1 Sink:MaD:1 | -| main.rs:111:16:111:37 | MacroExpr | main.rs:111:9:111:14 | ...::log | provenance | MaD:1 Sink:MaD:1 | -| main.rs:112:16:112:37 | MacroExpr | main.rs:112:9:112:14 | ...::log | provenance | MaD:1 Sink:MaD:1 | -| main.rs:115:15:115:75 | MacroExpr | main.rs:115:9:115:13 | ...::log | provenance | MaD:1 Sink:MaD:1 | -| main.rs:119:13:119:21 | user_data | main.rs:122:18:122:38 | MacroExpr | provenance | | -| main.rs:119:13:119:21 | user_data | main.rs:123:19:123:49 | MacroExpr | provenance | | -| main.rs:119:25:119:37 | ...::var | main.rs:119:25:119:45 | ...::var(...) [Ok] | provenance | Src:MaD:6 | -| main.rs:119:25:119:45 | ...::var(...) [Ok] | main.rs:119:25:119:65 | ... .unwrap_or_default() | provenance | MaD:11 | -| main.rs:119:25:119:65 | ... .unwrap_or_default() | main.rs:119:13:119:21 | user_data | provenance | | -| main.rs:122:18:122:38 | MacroExpr | main.rs:122:9:122:16 | ...::_print | provenance | MaD:3 Sink:MaD:3 | -| main.rs:123:19:123:49 | MacroExpr | main.rs:123:9:123:17 | ...::_eprint | provenance | MaD:2 Sink:MaD:2 | +| main.rs:48:9:48:14 | number | main.rs:49:11:49:30 | MacroExpr | provenance | | +| main.rs:48:18:48:43 | remote_data.parse() [Ok] | main.rs:48:18:48:56 | ... .unwrap_or(...) | provenance | MaD:10 | +| main.rs:48:18:48:56 | ... .unwrap_or(...) | main.rs:48:9:48:14 | number | provenance | | +| main.rs:49:11:49:30 | MacroExpr | main.rs:49:5:49:9 | ...::log | provenance | MaD:1 Sink:MaD:1 | +| main.rs:109:13:109:21 | user_data | main.rs:112:15:112:35 | MacroExpr | provenance | | +| main.rs:109:13:109:21 | user_data | main.rs:113:15:113:38 | MacroExpr | provenance | | +| main.rs:109:13:109:21 | user_data | main.rs:114:16:114:37 | MacroExpr | provenance | | +| main.rs:109:13:109:21 | user_data | main.rs:115:16:115:37 | MacroExpr | provenance | | +| main.rs:109:13:109:21 | user_data | main.rs:116:16:116:37 | MacroExpr | provenance | | +| main.rs:109:13:109:21 | user_data | main.rs:119:15:119:75 | MacroExpr | provenance | | +| main.rs:109:25:109:38 | ...::args | main.rs:109:25:109:40 | ...::args(...) [element] | provenance | Src:MaD:5 | +| main.rs:109:25:109:40 | ...::args(...) [element] | main.rs:109:25:109:47 | ... .nth(...) [Some] | provenance | MaD:7 | +| main.rs:109:25:109:47 | ... .nth(...) [Some] | main.rs:109:25:109:67 | ... .unwrap_or_default() | provenance | MaD:8 | +| main.rs:109:25:109:67 | ... .unwrap_or_default() | main.rs:109:13:109:21 | user_data | provenance | | +| main.rs:112:15:112:35 | MacroExpr | main.rs:112:9:112:13 | ...::log | provenance | MaD:1 Sink:MaD:1 | +| main.rs:113:15:113:38 | MacroExpr | main.rs:113:9:113:13 | ...::log | provenance | MaD:1 Sink:MaD:1 | +| main.rs:114:16:114:37 | MacroExpr | main.rs:114:9:114:14 | ...::log | provenance | MaD:1 Sink:MaD:1 | +| main.rs:115:16:115:37 | MacroExpr | main.rs:115:9:115:14 | ...::log | provenance | MaD:1 Sink:MaD:1 | +| main.rs:116:16:116:37 | MacroExpr | main.rs:116:9:116:14 | ...::log | provenance | MaD:1 Sink:MaD:1 | +| main.rs:119:15:119:75 | MacroExpr | main.rs:119:9:119:13 | ...::log | provenance | MaD:1 Sink:MaD:1 | +| main.rs:123:13:123:21 | user_data | main.rs:126:18:126:38 | MacroExpr | provenance | | +| main.rs:123:13:123:21 | user_data | main.rs:127:19:127:49 | MacroExpr | provenance | | +| main.rs:123:25:123:37 | ...::var | main.rs:123:25:123:45 | ...::var(...) [Ok] | provenance | Src:MaD:6 | +| main.rs:123:25:123:45 | ...::var(...) [Ok] | main.rs:123:25:123:65 | ... .unwrap_or_default() | provenance | MaD:11 | +| main.rs:123:25:123:65 | ... .unwrap_or_default() | main.rs:123:13:123:21 | user_data | provenance | | +| main.rs:126:18:126:38 | MacroExpr | main.rs:126:9:126:16 | ...::_print | provenance | MaD:3 Sink:MaD:3 | +| main.rs:127:19:127:49 | MacroExpr | main.rs:127:9:127:17 | ...::_eprint | provenance | MaD:2 Sink:MaD:2 | models | 1 | Sink: log::__private_api::log; Argument[0]; log-injection | | 2 | Sink: std::io::stdio::_eprint; Argument[0]; log-injection | @@ -63,7 +70,8 @@ models | 9 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | | 10 | Summary: ::unwrap_or; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | | 11 | Summary: ::unwrap_or_default; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | -| 12 | Summary: ::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 12 | Summary: ::parse; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 13 | Summary: ::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | nodes | main.rs:10:9:10:18 | user_input | semmle.label | user_input | | main.rs:10:22:10:34 | ...::var | semmle.label | ...::var | @@ -83,29 +91,34 @@ nodes | main.rs:19:12:19:39 | MacroExpr | semmle.label | MacroExpr | | main.rs:30:5:30:9 | ...::log | semmle.label | ...::log | | main.rs:30:11:30:66 | MacroExpr | semmle.label | MacroExpr | -| main.rs:105:13:105:21 | user_data | semmle.label | user_data | -| main.rs:105:25:105:38 | ...::args | semmle.label | ...::args | -| main.rs:105:25:105:40 | ...::args(...) [element] | semmle.label | ...::args(...) [element] | -| main.rs:105:25:105:47 | ... .nth(...) [Some] | semmle.label | ... .nth(...) [Some] | -| main.rs:105:25:105:67 | ... .unwrap_or_default() | semmle.label | ... .unwrap_or_default() | -| main.rs:108:9:108:13 | ...::log | semmle.label | ...::log | -| main.rs:108:15:108:35 | MacroExpr | semmle.label | MacroExpr | -| main.rs:109:9:109:13 | ...::log | semmle.label | ...::log | -| main.rs:109:15:109:38 | MacroExpr | semmle.label | MacroExpr | -| main.rs:110:9:110:14 | ...::log | semmle.label | ...::log | -| main.rs:110:16:110:37 | MacroExpr | semmle.label | MacroExpr | -| main.rs:111:9:111:14 | ...::log | semmle.label | ...::log | -| main.rs:111:16:111:37 | MacroExpr | semmle.label | MacroExpr | -| main.rs:112:9:112:14 | ...::log | semmle.label | ...::log | -| main.rs:112:16:112:37 | MacroExpr | semmle.label | MacroExpr | -| main.rs:115:9:115:13 | ...::log | semmle.label | ...::log | -| main.rs:115:15:115:75 | MacroExpr | semmle.label | MacroExpr | -| main.rs:119:13:119:21 | user_data | semmle.label | user_data | -| main.rs:119:25:119:37 | ...::var | semmle.label | ...::var | -| main.rs:119:25:119:45 | ...::var(...) [Ok] | semmle.label | ...::var(...) [Ok] | -| main.rs:119:25:119:65 | ... .unwrap_or_default() | semmle.label | ... .unwrap_or_default() | -| main.rs:122:9:122:16 | ...::_print | semmle.label | ...::_print | -| main.rs:122:18:122:38 | MacroExpr | semmle.label | MacroExpr | -| main.rs:123:9:123:17 | ...::_eprint | semmle.label | ...::_eprint | -| main.rs:123:19:123:49 | MacroExpr | semmle.label | MacroExpr | +| main.rs:48:9:48:14 | number | semmle.label | number | +| main.rs:48:18:48:43 | remote_data.parse() [Ok] | semmle.label | remote_data.parse() [Ok] | +| main.rs:48:18:48:56 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) | +| main.rs:49:5:49:9 | ...::log | semmle.label | ...::log | +| main.rs:49:11:49:30 | MacroExpr | semmle.label | MacroExpr | +| main.rs:109:13:109:21 | user_data | semmle.label | user_data | +| main.rs:109:25:109:38 | ...::args | semmle.label | ...::args | +| main.rs:109:25:109:40 | ...::args(...) [element] | semmle.label | ...::args(...) [element] | +| main.rs:109:25:109:47 | ... .nth(...) [Some] | semmle.label | ... .nth(...) [Some] | +| main.rs:109:25:109:67 | ... .unwrap_or_default() | semmle.label | ... .unwrap_or_default() | +| main.rs:112:9:112:13 | ...::log | semmle.label | ...::log | +| main.rs:112:15:112:35 | MacroExpr | semmle.label | MacroExpr | +| main.rs:113:9:113:13 | ...::log | semmle.label | ...::log | +| main.rs:113:15:113:38 | MacroExpr | semmle.label | MacroExpr | +| main.rs:114:9:114:14 | ...::log | semmle.label | ...::log | +| main.rs:114:16:114:37 | MacroExpr | semmle.label | MacroExpr | +| main.rs:115:9:115:14 | ...::log | semmle.label | ...::log | +| main.rs:115:16:115:37 | MacroExpr | semmle.label | MacroExpr | +| main.rs:116:9:116:14 | ...::log | semmle.label | ...::log | +| main.rs:116:16:116:37 | MacroExpr | semmle.label | MacroExpr | +| main.rs:119:9:119:13 | ...::log | semmle.label | ...::log | +| main.rs:119:15:119:75 | MacroExpr | semmle.label | MacroExpr | +| main.rs:123:13:123:21 | user_data | semmle.label | user_data | +| main.rs:123:25:123:37 | ...::var | semmle.label | ...::var | +| main.rs:123:25:123:45 | ...::var(...) [Ok] | semmle.label | ...::var(...) [Ok] | +| main.rs:123:25:123:65 | ... .unwrap_or_default() | semmle.label | ... .unwrap_or_default() | +| main.rs:126:9:126:16 | ...::_print | semmle.label | ...::_print | +| main.rs:126:18:126:38 | MacroExpr | semmle.label | MacroExpr | +| main.rs:127:9:127:17 | ...::_eprint | semmle.label | ...::_eprint | +| main.rs:127:19:127:49 | MacroExpr | semmle.label | MacroExpr | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-117/main.rs b/rust/ql/test/query-tests/security/CWE-117/main.rs index 10bb03eb02c..88350515314 100644 --- a/rust/ql/test/query-tests/security/CWE-117/main.rs +++ b/rust/ql/test/query-tests/security/CWE-117/main.rs @@ -40,10 +40,14 @@ fn main() { let system_time = std::time::SystemTime::now(); info!("Current time: {:?}", system_time); - // GOOD: Numeric data derived from user input (not directly logged) + // GOOD: Numeric data derived from user input (indirectly) let user_id = username.len(); info!("User ID length: {}", user_id); + // GOOD: Numeric data derived from user input (directly) + let number = remote_data.parse::().unwrap_or(0); + info!("Number: {}", number); // $ SPURIOUS: Alert[rust/log-injection]=remote + // More complex test cases test_complex_scenarios(&username, &user_input); test_indirect_flows(&remote_data);