In the below sample code, Table Name is an input parameter. In this case, how can I avoid SQL injection using sp_executesql
. Below is the sample code, I am trying t
You could first check if the parameter value is indeed a table name:
ALTER PROC Test @param1 NVARCHAR(50),
@param2 INT,
@tblname NVARCHAR(100)
AS
BEGIN
DECLARE @sql NVARCHAR(1000)
IF EXISTS(SELECT 1 FROM sys.objects WHERE type = 'u' AND name = @tblname)
BEGIN
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
END
If the passed value is not a table name your procedure won't do anything; or you could change it to throw an error. This way you're safe if the parameter contains a query.
You can enclose the table name in []
SET @sql= N' select * from [' + @tblname + '] where name= @param1 and id= @param2';
However, if you use a two-part naming convention e.g dbo.tablename
, you have to add additional parsing, since [dbo.tablename]
will result to:
Invalid object name [dbo.tablename].
You should parse it so that it'll be equal to dbo.[tablename]
.