Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.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# 参数为字符串的SqlCommand_C#_Sql_Sql Injection_Sqlcommand_Sqlparameter - Fatal编程技术网

C# 参数为字符串的SqlCommand

C# 参数为字符串的SqlCommand,c#,sql,sql-injection,sqlcommand,sqlparameter,C#,Sql,Sql Injection,Sqlcommand,Sqlparameter,我需要创建一个应用程序,在CSV形式的用户输入下,需要将CSV解析并生成为多种格式。其中一种格式是CSV每行的一系列SQL INSERT语句(作为字符串) (此时,您可以假设我已经将CSV解析为值列表或其他内容,因此这不是问题的重点) 鉴于此输入可能包含漏洞,我希望生成经过验证和清理的INSERT语句 我熟悉创建SqlCommand对象并将值添加到其参数列表中,但查看它似乎并没有按照我所希望的方式工作 那么,有没有一种方法可以按照我需要的方式生成经过清理的SQL语句(作为字符串) 编辑:这是我想

我需要创建一个应用程序,在CSV形式的用户输入下,需要将CSV解析并生成为多种格式。其中一种格式是CSV每行的一系列SQL INSERT语句(作为字符串)

(此时,您可以假设我已经将CSV解析为值列表或其他内容,因此这不是问题的重点)

鉴于此输入可能包含漏洞,我希望生成经过验证和清理的INSERT语句

我熟悉创建SqlCommand对象并将值添加到其参数列表中,但查看它似乎并没有按照我所希望的方式工作

那么,有没有一种方法可以按照我需要的方式生成经过清理的SQL语句(作为字符串)

编辑:这是我想做的一个例子

CSV:

SQL:


由于CSV中没有给出数据类型,应用程序也必须确定它。

因为我不知道您是如何存储变量的,我将使用
列表()向您展示一个完整的、可能的示例数据实现:

添加您的示例数据:

var tableName = "Users";
var records = new List<Dictionary<String, Object>>();
var recordFields = new Dictionary<String, Object>();
recordFields.Add("id", 1);
recordFields.Add("name", "Alice");
recordFields.Add("country", "France");
records.Add(recordFields);
recordFields = new Dictionary<String, Object>();
recordFields.Add("id", 2);
recordFields.Add("name", "Bob");
recordFields.Add("country", "Austria");
records.Add(recordFields);
recordFields = new Dictionary<String, Object>();
recordFields.Add("id", 3);
recordFields.Add("name", "Carol");
recordFields.Add("country", "Germany");
records.Add(recordFields);
请注意,这并没有经过真正的测试(它可以编译并且看起来不错),但无论如何它都应该对您有所帮助

编辑


@奥黛德:我想问题是丹尼尔不想管理公司 插入,但显示/输出/保存它们。因此,使用SqlCommand参数 不好,因为您看不到生成的SQL

@圆柱的,没错


这是不可能的,相反,不能将
字符串
SqlParameters
一起使用。因此,如果您稍后运行这些插入,恐怕您会接受Sql注入。我建议您在实际运行statemenets时使用上述代码。

因为我不知道您是如何存储变量的,我将使用
列表()向您展示一个完整的、可能的示例数据实现:

添加您的示例数据:

var tableName = "Users";
var records = new List<Dictionary<String, Object>>();
var recordFields = new Dictionary<String, Object>();
recordFields.Add("id", 1);
recordFields.Add("name", "Alice");
recordFields.Add("country", "France");
records.Add(recordFields);
recordFields = new Dictionary<String, Object>();
recordFields.Add("id", 2);
recordFields.Add("name", "Bob");
recordFields.Add("country", "Austria");
records.Add(recordFields);
recordFields = new Dictionary<String, Object>();
recordFields.Add("id", 3);
recordFields.Add("name", "Carol");
recordFields.Add("country", "Germany");
records.Add(recordFields);
请注意,这并没有经过真正的测试(它可以编译并且看起来不错),但无论如何它都应该对您有所帮助

编辑


