确保参数是编译时定义的字符串文本

Ensure an argument is a compile time defined string literal

提问人:Max888 提问时间:9/5/2023 更新时间:9/5/2023 访问量:48

问:

为了防止SQL注入的风险,我想创建一个API,其中包含一个仅接受编译时字符串文字作为输入的函数,例如,等。然后,该函数可以执行所需的字符串连接,生成 sql 语句并执行它。这将是执行 SQL 的唯一方法,因此它保证 SQL 语句仅由开发人员定义的 SQL 位创建,并且任何不受信任的用户输入都必须映射到字符串文字。这消除了用户输入最终出现在 SQL 语句中的任何可能性。这可能吗?"SELECT * FROM MYTABLE;""WHERE price > 10"String

字符串 rust sql 注入 string-literals

评论

5赞 tadman 9/5/2023
不要只允许编译时字符串,而是考虑习惯性地使用占位符值,即使数据是编译时数据也是如此。你仍然需要逃脱,如果你手动这样做,那就不好了。

答:

6赞 Chayim Friedman 9/5/2023 #1

你可以采取.这并不能完全消除风险,例如 String::leak() 或不安全的代码,但这不太可能。&'static str

如果你真的想要,你可以有一个小宏:

#[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