允许用户传递表名和列名,同时防止SQL注入
我有一个(Intranet)网页(ASP.NET C#),它允许用户在SQL-Server中的特定数据库上创建一个表,表名和列名是自由文本字段,实际结构由几个确定下拉菜单。 我知道传递create table语句是因为纯文本字符串与我的文本框中的文本连接在一起容易受到SQL注入的影响。 鉴于我传递的是不存在的db对象的实际名称而不是参数,除了在连接字符串之前检查每个文本框是否包含非法字符之外,还有什么方法可以防止注入的可能性?
这就是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)
它创建一个具有有效表名的表,并且不会删除我的其他表。