我想使用 T-SQL 创建一个存储过程,该过程基于不易受到 SQL 注入攻击的外部数据动态创建一个表
Posted
技术标签:
【中文标题】我想使用 T-SQL 创建一个存储过程,该过程基于不易受到 SQL 注入攻击的外部数据动态创建一个表【英文标题】:I want to create a stored procedure using T-SQL that dynamically creates a table based on outside data that isn't vulnerable to SQL injection 【发布时间】:2014-10-12 18:19:45 【问题描述】:我有一个表,其中有一列代表我们要创建的表的名称。与另一个表存在外键关系,该表有一列表示所需表的列名(所有数据类型均假定为 nvarchar)。我正在使用存储过程来创建此表。基本上我所做的是从我的表中获取所有相关数据,然后构建一个 SQL 字符串以生成表,最后使用EXEC sp_executesql @CreateTableSQL
。
@CreateTableSQL
是通过这样的字符串连接生成的:
SET @CreateTableSQL = 'CREATE TABLE ' + @TableName + ' (' + @ColumnString + ')';
这让我很容易受到 SQL 注入的攻击。如果有人要使用 @TableName
的值:
C (t int); DROP TABLE MyTable;--
那么这将丢弃 MyTable(不受欢迎)。
有人可以帮我构建这个 SQL 并让它不受注入攻击吗?非常感谢您的帮助。谢谢!
【问题讨论】:
编写一个函数,将@ColumnString 限制为只允许在表名中使用的字符集。 为什么需要像这样动态创建表呢?一旦你不得不求助于动态 sql 来创建表,这也意味着你必须使用动态 sql 来检索数据。这似乎是一个非常糟糕的表现的秘诀。您可以使用 QUOTENAME 来帮助表名,但您的列仍然是一个挑战。 @SeanLange 问我的 PM,哈哈。 【参考方案1】:您可以使用QUOTENAME()
函数,它将在变量(表和列名称)周围强制使用方括号[]
,并且传递给这些变量的任何值都将仅被视为对象名称。
类似......
SET @CreateTableSQL = 'CREATE TABLE ' + QUOTENAME(@TableName)
+ ' (' + QUOTENAME(@ColumnString) + ')';
现在,即使有人将值 C (t int); DROP TABLE MyTable;--
传递给这些变量中的任何一个,整个值 C (t int); DROP TABLE MyTable;--
仍将被视为对象名称。
【讨论】:
以上是关于我想使用 T-SQL 创建一个存储过程,该过程基于不易受到 SQL 注入攻击的外部数据动态创建一个表的主要内容,如果未能解决你的问题,请参考以下文章