Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 保护动态生成的SQL查询不受SQL注入的影响。C_C#_Sql_.net_Oracle_Sql Injection - Fatal编程技术网

C# 保护动态生成的SQL查询不受SQL注入的影响。C

C# 保护动态生成的SQL查询不受SQL注入的影响。C,c#,sql,.net,oracle,sql-injection,C#,Sql,.net,Oracle,Sql Injection,例如,下面我有一些示例代码 updateData(Dictionary<string,string> data){ string strTemp = string.Empty; foreach(KeyValuePair<string, string> values in data){ strTemp = values.Key + "='" values.Value + "',"; } string query = "updat

例如,下面我有一些示例代码

updateData(Dictionary<string,string> data){
    string strTemp = string.Empty;
    foreach(KeyValuePair<string, string> values in data){
        strTemp = values.Key + "='" values.Value + "',";
    }
   string query = "update tablename set " + strTemp + "modDate = sysdate"
 //execute query against oracle db
}

如果不知道字典、数据中有什么,并且对应用程序的其余部分知之甚少,那么防止SQL注入的最佳方法是什么?我可以动态参数化列名和值吗?

避免SQL注入的可靠方法是参数化查询:

UpdateData(Dictionary<string,string> data) {
    var assignments = string.Join(
        ", "
    ,   data.Keys.Select(key => $"{0}=:{0}", key)
    );
    string query = $"update tablename set {assignments}, modDate = sysdate"
    //execute query against oracle db
    Command cmd = ...
    foreach (var kvp in data) {
        cmd.Parameters.AddWithValue(kvp.Key, kvp.Value);
    }
    ...
}
首先,将由FieldName=:FieldName部分组成的赋值字符串添加到UPDATE语句中。之后,使用SQL参数集合上的AddWithValue方法将数据字典中的每个项绑定到其相应的参数


注意:以上假设您完全控制数据字典中的键,因为它们必须匹配表中的列名。如果整个字典来自外部输入,则在构造查询之前,必须根据表的元数据验证键,以防止试图利用键名进行SQL注入。

只需在SQL查询中传递一个参数,即可动态参数化值。白名单的关键;它们不能被参数化,而且你可能也不想让它们接触所有的列。你确实可以动态地构建一个可参数化的查询。另一种方法是预处理语句,它有一个限制,无法保存。如果数据中的键名是利用SQL注入的值呢?@BillKarwin对,我在这里假设键是预验证的。我对答案进行了编辑,明确指出了这一点。非常感谢。谢谢你的编辑。虽然这不太可能,而且在你的控制之下,但是有一个名为的列是合法的;删除表用户-。如果您不确定是否可以避免使用该列名,那么您的查询应该对列名进行分隔。@BillKarwin您是对的。不过,在Oracle中对名称进行定界带来了额外的挑战,因为一旦引用标识符,它就变得区分大小写。