允许用户传递表名和列名,同时防止SQL注入

时间:2016-11-09 16:10:14

标签: c# sql asp.net sql-server

我有一个(Intranet)网页(ASP.NET C#),它允许用户在SQL-Server中的特定数据库上创建表,表名和列名是自由文本字段,并确定实际结构通过几个下拉菜单。我知道将create table语句传递为纯字符串与我的文本框中的文本连接,这很容易被SQL注入。鉴于我传递的是不存在的db对象的实际名称而不是参数,除了在连接字符串之前检查每个文本框是否包含非法字符之外,还有什么方法可以防止注入的可能性吗?

1 个答案:

答案 0 :(得分:1)

这是QUOTENAME()创建的解决方案。您将列和表名称作为参数传递到QUOTENAME(),然后使用它的输出在动态SQL查询中表示数据库中的对象。

//The evil name tries to expliot code like:
//  set @sql = N'CREATE TABLE [' + @tablename + N'] (Foo int)'
var evilName = "someName] (Foo int); Drop table students --";

var query = @"
declare @sql as nvarchar(max)
set @sql = N'CREATE TABLE ' + QUOTENAME(@tablename) + N' (Foo int)'
exec sp_executesql @sql
";
using(var connection = new SqlConnection(ConnectionString))
using(var command = new SqlCommand(query, connection))
{
    command.Parameters.Add("@tablename", SqlDbType.NVarChar, 128).Value = evilName ;
    connection.Open();
    command.ExecuteNonQuery();
}

将在服务器上执行的查询将是

CREATE TABLE [someName]] (Foo int); Drop table students --] (Foo int)

创建一个具有有效表名的表,并且不会删除其他表。

enter image description here