Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.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注入问题_C#_Sql_Sql Injection_Secure Coding - Fatal编程技术网

C# 如何解决表截断的SQL注入问题

C# 如何解决表截断的SQL注入问题,c#,sql,sql-injection,secure-coding,C#,Sql,Sql Injection,Secure Coding,下面是截断表记录的代码行。表格值来自前端。在我的代码扫描中,它显示了SQL注入。我怎样才能避免这种情况?我无法创建存储过程,因为连接字符串是动态的,需要截断此表。还有别的办法吗 SqlCommand cmd = connection.CreateCommand(); cmd.Transaction = transaction; cmd.CommandText = "TRUNCATE TABLE " + tablename; cmd.ExecuteNonQuery(); 您需

下面是截断表记录的代码行。表格值来自前端。在我的代码扫描中,它显示了SQL注入。我怎样才能避免这种情况?我无法创建存储过程,因为连接字符串是动态的,需要截断此表。还有别的办法吗

SqlCommand cmd = connection.CreateCommand();
cmd.Transaction = transaction;
cmd.CommandText = "TRUNCATE TABLE " + tablename;
cmd.ExecuteNonQuery();
您需要动态sql:

string sql = @"
    DECLARE @SQL nvarchar(150); 
    SELECT @SQL = 'truncate table ' + quotename(table_name) + ';'
        FROM information_schema.tables 
        WHERE table_name = @table;
    EXEC(@SQL);";

using (var connection = new SqlConnection("connection string here"))
using (var cmd = new SqlCommand(sql, connection))
{
    cmd.Transaction = transaction;
    cmd.Parameters.Add("@table", SqlDbType.NVarChar, 128).Value = tablename;
    connection.Open();
    cmd.ExecuteNonQuery();
}
这是动态SQL使事情变得更安全而不是更少的为数不多的几次之一。更妙的是,如果您还在该数据库中维护一个特殊的表,其中列出了允许用户截断的其他表,并使用该表而不是信息模式来验证名称。让用户直接截断任何内容的想法有点可怕。

您需要动态sql:

string sql = @"
    DECLARE @SQL nvarchar(150); 
    SELECT @SQL = 'truncate table ' + quotename(table_name) + ';'
        FROM information_schema.tables 
        WHERE table_name = @table;
    EXEC(@SQL);";

using (var connection = new SqlConnection("connection string here"))
using (var cmd = new SqlCommand(sql, connection))
{
    cmd.Transaction = transaction;
    cmd.Parameters.Add("@table", SqlDbType.NVarChar, 128).Value = tablename;
    connection.Open();
    cmd.ExecuteNonQuery();
}

这是动态SQL使事情变得更安全而不是更少的为数不多的几次之一。更妙的是,如果您还在该数据库中维护一个特殊的表,其中列出了允许用户截断的其他表,并使用该表而不是信息模式来验证名称。让用户直接截断任何东西的想法有点可怕。

这里有一种方法可以在扫描工具面前隐藏它

私有常量字符串_sql=VFJVTkNBVEUgVEFCTEU=; . . . . var temp=new{t=tablename}; cmd.CommandText= Encoding.ASCII.GetStringConvert.FromBase64String_sql+temp.t.PadLefttemp.t.Length+1;
隐蔽性安全性

这里有一种对扫描工具隐藏的方法

私有常量字符串_sql=VFJVTkNBVEUgVEFCTEU=; . . . . var temp=new{t=tablename}; cmd.CommandText= Encoding.ASCII.GetStringConvert.FromBase64String_sql+temp.t.PadLefttemp.t.Length+1;
模糊性安全性

参数化与否,在这种情况下,您只能使其更加安全。从未完全安全。为此你需要

在存储的数据库中创建表TruncMapping id guid 报表varchar300 您的数据看起来像 SOME-GUID-XXX-YYY,“截断表TBL1”

在前端,使用带有文本/值的列表框或组合框,如Customer Data/SOME-GUID-XXX-YYY 在代码中,使用ExecuteScalar从TruncMapping执行Select语句,其中id=@1,其中id将是组合值中的参数化GUID 与现在一样,使用ExecuteOnQuery执行truncate命令,但使用上一次调用中检索到的字符串。 您的故障诊断仪很可能会卡住。如果它仍然认为代码是不安全的,您可以安全地指出这是误报,因为您执行的是来自您的安全数据库。潜在的攻击者无法破坏您的不可调谐表,因为它们未列在TruncMapping表中


您刚刚创建了针对sql注入的多层防御。

参数化与否,在这种情况下,您只能使其更加安全。从未完全安全。为此你需要

在存储的数据库中创建表TruncMapping id guid 报表varchar300 您的数据看起来像 SOME-GUID-XXX-YYY,“截断表TBL1”

