简体   繁体   English

C# 连接常量字符串以形成 SQL 查询是否安全?

[英]C# Is it safe to concatenate constant strings to form a SQL Query?

I need to change the table name dynamically based on specific conditions.我需要根据具体情况动态更改表名

Is it safe to build my sql query the following way or am I prone to SQL Injection?通过以下方式构建我的 sql 查询是否安全,或者我是否容易发生 SQL 注入?

string GenerateSQL(string tableName) {
    return $"SELECT * FROM {tableName};";
}

const string tableName1 = "MyTable1"; 
const string tableName2 = "MyTable2";

string sql;
if (condition1) {
    sql = GenerateSQL(tableName1);
} else if (condition2)
    sql = GenerateSQL(tableName1);
}

To generalize, I want to build a parameterized sql query string by concatenating constant strings.概括地说,我想通过连接常量字符串来构建一个参数化的 sql 查询字符串。

While this should not present any security problem as presented.虽然这不应该出现任何安全问题。 There should not be any possibility for SQL injection since it does not involve any user input. SQL 注入不应该有任何可能性,因为它不涉及任何用户输入。

I would still argue for using parametrized queries whenever possible, because code change.我仍然主张尽可能使用参数化查询,因为代码会发生变化。 There is a risk some future developer modifies the query to add a user injected parameter, or copies the example for some other purpose that does present a SQL injection vulnerability.某些未来的开发人员可能会修改查询以添加用户注入的参数,或者出于其他目的复制示例,这确实存在 SQL 注入漏洞。 Using parametrized queries everywhere would simplify your code guidelines and review.在任何地方使用参数化查询将简化您的代码指南和审查。

But as with everything related to security, it does depend on your specific application, threat model and other factors that only you can determine.但与与安全相关的所有事情一样,它确实取决于您的特定应用程序、威胁 model 和其他只有您可以确定的因素。

In the form you have shown, no there is no risk, as none of the query comes from user-input, and any possible combination of query and your table names cannot cause an injection.在您显示的表单中,没有风险,因为没有任何查询来自用户输入,并且查询和表名的任何可能组合都不会导致注入。

However it does introduce a possibility of a developer coming later and adding more conditions that may cause SQL injection.但是,它确实引入了开发人员稍后出现并添加更多可能导致 SQL 注入的条件的可能性。

One way to prevent (or at least discourage) this, is to declare the final query as const , this means that a developer would need to actively make decision to make it not const anymore.防止(或至少阻止)这种情况的一种方法是将最终查询声明为const ,这意味着开发人员需要积极做出决定以使其不再是const You cannot however use formatted $ strings.但是,您不能使用格式化的$字符串。

const string tableName1 = "MyTable1"; 
const string tableName2 = "MyTable2";

string GenerateSQL(string tableName) {
    const string query = @"
SELECT *
FROM " + tableName = @";
";
    return query;
}

Note also the use of a verbatim @ string in order to put newlines into the string, this makes queries far more readable.还要注意使用逐字的@字符串来将换行符放入字符串中,这使得查询更具可读性。

I would suggest changing the string to an enum to prevent any type of string manipulation in your SQL query:我建议将string更改为枚举,以防止 SQL 查询中的任何类型的字符串操作:

enum TableName {
    Unknown = 0, #default, always check and throw if Unknown
    MyTable1 = 1,
    MyTable2 = 2
}

string GenerateSQL(TableName tableName) {
    if(Unknown)throw new ArgumentOutOfRangeException();
    
    # could also use a [DescriptionAttribute] instead of ToString
    string name = tableName.ToString();
    return $"SELECT * FROM {name};";
}

# some method that needs the sql
TableName tableName = condition1 
    ? TableName.MyTable1 
    : TableName.MyTable2;

string sql = GenerateSQL(tableName);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM