Skip to content

Commit 310c02f

Browse files
committed
Rust: Add a dataflow sources test for the Poem web fraemework.
1 parent ae2fd52 commit 310c02f

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

rust/ql/test/library-tests/dataflow/sources/TaintSources.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,8 @@
4747
| test.rs:369:25:369:43 | ...::open | Flow source 'FileSource' of type file (DEFAULT). |
4848
| test.rs:377:22:377:35 | ...::stdin | Flow source 'StdInSource' of type stdin (DEFAULT). |
4949
| test.rs:386:16:386:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs (DEFAULT). |
50+
| web_frameworks.rs:13:31:13:31 | a | Flow source 'RemoteSource' of type remote (DEFAULT). |
51+
| web_frameworks.rs:22:31:22:36 | TuplePat | Flow source 'RemoteSource' of type remote (DEFAULT). |
52+
| web_frameworks.rs:44:31:44:45 | MyStruct {...} | Flow source 'RemoteSource' of type remote (DEFAULT). |
53+
| web_frameworks.rs:52:31:52:32 | ms | Flow source 'RemoteSource' of type remote (DEFAULT). |
54+
| web_frameworks.rs:61:15:61:15 | a | Flow source 'RemoteSource' of type remote (DEFAULT). |

rust/ql/test/library-tests/dataflow/sources/options.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ qltest_dependencies:
77
- http = { version = "1.2.0" }
88
- tokio = { version = "1.43.0", features = ["full"] }
99
- futures = { version = "0.3" }
10+
- poem = { version = "3.1.10" }
11+
- serde = { version = "1.0.219" }
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#![allow(deprecated)]
2+
3+
fn sink<T>(_: T) { }
4+
5+
// --- tests ---
6+
7+
mod poem_test {
8+
use poem::{get, handler, web::Path, web::Query, Route, Server, listener::TcpListener};
9+
use serde::Deserialize;
10+
use crate::web_frameworks::sink;
11+
12+
#[handler]
13+
fn my_poem_handler_1(Path(a): Path<String>) -> String { // $ Alert[rust/summary/taint-sources]
14+
sink(a.as_str()); // $ MISSING: hasTaintFlow
15+
sink(a.as_bytes()); // $ MISSING: hasTaintFlow
16+
sink(a); // $ MISSING: hasTaintFlow
17+
18+
"".to_string()
19+
}
20+
21+
#[handler]
22+
fn my_poem_handler_2(Path((a, b)): Path<(String, String)>) -> String { // $ Alert[rust/summary/taint-sources]
23+
sink(a); // $ MISSING: hasTaintFlow
24+
sink(b); // $ MISSING: hasTaintFlow
25+
26+
"".to_string()
27+
}
28+
29+
#[handler]
30+
fn my_poem_handler_3(path: Path<(String, String)>) -> String { // $ MISSING: Alert[rust/summary/taint-sources]
31+
sink(&path.0); // $ MISSING: hasTaintFlow
32+
sink(&path.1); // $ MISSING: hasTaintFlow
33+
34+
"".to_string()
35+
}
36+
37+
#[derive(Deserialize)]
38+
struct MyStruct {
39+
a: String,
40+
b: String,
41+
}
42+
43+
#[handler]
44+
fn my_poem_handler_4(Path(MyStruct {a, b}): Path<MyStruct>) -> String { // $ Alert[rust/summary/taint-sources]
45+
sink(a); // $ MISSING: hasTaintFlow
46+
sink(b); // $ MISSING: hasTaintFlow
47+
48+
"".to_string()
49+
}
50+
51+
#[handler]
52+
fn my_poem_handler_5(Path(ms): Path<MyStruct>) -> String { // $ Alert[rust/summary/taint-sources]
53+
sink(ms.a); // $ MISSING: hasTaintFlow
54+
sink(ms.b); // $ MISSING: hasTaintFlow
55+
56+
"".to_string()
57+
}
58+
59+
#[handler]
60+
fn my_poem_handler_6(
61+
Query(a): Query<String>, // $ Alert[rust/summary/taint-sources]
62+
) -> String {
63+
sink(a); // $ MISSING: hasTaintFlow
64+
65+
"".to_string()
66+
}
67+
68+
async fn test_poem() {
69+
let app = Route::new()
70+
.at("/1/:a", get(my_poem_handler_1))
71+
.at("/2/:a/:b", get(my_poem_handler_2))
72+
.at("/3/:a/:b", get(my_poem_handler_3))
73+
.at("/4/:a/:b", get(my_poem_handler_4))
74+
.at("/4/:a/:b", get(my_poem_handler_5))
75+
.at("/5/:a/", get(my_poem_handler_6));
76+
77+
_ = Server::new(TcpListener::bind("0.0.0.0:3000")).run(app).await.unwrap();
78+
79+
// ...
80+
}
81+
}

0 commit comments

Comments
 (0)