@奥黛德:我想问题是丹尼尔不想管理公司 插入,但显示/输出/保存它们。因此,使用SqlCommand参数 不好,因为您看不到生成的SQL

@圆柱的,没错


这是不可能的,相反,不能将
字符串
SqlParameters
一起使用。因此,如果您稍后运行这些插入,恐怕您会接受Sql注入。我建议您在实际运行statemenets时使用上述代码。

与其说是答案,不如说是警告。如果您最终需要使用“经典”的转义路径来执行此操作,并且确实需要安全性(即数据来自不受信任的来源),请不要忘记,您需要担心的不仅仅是简单的转义

我们经常听到的基本特征是:

  • ”——>”
    撇号和其他东西非常明显,并且有文档记录
  • 一条语句中的多个命令-DB不总是允许,但很危险
如果您正在解析“邪恶行为”,您是否考虑过:

  • SELECT/*不重要*/1/*真的…*/FROM/*我很严肃*/users
  • 从%0dTABLE\u NAME中选择%09字段%09
  • 其中username=CONCAT(CHAR(97)、CHAR(100)、CHAR(109)、CHAR(105)、CHAR(110))
  • 从username=0x61646d696e的用户中选择passwd
总结:这里有龙


与其说是一个答案,不如说是一个警告。如果您最终需要使用“经典”的转义路径来执行此操作,并且确实需要安全性(即数据来自不受信任的来源),请不要忘记,您需要担心的不仅仅是简单的转义

我们经常听到的基本特征是:

  • ”——>”
    撇号和其他东西非常明显,并且有文档记录
  • 一条语句中的多个命令-DB不总是允许,但很危险
如果您正在解析“邪恶行为”,您是否考虑过:

  • SELECT/*不重要*/1/*真的…*/FROM/*我很严肃*/users
  • 从%0dTABLE\u NAME中选择%09字段%09
  • 其中username=CONCAT(CHAR(97)、CHAR(100)、CHAR(109)、CHAR(105)、CHAR(110))
  • 从username=0x61646d696e的用户中选择passwd
总结:这里有龙


如果您不想使用SQL对象,那么您必须自己对条目进行sanatize。我不知道SQL有什么推荐的格式,但是对于MySQL,下面的格式可以。我已经将它改为使用SQL,但是我不能保证它涵盖了所有可能的注入攻击

public string sqlEscape(string VAL)
{
    if (VAL == null)
    {
        return null;
    }
    return "\"" + Regex.Replace(VAL, @"[\r\n\x00\x1a\\'""]", @"\$0") + "\"";
}
若要使用,请执行以下操作(假设您的CSV行存储在一个名为CSV的数组中):


如果有人能提高这个让我知道

如果您不想使用SQL对象,那么您必须自己对条目进行sanatize。我不知道SQL有什么推荐的格式,但是对于MySQL,下面的格式可以。我已经将它改为使用SQL,但是我不能保证它涵盖了所有可能的注入攻击

public string sqlEscape(string VAL)
{
    if (VAL == null)
    {
        return null;
    }
    return "\"" + Regex.Replace(VAL, @"[\r\n\x00\x1a\\'""]", @"\$0") + "\"";
}
若要使用,请执行以下操作(假设您的CSV行存储在一个名为CSV的数组中):


如果有人能提高这个让我知道

这个问题的答案有什么不对?为什么它们不适合你?向我们展示:你做了什么,你得到了什么,你想要得到什么。你应该向我们展示一个示例
Insert
,其中包含字段名/类型和值。我已经包含了一个编辑。这更有意义吗?还应该有一个CREATETABLE语句,但我没有费心把它包括进去。@Oded:我想问题是daniel没有
public string sqlEscape(string VAL)
{
    if (VAL == null)
    {
        return null;
    }
    return "\"" + Regex.Replace(VAL, @"[\r\n\x00\x1a\\'""]", @"\$0") + "\"";
}
string query = @"INSERT INTO Users (id, name, country) VALUES (" + sqlEscape(csv[0]) + ", " + sqlEscape(csv[1]) + ", " + sqlEscape(csv[2]) + ");";