小编典典

如何使用sp_executesql避免SQL注入

sql

在下面的示例代码中,表名称是一个输入参数。在这种情况下,如何避免使用进行SQL注入sp_executesql。下面是示例代码,我尝试使用sp_executesql它来避免它,但是它不起作用。谁能告诉我如何纠正它?

ALTER PROC Test @param1  NVARCHAR(50), 
                 @param2  INT, 
                 @tblname NVARCHAR(100) 
AS 
  BEGIN 
      DECLARE @sql NVARCHAR(1000)

      SET @sql= N'  select * from ' + @tblname 
                + ' where name= @param1 and id= @param2';

      PRINT @sql

      EXEC Sp_executesql 
        @sql, 
        N'@param1 nvarchar(50), @param2 int', 
        @param1, 
        @param2; 
  END

EXEC Test 
  'John', 
  2, 
  ' emp; delete from emp where id = 567; select * from emp '

输出:打印消息:

select * from  emp; delete from emp where id = 567; select * from emp  where name= @param1 and id= @param2;

所有输入参数将完全替换,并删除一行。请让我知道如何处理这种情况。


阅读 340

收藏
2021-04-14

共1个答案

小编典典

您可以将表名包含在 []

SET @sql= N'  select * from [' + @tblname + '] where name= @param1 and id= @param2';

但是,如果使用两部分命名约定,例如dbo.tablename,则必须添加其他解析,因为这[dbo.tablename]将导致:

无效的对象名称[dbo.tablename]。

您应该对其进行解析,以使其等于dbo.[tablename]

2021-04-14