Skip to content

Commit 883e005

Browse files
committed
Rust: Add test cases for the mysql_async library.
1 parent ef93b36 commit 883e005

File tree

3 files changed

+185
-56
lines changed

3 files changed

+185
-56
lines changed

rust/ql/test/query-tests/security/CWE-089/Cargo.lock

Lines changed: 85 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/ql/test/query-tests/security/CWE-089/mysql.rs

Lines changed: 99 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,106 @@
1-
use mysql::*;
2-
use mysql::prelude::*;
3-
4-
async fn test_mysql(url: &str) -> Result<(), Box<dyn std::error::Error>> {
5-
// connect through a MySQL connection pool
6-
let mut pool = Pool::new("")?; // (this test is not runnable)
7-
let mut conn: PooledConn = pool.get_conn()?;
8-
let mut conn2: Conn = pool.get_conn()?.unwrap();
9-
10-
// construct queries
11-
let mut remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("")); // $ MISSING: Source=remote10
12-
let safe_query = String::from("SELECT * FROM people WHERE firstname='Alice'");
13-
let unsafe_query = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'";
14-
let prepared_query = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe)
15-
16-
// direct execution (safe)
17-
let _ : Vec<i64> = conn.query(safe_query.as_str())?;
18-
19-
// direct execution (unsafe)
20-
let _ : Vec<i64> = conn.query(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
21-
let _ : Vec<Result<i64, FromRowError>> = conn.query_opt(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
22-
conn.query_drop(unsafe_query.as_str()); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
23-
let _ : i64 = conn.query_first(unsafe_query.as_str())?.unwrap(); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
24-
let _ : Result<i64, FromRowError>= conn.query_first_opt(unsafe_query.as_str())?.unwrap(); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
25-
let _ = conn.query_fold(unsafe_query.as_str(), 0, |_: i64, _: i64| -> i64 { 0 })?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
26-
let _ = conn.query_fold_opt(unsafe_query.as_str(), 0, |_: i64, _: Result<i64, FromRowError>| -> i64 { 0 })?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
27-
let _ = conn.query_iter(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
28-
let _ = conn.query_map(unsafe_query.as_str(), |_: i64| -> () {})?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
29-
let _ = conn.query_map_opt(unsafe_query.as_str(), |_: Result<i64, FromRowError>| -> () {})?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
30-
let _ : Vec<i64> = conn2.query(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
31-
32-
// prepared queries (safe)
33-
let stmt = conn.prep(prepared_query.as_str())?;
34-
let _ : Vec<i64> = conn.exec(&stmt, (remote_string.as_str(),))?;
35-
let _ : Vec<Result<i64, FromRowError>> = conn.exec_opt(&stmt, (remote_string.as_str(),))?;
36-
let _ = conn.exec_batch(&stmt, vec![(remote_string.as_str(),)])?;
37-
conn.exec_drop(&stmt, (&remote_string.as_str(),));
38-
let _ : i64 = conn.exec_first(&stmt, (remote_string.as_str(),))?.unwrap();
39-
let _ : Result<i64, FromRowError> = conn.exec_first_opt(&stmt, (remote_string.as_str(),))?.unwrap();
40-
let _ = conn.exec_fold(&stmt, (remote_string.as_str(),), 0, |_: i64, _: i64| -> i64 { 0 })?;
41-
let _ = conn.exec_fold_opt(&stmt, (remote_string.as_str(),), 0, |_: i64, _: Result<i64, FromRowError>| -> i64 { 0 })?;
42-
let _ = conn.exec_iter(&stmt, (remote_string.as_str(),))?;
43-
let _ = conn.exec_map(&stmt, (remote_string.as_str(),), |_: i64| -> () {})?;
44-
let _ = conn.exec_map_opt(&stmt, (remote_string.as_str(),), |_: Result<i64, FromRowError>| -> () {})?;
45-
46-
Ok(())
1+
mod sync_test
2+
{
3+
use mysql::*;
4+
use mysql::prelude::*;
5+
6+
pub fn test_mysql(url: &str) -> Result<(), Box<dyn std::error::Error>> {
7+
// connect through a MySQL connection pool
8+
let mut pool = Pool::new("")?; // (this test is not runnable)
9+
let mut conn: PooledConn = pool.get_conn()?;
10+
let mut conn2: Conn = pool.get_conn()?.unwrap();
11+
12+
// construct queries
13+
let mut remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("")); // $ MISSING: Source=remote10
14+
let safe_query = String::from("SELECT * FROM people WHERE firstname='Alice'");
15+
let unsafe_query = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'";
16+
let prepared_query = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe)
17+
18+
// direct execution (safe)
19+
let _ : Vec<i64> = conn.query(safe_query.as_str())?;
20+
21+
// direct execution (unsafe)
22+
let _ : Vec<i64> = conn.query(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
23+
let _ : Vec<Result<i64, FromRowError>> = conn.query_opt(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
24+
conn.query_drop(unsafe_query.as_str()); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
25+
let _ : i64 = conn.query_first(unsafe_query.as_str())?.unwrap(); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
26+
let _ : Result<i64, FromRowError>= conn.query_first_opt(unsafe_query.as_str())?.unwrap(); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
27+
let _ = conn.query_fold(unsafe_query.as_str(), 0, |_: i64, _: i64| -> i64 { 0 })?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
28+
let _ = conn.query_fold_opt(unsafe_query.as_str(), 0, |_: i64, _: Result<i64, FromRowError>| -> i64 { 0 })?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
29+
let _ = conn.query_iter(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
30+
let _ = conn.query_map(unsafe_query.as_str(), |_: i64| -> () {})?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
31+
let _ = conn.query_map_opt(unsafe_query.as_str(), |_: Result<i64, FromRowError>| -> () {})?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
32+
let _ : Vec<i64> = conn2.query(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
33+
34+
// prepared queries (safe)
35+
let stmt = conn.prep(prepared_query.as_str())?;
36+
let _ : Vec<i64> = conn.exec(&stmt, (remote_string.as_str(),))?;
37+
let _ : Vec<Result<i64, FromRowError>> = conn.exec_opt(&stmt, (remote_string.as_str(),))?;
38+
let _ = conn.exec_batch(&stmt, vec![(remote_string.as_str(),)])?;
39+
conn.exec_drop(&stmt, (&remote_string.as_str(),));
40+
let _ : i64 = conn.exec_first(&stmt, (remote_string.as_str(),))?.unwrap();
41+
let _ : Result<i64, FromRowError> = conn.exec_first_opt(&stmt, (remote_string.as_str(),))?.unwrap();
42+
let _ = conn.exec_fold(&stmt, (remote_string.as_str(),), 0, |_: i64, _: i64| -> i64 { 0 })?;
43+
let _ = conn.exec_fold_opt(&stmt, (remote_string.as_str(),), 0, |_: i64, _: Result<i64, FromRowError>| -> i64 { 0 })?;
44+
let _ = conn.exec_iter(&stmt, (remote_string.as_str(),))?;
45+
let _ = conn.exec_map(&stmt, (remote_string.as_str(),), |_: i64| -> () {})?;
46+
let _ = conn.exec_map_opt(&stmt, (remote_string.as_str(),), |_: Result<i64, FromRowError>| -> () {})?;
47+
48+
Ok(())
49+
}
50+
}
51+
52+
mod async_test
53+
{
54+
use mysql_async::*;
55+
use mysql_async::prelude::*;
56+
57+
pub async fn test_mysql_async(url: &str) -> Result<()> {
58+
// connect through a MySQL connection pool
59+
let mut pool = Pool::new(""); // (this test is not runnable)
60+
let mut conn = pool.get_conn().await?;
61+
62+
// construct queries
63+
let mut remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("")); // $ MISSING: Source=remote11
64+
let safe_query = String::from("SELECT * FROM people WHERE firstname='Alice'");
65+
let unsafe_query = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'";
66+
let prepared_query = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe)
67+
68+
// direct execution (safe)
69+
let _ : Vec<i64> = conn.query(safe_query.as_str()).await?;
70+
71+
// direct execution (unsafe)
72+
let _ : Vec<i64> = conn.query(unsafe_query.as_str()).await?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
73+
conn.query_drop(unsafe_query.as_str()); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
74+
let _ : Option<i64> = conn.query_first(unsafe_query.as_str()).await?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
75+
let _ = conn.query_fold(unsafe_query.as_str(), 0, |_: i64, _: i64| -> i64 { 0 }).await?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
76+
let _ = conn.query_iter(unsafe_query.as_str()).await?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
77+
let _ = conn.query_stream::<i64, &str>(unsafe_query.as_str()).await?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
78+
let _ = conn.query_map(unsafe_query.as_str(), |_: i64| -> () {}).await?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
79+
80+
// prepared queries (safe)
81+
let stmt = conn.prep(prepared_query.as_str()).await?;
82+
let _ : Vec<i64> = conn.exec(&stmt, (remote_string.as_str(),)).await?;
83+
let _ = conn.exec_batch(&stmt, vec![(remote_string.as_str(),)]).await?;
84+
conn.exec_drop(&stmt, (&remote_string.as_str(),));
85+
let _ : Option<i64> = conn.exec_first(&stmt, (remote_string.as_str(),)).await?;
86+
let _ = conn.exec_fold(&stmt, (remote_string.as_str(),), 0, |_: i64, _: i64| -> i64 { 0 }).await?;
87+
let _ = conn.exec_iter(&stmt, (remote_string.as_str(),)).await?;
88+
let _ = conn.exec_stream::<i64, &Statement, (&str,)>(&stmt, (remote_string.as_str(),)).await?;
89+
let _ = conn.exec_map(&stmt, (remote_string.as_str(),), |_: i64| -> () {}).await?;
90+
91+
Ok(())
92+
}
4793
}
4894

4995
fn main() {
5096
println!("test_mysql...");
51-
match futures::executor::block_on(test_mysql("")) {
97+
match (sync_test::test_mysql("")) {
98+
Ok(_) => println!(" successful!"),
99+
Err(e) => println!(" error: {}", e),
100+
}
101+
102+
println!("test_mysql_async...");
103+
match futures::executor::block_on(async_test::test_mysql_async("")) {
52104
Ok(_) => println!(" successful!"),
53105
Err(e) => println!(" error: {}", e),
54106
}

rust/ql/test/query-tests/security/CWE-089/options.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ qltest_dependencies:
44
- sqlx = { version = "0.8", features = ["mysql", "sqlite", "postgres", "runtime-async-std", "tls-native-tls"] }
55
- futures = { version = "0.3" }
66
- mysql = { version = "26.0.1" }
7+
- mysql_async = { version = "0.36.1" }

0 commit comments

Comments
 (0)