Skip to content

Commit 9d6a13c

Browse files
committed
Rust: Accept improved results for rust/sql-injection. Note that the lost annotations are only sources, not results, and I suspect will return when we have sufficient flow in these cases.
1 parent 9ea9f3a commit 9d6a13c

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,45 @@
11
#select
2+
| sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value |
3+
| sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value |
24
edges
5+
| sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:56:34:56:89 | MacroExpr | provenance | |
6+
| sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | provenance | Src:MaD:1 |
7+
| sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | sqlx.rs:48:25:48:78 | ... .unwrap(...) | provenance | MaD:4 |
8+
| sqlx.rs:48:25:48:78 | ... .unwrap(...) | sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | provenance | MaD:7 |
9+
| sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | provenance | MaD:5 |
10+
| sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | sqlx.rs:48:9:48:21 | remote_string | provenance | |
11+
| sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:67:30:67:43 | unsafe_query_4 | provenance | |
12+
| sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:78:29:78:42 | unsafe_query_4 | provenance | |
13+
| sqlx.rs:56:26:56:90 | res | sqlx.rs:56:34:56:89 | { ... } | provenance | |
14+
| sqlx.rs:56:34:56:89 | ...::format(...) | sqlx.rs:56:26:56:90 | res | provenance | |
15+
| sqlx.rs:56:34:56:89 | ...::must_use(...) | sqlx.rs:56:9:56:22 | unsafe_query_4 | provenance | |
16+
| sqlx.rs:56:34:56:89 | MacroExpr | sqlx.rs:56:34:56:89 | ...::format(...) | provenance | MaD:3 |
17+
| sqlx.rs:56:34:56:89 | { ... } | sqlx.rs:56:34:56:89 | ...::must_use(...) | provenance | MaD:6 |
18+
| sqlx.rs:67:30:67:43 | unsafe_query_4 | sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | provenance | MaD:2 |
19+
| sqlx.rs:78:29:78:42 | unsafe_query_4 | sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | provenance | MaD:2 |
20+
models
21+
| 1 | Source: repo:https://github.com/seanmonstar/reqwest:reqwest; crate::blocking::get; remote; ReturnValue.Variant[crate::result::Result::Ok(0)] |
22+
| 2 | Summary: lang:alloc; <crate::string::String>::as_str; Argument[self]; ReturnValue; taint |
23+
| 3 | Summary: lang:alloc; crate::fmt::format; Argument[0]; ReturnValue; taint |
24+
| 4 | Summary: lang:core; <crate::result::Result>::unwrap; Argument[self].Variant[crate::result::Result::Ok(0)]; ReturnValue; value |
25+
| 5 | Summary: lang:core; <crate::result::Result>::unwrap_or; Argument[self].Variant[crate::result::Result::Ok(0)]; ReturnValue; value |
26+
| 6 | Summary: lang:core; crate::hint::must_use; Argument[0]; ReturnValue; value |
27+
| 7 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; <crate::blocking::response::Response>::text; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint |
328
nodes
29+
| sqlx.rs:48:9:48:21 | remote_string | semmle.label | remote_string |
30+
| sqlx.rs:48:25:48:46 | ...::get | semmle.label | ...::get |
31+
| sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | semmle.label | ...::get(...) [Ok] |
32+
| sqlx.rs:48:25:48:78 | ... .unwrap(...) | semmle.label | ... .unwrap(...) |
33+
| sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | semmle.label | ... .text(...) [Ok] |
34+
| sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) |
35+
| sqlx.rs:56:9:56:22 | unsafe_query_4 | semmle.label | unsafe_query_4 |
36+
| sqlx.rs:56:26:56:90 | res | semmle.label | res |
37+
| sqlx.rs:56:34:56:89 | ...::format(...) | semmle.label | ...::format(...) |
38+
| sqlx.rs:56:34:56:89 | ...::must_use(...) | semmle.label | ...::must_use(...) |
39+
| sqlx.rs:56:34:56:89 | MacroExpr | semmle.label | MacroExpr |
40+
| sqlx.rs:56:34:56:89 | { ... } | semmle.label | { ... } |
41+
| sqlx.rs:67:30:67:43 | unsafe_query_4 | semmle.label | unsafe_query_4 |
42+
| sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | semmle.label | unsafe_query_4.as_str(...) |
43+
| sqlx.rs:78:29:78:42 | unsafe_query_4 | semmle.label | unsafe_query_4 |
44+
| sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | semmle.label | unsafe_query_4.as_str(...) |
445
subpaths

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err
6464
if enable_remote {
6565
let _ = conn.execute(unsafe_query_2.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1
6666
let _ = conn.execute(unsafe_query_3.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1
67-
let _ = conn.execute(unsafe_query_4.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1
67+
let _ = conn.execute(unsafe_query_4.as_str()).await?; // $ sql-sink Alert[rust/sql-injection]=remote1
6868
}
6969

7070
// prepared queries
@@ -75,7 +75,7 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err
7575
if enable_remote {
7676
let _ = sqlx::query(unsafe_query_2.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1
7777
let _ = sqlx::query(unsafe_query_3.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1
78-
let _ = sqlx::query(unsafe_query_4.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1
78+
let _ = sqlx::query(unsafe_query_4.as_str()).execute(&pool).await?; // $ sql-sink Alert[rust/sql-injection]=remote1
7979
}
8080
let _ = sqlx::query(prepared_query_1.as_str()).bind(const_string).execute(&pool).await?; // $ sql-sink
8181
let _ = sqlx::query(prepared_query_1.as_str()).bind(arg_string).execute(&pool).await?; // $ sql-sink
@@ -93,7 +93,7 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er
9393

9494
// construct queries
9595
let const_string = String::from("Alice");
96-
let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ Source=remote2
96+
let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING: Source=remote2
9797
let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'";
9898
let unsafe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'";
9999
let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe)
@@ -166,7 +166,7 @@ async fn test_sqlx_postgres(url: &str, enable_remote: bool) -> Result<(), sqlx::
166166

167167
// construct queries
168168
let const_string = String::from("Alice");
169-
let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ Source=remote3
169+
let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING: Source=remote3
170170
let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'";
171171
let unsafe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'";
172172
let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=$1"); // (prepared arguments are safe)

0 commit comments

Comments
 (0)