diff --git a/rust/ql/lib/codeql/rust/security/LogInjectionExtensions.qll b/rust/ql/lib/codeql/rust/security/LogInjectionExtensions.qll index a0282a0ff29..dafebc96731 100644 --- a/rust/ql/lib/codeql/rust/security/LogInjectionExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/LogInjectionExtensions.qll @@ -8,6 +8,7 @@ private import codeql.rust.dataflow.DataFlow private import codeql.rust.dataflow.FlowSink private import codeql.rust.Concepts private import codeql.util.Unit +private import codeql.rust.security.Barriers as Barriers /** * Provides default sources, sinks and barriers for detecting log injection @@ -42,4 +43,10 @@ module LogInjection { private class ModelsAsDataSink extends Sink { ModelsAsDataSink() { sinkNode(this, "log-injection") } } + + /** + * A barrier for log injection vulnerabilities for nodes whose type is a + * numeric or boolean type, which is unlikely to expose any vulnerability. + */ + private class NumericTypeBarrier extends Barrier instanceof Barriers::NumericTypeBarrier { } } 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 6a4995a2728..2e00f941c24 100644 --- a/rust/ql/test/query-tests/security/CWE-117/LogInjection.expected +++ b/rust/ql/test/query-tests/security/CWE-117/LogInjection.expected @@ -3,7 +3,6 @@ | 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: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 | @@ -20,21 +19,15 @@ 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:13 | +| main.rs:11:23:12:17 | ... .unwrap() | main.rs:11:23:12:24 | ... .text() [Ok] | provenance | MaD:12 | | 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: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 | | @@ -70,8 +63,7 @@ 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: ::parse; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 13 | Summary: ::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 12 | 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 | @@ -91,11 +83,6 @@ 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: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] | 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 88350515314..f5001846d1b 100644 --- a/rust/ql/test/query-tests/security/CWE-117/main.rs +++ b/rust/ql/test/query-tests/security/CWE-117/main.rs @@ -46,7 +46,7 @@ fn main() { // 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 + info!("Number: {}", number); // More complex test cases test_complex_scenarios(&username, &user_input);