Skip to content

Commit fcce862

Browse files
committed
Rust: Add an explicit test case for sinks with two relevant args.
1 parent 16e0de0 commit fcce862

File tree

2 files changed

+46
-26
lines changed

2 files changed

+46
-26
lines changed

rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,67 @@
44
| src/main.rs:107:13:107:31 | ...::open | src/main.rs:103:17:103:30 | ...::args | src/main.rs:107:13:107:31 | ...::open | This path depends on a $@. | src/main.rs:103:17:103:30 | ...::args | user-provided value |
55
| src/main.rs:110:13:110:33 | ...::open | src/main.rs:103:17:103:30 | ...::args | src/main.rs:110:13:110:33 | ...::open | This path depends on a $@. | src/main.rs:103:17:103:30 | ...::args | user-provided value |
66
| src/main.rs:113:13:113:37 | ...::open | src/main.rs:103:17:103:30 | ...::args | src/main.rs:113:13:113:37 | ...::open | This path depends on a $@. | src/main.rs:103:17:103:30 | ...::args | user-provided value |
7+
| src/main.rs:122:13:122:25 | ...::copy | src/main.rs:103:17:103:30 | ...::args | src/main.rs:122:13:122:25 | ...::copy | This path depends on a $@. | src/main.rs:103:17:103:30 | ...::args | user-provided value |
8+
| src/main.rs:123:13:123:25 | ...::copy | src/main.rs:103:17:103:30 | ...::args | src/main.rs:123:13:123:25 | ...::copy | This path depends on a $@. | src/main.rs:103:17:103:30 | ...::args | user-provided value |
79
edges
810
| src/main.rs:7:11:7:19 | file_name | src/main.rs:9:35:9:43 | file_name | provenance | |
911
| src/main.rs:9:9:9:17 | file_path | src/main.rs:11:24:11:32 | file_path | provenance | |
1012
| src/main.rs:9:21:9:44 | ...::from(...) | src/main.rs:9:9:9:17 | file_path | provenance | |
11-
| src/main.rs:9:35:9:43 | file_name | src/main.rs:9:21:9:44 | ...::from(...) | provenance | MaD:10 |
12-
| src/main.rs:9:35:9:43 | file_name | src/main.rs:9:21:9:44 | ...::from(...) | provenance | MaD:10 |
13-
| src/main.rs:11:24:11:32 | file_path | src/main.rs:11:5:11:22 | ...::read_to_string | provenance | MaD:4 Sink:MaD:4 |
13+
| src/main.rs:9:35:9:43 | file_name | src/main.rs:9:21:9:44 | ...::from(...) | provenance | MaD:12 |
14+
| src/main.rs:9:35:9:43 | file_name | src/main.rs:9:21:9:44 | ...::from(...) | provenance | MaD:12 |
15+
| src/main.rs:11:24:11:32 | file_path | src/main.rs:11:5:11:22 | ...::read_to_string | provenance | MaD:6 Sink:MaD:6 |
1416
| src/main.rs:103:9:103:13 | path1 | src/main.rs:104:33:104:37 | path1 | provenance | |
1517
| src/main.rs:103:9:103:13 | path1 | src/main.rs:106:39:106:43 | path1 | provenance | |
1618
| src/main.rs:103:9:103:13 | path1 | src/main.rs:109:41:109:45 | path1 | provenance | |
1719
| src/main.rs:103:9:103:13 | path1 | src/main.rs:112:45:112:49 | path1 | provenance | |
18-
| src/main.rs:103:17:103:30 | ...::args | src/main.rs:103:17:103:32 | ...::args(...) [element] | provenance | Src:MaD:5 |
19-
| src/main.rs:103:17:103:32 | ...::args(...) [element] | src/main.rs:103:17:103:39 | ... .nth(...) [Some] | provenance | MaD:7 |
20-
| src/main.rs:103:17:103:39 | ... .nth(...) [Some] | src/main.rs:103:17:103:48 | ... .unwrap() | provenance | MaD:8 |
20+
| src/main.rs:103:9:103:13 | path1 | src/main.rs:122:27:122:31 | path1 | provenance | |
21+
| src/main.rs:103:9:103:13 | path1 | src/main.rs:123:37:123:41 | path1 | provenance | |
22+
| src/main.rs:103:17:103:30 | ...::args | src/main.rs:103:17:103:32 | ...::args(...) [element] | provenance | Src:MaD:7 |
23+
| src/main.rs:103:17:103:32 | ...::args(...) [element] | src/main.rs:103:17:103:39 | ... .nth(...) [Some] | provenance | MaD:9 |
24+
| src/main.rs:103:17:103:39 | ... .nth(...) [Some] | src/main.rs:103:17:103:48 | ... .unwrap() | provenance | MaD:10 |
2125
| src/main.rs:103:17:103:48 | ... .unwrap() | src/main.rs:103:9:103:13 | path1 | provenance | |
22-
| src/main.rs:104:33:104:37 | path1 | src/main.rs:104:33:104:45 | path1.clone() | provenance | MaD:6 |
26+
| src/main.rs:104:33:104:37 | path1 | src/main.rs:104:33:104:45 | path1.clone() | provenance | MaD:8 |
2327
| src/main.rs:104:33:104:45 | path1.clone() | src/main.rs:104:13:104:31 | ...::open | provenance | MaD:2 Sink:MaD:2 |
2428
| src/main.rs:106:9:106:13 | path2 | src/main.rs:107:33:107:37 | path2 | provenance | |
25-
| src/main.rs:106:17:106:52 | ...::canonicalize(...) [Ok] | src/main.rs:106:17:106:61 | ... .unwrap() | provenance | MaD:9 |
29+
| src/main.rs:106:17:106:52 | ...::canonicalize(...) [Ok] | src/main.rs:106:17:106:61 | ... .unwrap() | provenance | MaD:11 |
2630
| src/main.rs:106:17:106:61 | ... .unwrap() | src/main.rs:106:9:106:13 | path2 | provenance | |
27-
| src/main.rs:106:39:106:43 | path1 | src/main.rs:106:39:106:51 | path1.clone() | provenance | MaD:6 |
28-
| src/main.rs:106:39:106:51 | path1.clone() | src/main.rs:106:17:106:52 | ...::canonicalize(...) [Ok] | provenance | MaD:12 |
31+
| src/main.rs:106:39:106:43 | path1 | src/main.rs:106:39:106:51 | path1.clone() | provenance | MaD:8 |
32+
| src/main.rs:106:39:106:51 | path1.clone() | src/main.rs:106:17:106:52 | ...::canonicalize(...) [Ok] | provenance | MaD:14 |
2933
| src/main.rs:107:33:107:37 | path2 | src/main.rs:107:13:107:31 | ...::open | provenance | MaD:2 Sink:MaD:2 |
3034
| src/main.rs:109:9:109:13 | path3 | src/main.rs:110:35:110:39 | path3 | provenance | |
3135
| src/main.rs:109:17:109:54 | ...::canonicalize(...) [future, Ok] | src/main.rs:109:17:109:60 | await ... [Ok] | provenance | |
32-
| src/main.rs:109:17:109:60 | await ... [Ok] | src/main.rs:109:17:109:69 | ... .unwrap() | provenance | MaD:9 |
36+
| src/main.rs:109:17:109:60 | await ... [Ok] | src/main.rs:109:17:109:69 | ... .unwrap() | provenance | MaD:11 |
3337
| src/main.rs:109:17:109:69 | ... .unwrap() | src/main.rs:109:9:109:13 | path3 | provenance | |
34-
| src/main.rs:109:41:109:45 | path1 | src/main.rs:109:41:109:53 | path1.clone() | provenance | MaD:6 |
35-
| src/main.rs:109:41:109:53 | path1.clone() | src/main.rs:109:17:109:54 | ...::canonicalize(...) [future, Ok] | provenance | MaD:13 |
38+
| src/main.rs:109:41:109:45 | path1 | src/main.rs:109:41:109:53 | path1.clone() | provenance | MaD:8 |
39+
| src/main.rs:109:41:109:53 | path1.clone() | src/main.rs:109:17:109:54 | ...::canonicalize(...) [future, Ok] | provenance | MaD:15 |
3640
| src/main.rs:110:35:110:39 | path3 | src/main.rs:110:13:110:33 | ...::open | provenance | MaD:3 Sink:MaD:3 |
3741
| src/main.rs:112:9:112:13 | path4 | src/main.rs:113:39:113:43 | path4 | provenance | |
3842
| src/main.rs:112:17:112:58 | ...::canonicalize(...) [future, Ok] | src/main.rs:112:17:112:64 | await ... [Ok] | provenance | |
39-
| src/main.rs:112:17:112:64 | await ... [Ok] | src/main.rs:112:17:112:73 | ... .unwrap() | provenance | MaD:9 |
43+
| src/main.rs:112:17:112:64 | await ... [Ok] | src/main.rs:112:17:112:73 | ... .unwrap() | provenance | MaD:11 |
4044
| src/main.rs:112:17:112:73 | ... .unwrap() | src/main.rs:112:9:112:13 | path4 | provenance | |
41-
| src/main.rs:112:45:112:49 | path1 | src/main.rs:112:45:112:57 | path1.clone() | provenance | MaD:6 |
42-
| src/main.rs:112:45:112:57 | path1.clone() | src/main.rs:112:17:112:58 | ...::canonicalize(...) [future, Ok] | provenance | MaD:11 |
45+
| src/main.rs:112:45:112:49 | path1 | src/main.rs:112:45:112:57 | path1.clone() | provenance | MaD:8 |
46+
| src/main.rs:112:45:112:57 | path1.clone() | src/main.rs:112:17:112:58 | ...::canonicalize(...) [future, Ok] | provenance | MaD:13 |
4347
| src/main.rs:113:39:113:43 | path4 | src/main.rs:113:13:113:37 | ...::open | provenance | MaD:1 Sink:MaD:1 |
48+
| src/main.rs:122:27:122:31 | path1 | src/main.rs:122:27:122:39 | path1.clone() | provenance | MaD:8 |
49+
| src/main.rs:122:27:122:39 | path1.clone() | src/main.rs:122:13:122:25 | ...::copy | provenance | MaD:4 Sink:MaD:4 |
50+
| src/main.rs:123:37:123:41 | path1 | src/main.rs:123:37:123:49 | path1.clone() | provenance | MaD:8 |
51+
| src/main.rs:123:37:123:49 | path1.clone() | src/main.rs:123:13:123:25 | ...::copy | provenance | MaD:5 Sink:MaD:5 |
4452
models
4553
| 1 | Sink: <async_std::fs::file::File>::open; Argument[0]; path-injection |
4654
| 2 | Sink: <std::fs::File>::open; Argument[0]; path-injection |
4755
| 3 | Sink: <tokio::fs::file::File>::open; Argument[0]; path-injection |
48-
| 4 | Sink: std::fs::read_to_string; Argument[0]; path-injection |
49-
| 5 | Source: std::env::args; ReturnValue.Element; commandargs |
50-
| 6 | Summary: <_ as core::clone::Clone>::clone; Argument[self].Reference; ReturnValue; value |
51-
| 7 | Summary: <_ as core::iter::traits::iterator::Iterator>::nth; Argument[self].Element; ReturnValue.Field[core::option::Option::Some(0)]; value |
52-
| 8 | Summary: <core::option::Option>::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value |
53-
| 9 | Summary: <core::result::Result>::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
54-
| 10 | Summary: <std::path::PathBuf as core::convert::From>::from; Argument[0]; ReturnValue; taint |
55-
| 11 | Summary: async_std::fs::canonicalize::canonicalize; Argument[0]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
56-
| 12 | Summary: std::fs::canonicalize; Argument[0]; ReturnValue.Field[core::result::Result::Ok(0)]; taint |
57-
| 13 | Summary: tokio::fs::canonicalize::canonicalize; Argument[0]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
56+
| 4 | Sink: std::fs::copy; Argument[0]; path-injection |
57+
| 5 | Sink: std::fs::copy; Argument[1]; path-injection |
58+
| 6 | Sink: std::fs::read_to_string; Argument[0]; path-injection |
59+
| 7 | Source: std::env::args; ReturnValue.Element; commandargs |
60+
| 8 | Summary: <_ as core::clone::Clone>::clone; Argument[self].Reference; ReturnValue; value |
61+
| 9 | Summary: <_ as core::iter::traits::iterator::Iterator>::nth; Argument[self].Element; ReturnValue.Field[core::option::Option::Some(0)]; value |
62+
| 10 | Summary: <core::option::Option>::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value |
63+
| 11 | Summary: <core::result::Result>::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
64+
| 12 | Summary: <std::path::PathBuf as core::convert::From>::from; Argument[0]; ReturnValue; taint |
65+
| 13 | Summary: async_std::fs::canonicalize::canonicalize; Argument[0]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
66+
| 14 | Summary: std::fs::canonicalize; Argument[0]; ReturnValue.Field[core::result::Result::Ok(0)]; taint |
67+
| 15 | Summary: tokio::fs::canonicalize::canonicalize; Argument[0]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint |
5868
nodes
5969
| src/main.rs:7:11:7:19 | file_name | semmle.label | file_name |
6070
| src/main.rs:9:9:9:17 | file_path | semmle.label | file_path |
@@ -93,4 +103,10 @@ nodes
93103
| src/main.rs:112:45:112:57 | path1.clone() | semmle.label | path1.clone() |
94104
| src/main.rs:113:13:113:37 | ...::open | semmle.label | ...::open |
95105
| src/main.rs:113:39:113:43 | path4 | semmle.label | path4 |
106+
| src/main.rs:122:13:122:25 | ...::copy | semmle.label | ...::copy |
107+
| src/main.rs:122:27:122:31 | path1 | semmle.label | path1 |
108+
| src/main.rs:122:27:122:39 | path1.clone() | semmle.label | path1.clone() |
109+
| src/main.rs:123:13:123:25 | ...::copy | semmle.label | ...::copy |
110+
| src/main.rs:123:37:123:41 | path1 | semmle.label | path1 |
111+
| src/main.rs:123:37:123:49 | path1.clone() | semmle.label | path1.clone() |
96112
subpaths

rust/ql/test/query-tests/security/CWE-022/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ async fn more_simple_cases() {
117117

118118
let path6 = path5.canonicalize().unwrap();
119119
let _ = std::fs::File::open(path6); // $ path-injection-sink MISSING: Alert[rust/path-injection]=arg1
120+
121+
let harmless = "";
122+
let _ = std::fs::copy(path1.clone(), harmless); // $ path-injection-sink Alert[rust/path-injection]=arg1
123+
let _ = std::fs::copy(harmless, path1.clone()); // $ path-injection-sink Alert[rust/path-injection]=arg1
120124
}
121125

122126
fn sinks(path1: &Path, path2: &Path) {

0 commit comments

Comments
 (0)