如何使用条件集合构建 SELECT * WHERE
How to build SELECT * WHERE using collection of conditions
我想使用来自 REST api 的查询字符串的条件列表构建一个 SELECT 语句。我写了这个函数,但它可能容易受到 SQL 注入。有人可以告诉我这是否容易受到攻击如何修复?也许我应该使用某种 SQLBuilder 包?或者有没有办法只用 dotNet 来做到这一点。我正在使用 dotNet 4.6.1
string BuildSelect(NameValueCollection query)
{
var result = "SELECT * FROM MYTABLE";
if (query.Count == 0) return result;
var logic = " WHERE ";
foreach (string key in query)
foreach (string v in query.GetValues(key))
{
result += logic + key + " = " + v;
logic = " AND ";
}
return result;
}
是的,它容易受到 SQL 注入攻击。您可以构建查询以改用参数(您只是使用 = 仅检查)。
既然你知道表名,那意味着你也知道列(键)可以是什么。因此,您可以循环列,如果集合具有该键,则将其作为参数化语句添加到 where 但值部分未作为字符串传递,您将其解析为应有的类型(或让后端执行转换并在无法转换时出错)。在伪代码中:
List<string> clauses = new List<string>();
var result = "SELECT * FROM MYTABLE";
foreach( var col in myTable.Columns )
{
if (query.ContainsKey(col.Name))
{
clauses.Add( $"{col.Name} = @{col.Name}";
string v = query[col.Name];
command.Parameters.Add( $"@{col.Name}", col.Type).Value = typeParse(v);
}
}
if (clauses.Any())
{
result += " WHERE " + string.Join( " AND ", clauses );
}
return result;
HTH
我想使用来自 REST api 的查询字符串的条件列表构建一个 SELECT 语句。我写了这个函数,但它可能容易受到 SQL 注入。有人可以告诉我这是否容易受到攻击如何修复?也许我应该使用某种 SQLBuilder 包?或者有没有办法只用 dotNet 来做到这一点。我正在使用 dotNet 4.6.1
string BuildSelect(NameValueCollection query)
{
var result = "SELECT * FROM MYTABLE";
if (query.Count == 0) return result;
var logic = " WHERE ";
foreach (string key in query)
foreach (string v in query.GetValues(key))
{
result += logic + key + " = " + v;
logic = " AND ";
}
return result;
}
是的,它容易受到 SQL 注入攻击。您可以构建查询以改用参数(您只是使用 = 仅检查)。
既然你知道表名,那意味着你也知道列(键)可以是什么。因此,您可以循环列,如果集合具有该键,则将其作为参数化语句添加到 where 但值部分未作为字符串传递,您将其解析为应有的类型(或让后端执行转换并在无法转换时出错)。在伪代码中:
List<string> clauses = new List<string>();
var result = "SELECT * FROM MYTABLE";
foreach( var col in myTable.Columns )
{
if (query.ContainsKey(col.Name))
{
clauses.Add( $"{col.Name} = @{col.Name}";
string v = query[col.Name];
command.Parameters.Add( $"@{col.Name}", col.Type).Value = typeParse(v);
}
}
if (clauses.Any())
{
result += " WHERE " + string.Join( " AND ", clauses );
}
return result;
HTH