mirror of
https://github.com/github/codeql.git
synced 2026-04-21 06:55:31 +02:00
Merge pull request #19466 from geoffw0/web
Rust: Add tests for web frameworks as taint sources
This commit is contained in:
@@ -47,3 +47,8 @@
|
||||
| test.rs:369:25:369:43 | ...::open | Flow source 'FileSource' of type file (DEFAULT). |
|
||||
| test.rs:377:22:377:35 | ...::stdin | Flow source 'StdInSource' of type stdin (DEFAULT). |
|
||||
| test.rs:386:16:386:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs (DEFAULT). |
|
||||
| web_frameworks.rs:12:31:12:31 | a | Flow source 'RemoteSource' of type remote (DEFAULT). |
|
||||
| web_frameworks.rs:21:31:21:36 | TuplePat | Flow source 'RemoteSource' of type remote (DEFAULT). |
|
||||
| web_frameworks.rs:43:31:43:45 | MyStruct {...} | Flow source 'RemoteSource' of type remote (DEFAULT). |
|
||||
| web_frameworks.rs:51:31:51:32 | ms | Flow source 'RemoteSource' of type remote (DEFAULT). |
|
||||
| web_frameworks.rs:60:15:60:15 | a | Flow source 'RemoteSource' of type remote (DEFAULT). |
|
||||
|
||||
@@ -7,3 +7,8 @@ qltest_dependencies:
|
||||
- http = { version = "1.2.0" }
|
||||
- tokio = { version = "1.43.0", features = ["full"] }
|
||||
- futures = { version = "0.3" }
|
||||
- poem = { version = "3.1.10" }
|
||||
- serde = { version = "1.0.219" }
|
||||
- actix-web = { version = "4.10.2" }
|
||||
- axum = { version = "0.8.4" }
|
||||
- serde_json = { version = "1.0.140" }
|
||||
|
||||
198
rust/ql/test/library-tests/dataflow/sources/web_frameworks.rs
Normal file
198
rust/ql/test/library-tests/dataflow/sources/web_frameworks.rs
Normal file
@@ -0,0 +1,198 @@
|
||||
|
||||
fn sink<T>(_: T) { }
|
||||
|
||||
// --- tests ---
|
||||
|
||||
mod poem_test {
|
||||
use poem::{get, handler, web::Path, web::Query, Route, Server, listener::TcpListener};
|
||||
use serde::Deserialize;
|
||||
use super::sink;
|
||||
|
||||
#[handler]
|
||||
fn my_poem_handler_1(Path(a): Path<String>) -> String { // $ Alert[rust/summary/taint-sources]
|
||||
sink(a.as_str()); // $ MISSING: hasTaintFlow
|
||||
sink(a.as_bytes()); // $ MISSING: hasTaintFlow
|
||||
sink(a); // $ MISSING: hasTaintFlow
|
||||
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
#[handler]
|
||||
fn my_poem_handler_2(Path((a, b)): Path<(String, String)>) -> String { // $ Alert[rust/summary/taint-sources]
|
||||
sink(a); // $ MISSING: hasTaintFlow
|
||||
sink(b); // $ MISSING: hasTaintFlow
|
||||
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
#[handler]
|
||||
fn my_poem_handler_3(path: Path<(String, String)>) -> String { // $ MISSING: Alert[rust/summary/taint-sources]
|
||||
sink(&path.0); // $ MISSING: hasTaintFlow
|
||||
sink(&path.1); // $ MISSING: hasTaintFlow
|
||||
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct MyStruct {
|
||||
a: String,
|
||||
b: String,
|
||||
}
|
||||
|
||||
#[handler]
|
||||
fn my_poem_handler_4(Path(MyStruct {a, b}): Path<MyStruct>) -> String { // $ Alert[rust/summary/taint-sources]
|
||||
sink(a); // $ MISSING: hasTaintFlow
|
||||
sink(b); // $ MISSING: hasTaintFlow
|
||||
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
#[handler]
|
||||
fn my_poem_handler_5(Path(ms): Path<MyStruct>) -> String { // $ Alert[rust/summary/taint-sources]
|
||||
sink(ms.a); // $ MISSING: hasTaintFlow
|
||||
sink(ms.b); // $ MISSING: hasTaintFlow
|
||||
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
#[handler]
|
||||
fn my_poem_handler_6(
|
||||
Query(a): Query<String>, // $ Alert[rust/summary/taint-sources]
|
||||
) -> String {
|
||||
sink(a); // $ MISSING: hasTaintFlow
|
||||
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
async fn test_poem() {
|
||||
let app = Route::new()
|
||||
.at("/1/:a", get(my_poem_handler_1))
|
||||
.at("/2/:a/:b", get(my_poem_handler_2))
|
||||
.at("/3/:a/:b", get(my_poem_handler_3))
|
||||
.at("/4/:a/:b", get(my_poem_handler_4))
|
||||
.at("/5/:a/:b", get(my_poem_handler_5))
|
||||
.at("/6/:a/", get(my_poem_handler_6));
|
||||
|
||||
Server::new(TcpListener::bind("0.0.0.0:3000")).run(app).await.unwrap();
|
||||
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
mod actix_test {
|
||||
use actix_web::{get, web, App};
|
||||
use super::sink;
|
||||
|
||||
async fn my_actix_handler_1(path: web::Path<String>) -> String { // $ MISSING: Alert[rust/summary/taint-sources]
|
||||
let a = path.into_inner();
|
||||
sink(a.as_str()); // $ MISSING: hasTaintFlow
|
||||
sink(a.as_bytes()); // $ MISSING: hasTaintFlow
|
||||
sink(a); // $ MISSING: hasTaintFlow
|
||||
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
async fn my_actix_handler_2(path: web::Path<(String, String)>) -> String { // $ MISSING: Alert[rust/summary/taint-sources]
|
||||
let (a, b) = path.into_inner();
|
||||
|
||||
sink(a); // $ MISSING: hasTaintFlow
|
||||
sink(b); // $ MISSING: hasTaintFlow
|
||||
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
async fn my_actix_handler_3(web::Query(a): web::Query<String>) -> String { // $ MISSING: Alert[rust/summary/taint-sources]
|
||||
sink(a); // $ MISSING: hasTaintFlow
|
||||
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
#[get("/4/{a}")]
|
||||
async fn my_actix_handler_4(path: web::Path<String>) -> String { // $ MISSING: Alert[rust/summary/taint-sources]
|
||||
let a = path.into_inner();
|
||||
sink(a); // $ MISSING: hasTaintFlow
|
||||
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
async fn test_actix() {
|
||||
let app = App::new()
|
||||
.route("/1/{a}", web::get().to(my_actix_handler_1))
|
||||
.route("/2/{a}/{b}", web::get().to(my_actix_handler_2))
|
||||
.route("/3/{a}", web::get().to(my_actix_handler_3))
|
||||
.service(my_actix_handler_4);
|
||||
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
mod axum_test {
|
||||
use axum::Router;
|
||||
use axum::routing::get;
|
||||
use axum::extract::{Path, Query, Request, Json};
|
||||
use std::collections::HashMap;
|
||||
use super::sink;
|
||||
|
||||
async fn my_axum_handler_1(Path(a): Path<String>) -> &'static str { // $ MISSING: Alert[rust/summary/taint-sources]
|
||||
sink(a.as_str()); // $ MISSING: hasTaintFlow
|
||||
sink(a.as_bytes()); // $ MISSING: hasTaintFlow
|
||||
sink(a); // $ MISSING: hasTaintFlow
|
||||
|
||||
""
|
||||
}
|
||||
|
||||
async fn my_axum_handler_2(Path((a, b)): Path<(String, String)>) -> &'static str { // $ MISSING: Alert[rust/summary/taint-sources]
|
||||
sink(a); // $ MISSING: hasTaintFlow
|
||||
sink(b); // $ MISSING: hasTaintFlow
|
||||
|
||||
""
|
||||
}
|
||||
|
||||
async fn my_axum_handler_3(Query(params): Query<HashMap<String, String>>) -> &'static str { // $ MISSING: Alert[rust/summary/taint-sources]
|
||||
for (key, value) in params {
|
||||
sink(key); // $ MISSING: hasTaintFlow
|
||||
sink(value); // $ MISSING: hasTaintFlow
|
||||
}
|
||||
|
||||
""
|
||||
}
|
||||
|
||||
async fn my_axum_handler_4(request: Request) -> &'static str { // $ MISSING: Alert[rust/summary/taint-sources]
|
||||
sink(request.body()); // $ MISSING: hasTaintFlow
|
||||
request.headers().get("header").unwrap(); // $ MISSING: hasTaintFlow
|
||||
sink(request.into_body()); // $ MISSING: hasTaintFlow
|
||||
|
||||
""
|
||||
}
|
||||
|
||||
async fn my_axum_handler_5(Json(payload): Json<serde_json::Value>) -> &'static str { // $ MISSING: Alert[rust/summary/taint-sources]
|
||||
sink(payload.as_str()); // $ MISSING: hasTaintFlow
|
||||
sink(payload); // $ MISSING: hasTaintFlow
|
||||
|
||||
""
|
||||
}
|
||||
|
||||
async fn my_axum_handler_6(body: String) -> &'static str { // $ MISSING: Alert[rust/summary/taint-sources]
|
||||
sink(body); // $ MISSING: hasTaintFlow
|
||||
|
||||
""
|
||||
}
|
||||
|
||||
async fn my_axum_handler_7(body: String) -> &'static str { // $ MISSING: Alert[rust/summary/taint-sources]
|
||||
sink(body); // $ MISSING: hasTaintFlow
|
||||
|
||||
""
|
||||
}
|
||||
|
||||
async fn test_axum() {
|
||||
let app = Router::<()>::new()
|
||||
.route("/1/{a}", get(my_axum_handler_1))
|
||||
.route("/2/{a}/{b}", get(my_axum_handler_2))
|
||||
.route("/3/:a", get(my_axum_handler_3))
|
||||
.route("/4/:a", get(my_axum_handler_4))
|
||||
.route("/5/:a", get(my_axum_handler_5))
|
||||
.route("/67/:a", get(my_axum_handler_6).get(my_axum_handler_7));
|
||||
|
||||
// ...
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user