8个版本 (4个重大更新)
0.5.1 | 2023年2月14日 |
---|---|
0.5.0 | 2023年2月14日 |
0.4.0 | 2021年1月20日 |
0.3.0 | 2020年12月3日 |
0.1.1 | 2020年11月16日 |
在数据库接口类别中排名第1980
每月下载量:284
在concatsql_macro中使用
110KB
2.5K SLoC
ConcatSQL
ConcatSQL(concatsql
)是一个安全的SQL数据库库。
您可以使用字符串连接来防止SQL注入。
支持的数据库
您可以在Cargo.toml
中配置数据库后端
[dependencies]
concatsql = { version = "<version>", features = ["<postgres|mysql|sqlite>"] }
示例
正常值
let id = String::from("42"); // User supplied input
let passwd = String::from("pass"); // User supplied input
let query = query!("SELECT name FROM users WHERE id={id} AND passwd={passwd}");
assert_eq!(query.simulate(), "SELECT name FROM users WHERE id='42' AND passwd='pass'");
for row in conn.rows(&query).unwrap() {
assert_eq!(row.get(0).unwrap(), "Alice");
assert_eq!(row.get("name").unwrap(), "Alice");
}
危险值
let id = String::from("42"); // User supplied input
let passwd = String::from("'' or 1=1; --"); // User supplied input
let query = query!("SELECT name FROM users WHERE id={id} AND passwd={passwd}");
assert_eq!(query.simulate(), "SELECT name FROM users WHERE id='42' AND passwd=''''' or 1=1; --'");
for row in conn.rows(&query).unwrap() {
assert!(row.get("name").is_none());
}
如果您没有使用query!
无法编译 ... 安全!
let id = String::from("42");
let passwd = String::from("' or 1=1; --");
let query = format!("SELECT name FROM users WHERE id={id} AND passwd={passwd}");
conn.execute(&query).unwrap(); // error
当使用query(<String>)
无法编译 ... 安全!
let age = String::from("50 or 1=1; --");
let query = query!("SELECT name FROM users WHERE age < ") + query!(age); // error
为什么这个库可以防止SQL注入?
这是因为它是通过使用运算符重载而不是简单的字符串连接来实现的。query!
宏返回库的自身类型(WrapString
)。
例如,如果您将此WrapString
类型与一个String
类型组合,则会被转义的String
类型将组合并返回一个新的WrapString
。
struct WrapString<'a> {
query: Vec<Option<Cow<'a, str>>>,
params: Vec<Value>,
}
let bar: String = String::from("bar");
let num: i32 = 42;
let foobar42: WrapString = query!("foo{bar}{num}");
foobar42 {
query: [Some("foo"), None, None],
params: [Value::Text("bar"), Value::I32(42)],
}
ffi::sqlite3_prepare_v2(..., "foo??", ...);
ffi::sqlite3_bind_text(..., "bar", ...);
ffi::sqlite3_bind_int(..., 42);
许可证
MIT
依赖关系
~4–20MB
~276K SLoC