确保一个参数是在编译时定义的字符串字面量。

3
为了防止SQL注入的风险,我想创建一个API,该API只接受编译时字符串字面量作为输入,例如"SELECT * FROM MYTABLE;""WHERE price > 10"等。该函数可以进行所需的字符串拼接,生成一个String类型的SQL语句并执行。这将是执行SQL的唯一方式,因此可以确保SQL语句仅由开发人员定义的SQL片段创建,并且任何不受信任的用户输入必须映射到字符串字面量。这样可以消除用户输入最终进入SQL语句的任何可能性。这种做法可行吗?

5
不要只允许编译时字符串,考虑养成使用占位符值的习惯,即使数据是编译时的。你仍然需要进行转义,如果你手动操作,那是不好的。 - undefined
1个回答

6
你可以使用`&'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,这是不可能(完全)不通过字面值构造的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接