为了防止SQL注入的风险,我想用一个函数创建一个API,该函数只接受编译时字符串文字作为输入,例如"SELECT * FROM MYTABLE;"
、"WHERE price > 10"
等.然后该函数可以进行所需的字符串连接,生成String
SQL语句并执行它.这将是执行SQL的唯一方法,因此它保证只从开发人员定义的部分SQL创建SQL语句,并且任何不受信任的用户输入都必须映射到字符串文字.这消除了用户输入以SQL语句结尾的任何可能性.这个是可能的吗?
为了防止SQL注入的风险,我想用一个函数创建一个API,该函数只接受编译时字符串文字作为输入,例如"SELECT * FROM MYTABLE;"
、"WHERE price > 10"
等.然后该函数可以进行所需的字符串连接,生成String
SQL语句并执行它.这将是执行SQL的唯一方法,因此它保证只从开发人员定义的部分SQL创建SQL语句,并且任何不受信任的用户输入都必须映射到字符串文字.这消除了用户输入以SQL语句结尾的任何可能性.这个是可能的吗?
你可以选&'static str
号.这不会因为String::leak()
或不安全的代码而消除风险,但这使它变得非常不可能.
如果你真的想要,你可以有一个小宏图:
#[derive(Clone, Copy)]
pub struct StringLiteral(&'static str);
impl StringLiteral {
/// # Safety
///
/// `v` must be a string literal.
#[doc(hidden)]
pub unsafe fn new(v: &'static str) -> Self {
Self(v)
}
pub fn get(self) -> &'static str {
self.0
}
}
#[macro_export]
macro_rules! string_literal {
($v:literal) => {{
let v = $v; // This has to be a separate statement, to not be in the `unsafe` block
// SAFETY: We only accept literals.
unsafe { $crate::StringLiteral::new(v) }
}};
}
然后在代码中的任何地方使用StringLiteral
,如果不是从文字构造的,这是不可能(合理地)构造的.