在前端,使用带有文本/值的列表框或组合框,如Customer Data/SOME-GUID-XXX-YYY 在代码中,使用ExecuteScalar从TruncMapping执行Select语句,其中id=@1,其中id将是组合值中的参数化GUID 与现在一样,使用ExecuteOnQuery执行truncate命令,但使用上一次调用中检索到的字符串。 您的故障诊断仪很可能会卡住。如果它仍然认为代码是不安全的,您可以安全地指出这是误报,因为您执行的是来自您的安全数据库。潜在的攻击者无法破坏您的不可调谐表,因为它们未列在TruncMapping表中


您刚刚创建了针对sql注入的多层防御。

您可以将其标记为假阳性。但我同意,这是一个糟糕的举动。为什么不能创建过程?有多少表可以发送到此代码?我建议将可能的表列表放入数组或哈希集中,并让代码确保传入的tablename值在其中。然后使用数组中的值,而不是传入的值。这并不完全是误报。然而首先,您需要确保正确转义了名称。或者对tablename使用枚举类型或常量字符串,而不是常规类型string@JoelFan我理解乔,它不是我设计的,它的代码很旧,我刚刚接到修复这些问题的任务,所以我只是想得到一个有效的帮助,如果我们可以做任何事情而不重新设计整个架构,你可以标记为假阳性。但我同意,这是一个糟糕的举动。为什么不能创建过程?有多少表可以发送到此代码?我建议将可能的表列表放入数组或哈希集中,并让代码确保传入的tablename值在其中。然后使用数组中的值,而不是传入的值。这并不完全是误报。然而首先,您需要确保正确转义名称。或者为tablenam使用枚举类型或常量字符串

e而不是普通的string@JoelFan我了解joe,它不是由我设计的,它的代码非常旧,我只是得到了修复这些问题的任务,所以我只是想得到一个有效的帮助,如果我们可以做任何事情而不重新设计整个架构,它不会产生sql注入缺陷??因为桌名是从前面传来的end@SarveshGupta不会,因为该表名已参数化here@SarveshGupta这将以安全的方式在数据库中循环输入,以确保您具有有效的表名。还有一个问题是,为什么允许选择任何表名并将其完全截断。@SarveshGupta为上下文添加了更多代码。您现在可以看到表作为安全参数值传入的位置。@Rahul参数化并不能使它在这里神奇地安全。这是另一个不会产生sql注入缺陷的步骤??因为桌名是从前面传来的end@SarveshGupta不会,因为该表名已参数化here@SarveshGupta这将以安全的方式在数据库中循环输入,以确保您具有有效的表名。还有一个问题是,为什么允许选择任何表名并将其完全截断。@SarveshGupta为上下文添加了更多代码。您现在可以看到表作为安全参数值传入的位置。@Rahul参数化并不能使它在这里神奇地安全。这是另一个步骤。这不是使用模糊性来消除代码分析中发现的完全合法的安全问题吗?@MartinSmith您是否对其进行参数化,如果您从文本框中获取一些内容并连接以截断表,则这是不安全的。更安全的是,如果控件是一个组合,或者列表框,如果它是对照表列表进行检查的,等等。在这里,我们严格地处理击败一个扫描工具的问题。为什么您要试图击败一个您自己运行的扫描工具?如果您认为静态代码分析不值得,或者您已经在上下文中对其进行了评估并发现它是安全的,请不要运行静态代码分析。请使用标记为安全的任何方法。让代码变得非常模糊,这样就没有人能看到它的功能,这不是一个好主意solution@MartinSmith让我们谈谈目前的情况。唯一或多或少安全的方法是,当您在前端获得一个带有某个ID的列表时,将其传递到后端,然后对照(比如)一个表进行检查。不是信息架构表,而是保存此id和实际tuncate语句的自定义表。而且,这个Id最好是某个Guid。现在,扫描工具会抱怨所有这些事情,但你需要这个,句号。这些工具抱怨您的变量称为password或pwd。所以是的,我们称之为p_zz4rd或类似的东西,只是为了让工具停止呜呜声,这不是在使用模糊性来消除代码分析发现的完全合法的安全问题吗?@MartinSmith您是否对其进行参数化,如果您从文本框中获取一些内容并连接到截断表,这是不安全的。更安全的是,如果控件是一个组合,或者列表框,如果它是对照表列表进行检查的,等等。在这里,我们严格地处理击败一个扫描工具的问题。为什么您要试图击败一个您自己运行的扫描工具?如果您认为静态代码分析不值得,或者您已经在上下文中对其进行了评估并发现它是安全的,请不要运行静态代码分析。请使用标记为安全的任何方法。让代码变得非常模糊,这样就没有人能看到它的功能,这不是一个好主意solution@MartinSmith让我们谈谈目前的情况。唯一或多或少安全的方法是,当您在前端获得一个带有某个ID的列表时,将其传递到后端,然后对照(比如)一个表进行检查。不是信息架构表,而是保存此id和实际tuncate语句的自定义表。而且,这个Id最好是某个Guid。现在,扫描工具会抱怨所有这些事情,但你需要这个,句号。这些工具抱怨您的变量称为password或pwd。所以,是的,我们称之为p_zz4rd或类似的东西,只是为了让工具停止抱怨