使用列名的字符串列表查询SQL表
本文关键字:列表 查询 SQL 字符串 | 更新日期: 2023-09-27 18:20:25
我有两个问题1.我有一个字符串列表,它是列名。如何在SQL查询中使用它?2.该方法是否易于SQL注入?
这就是我现在所拥有的,
List<string> Columnnames = new List<string>();
cmd = new SqlCommand("Select "+Columnnames+" from test");
回答您的问题:
问题1-将您的代码更改为类似的代码
List<string> Columnnames = new List<string>();
// Code that populates Columnnames here
cmd = new SqlCommand("Select " + string.Join(",", Columnnames) + " from test");
问题2-取决于如何填充Columnnames
。如果这是通过网络输入填充的,那么是的。
如果列名来自外部源,那么是的,您必须将它们连接到字符串中。理想情况下,您应该使用[
/]
,但这只允许使用带空格的列名等-这不会改变SQL注入的任何内容,是的:除非您先将列名列为白名单,否则允许用户指定列名将是SQL注入的风险。也许:
if(Columnnames.Count == 0) throw new ArgumentException(
"You need to specify at least one column");
var sql = new StringBuilder("select ");
bool first = true;
foreach(var name in Columnnames) {
if(!IsKnownColumnName(name)) { // <=== very important test
throw new ArgumentException("Invalid column name: " + name);
}
sql.Append(first ? "[" : ",[").Append(name).Append("]");
first = false;
}
sql.Append(" from test");
...
cmd.CommandText = sql.ToString();
您可以将Columnnames
列表转换为逗号分隔的列值。像这样:
string columns = Columnnames.Aggregate((x,y) => x + "," + y);
cmd = new SqlCommand("Select "+columns+" from test");
这种方法很容易注入sql,因为有人可以很容易地发送像column ;drop database yourDB
这样的列名,所以这是个坏主意。
首先检查Columnames是否有任何值。其次,制作一个函数来创建类似dus-colunta、columnb的东西
SqlCommend应该像这样从测试中选择columna、columb;
您应该将列名连接到查询,以便每个列名与下一个列名用逗号分隔,例如(伪)
define sql = "SELECT "
for columnName in columnNames:
concatenate sql,columnName
if columnName is not last:
concatenate sql,","
end if
end for
concatenate sql," FROM test"
漏洞取决于列名的来源。如果您有内部不可变的列名列表,那么就没有风险,但如果它们以某种方式源自外部源,例如使用应用程序的用户,那么肯定容易出现SQL注入。