我有一个带有一个参数@Name
的简单存储过程,我想用另一个变量替换它。
我实际上在寻找SQL注入字符,如果名称包含--
,那么它应该用空格替换它。下面显示的存储过程,它正在执行而没有错误,但是没有替换字符串,例如,让我们说用户搜索其中包含SQL注入语句的EXEC John'''select * FROM TEST2 --
CREATE PROCEDURE GetStudentDetails
@Name nvarchar(300)
AS
BEGIN
SET NOCOUNT ON;
SELECT @Name = REPLACE(@Name ,'--','');
SET @Name = REPLACE(@Name ,'--','');
SELECT *
FROM TABLENAME
WHERE Name LIKE N'%'+ @Name +'%'
END
更新了存储过程:
CREATE PROCEDURE GetStudentDetails
@Name nvarchar(300)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @SafeSearchItem nvarchar(30);
SELECT @SafeSearchItem = REPLACE(@Name ,N'--',N'')
SET @SafeSearchItem = REPLACE(@Name ,N'--',N'')
SELECT *
FROM TABLENAME
WHERE Name LIKE N'%'+ @SafeSearchItem +'%'
END
EXEC
EXEC John'''select * FROM TEST2 --
在第二个存储过程中,我总是能够注入SQL - 不确定它是我的系统吗?
答案 0 :(得分:1)
目前我们无法回答这个问题,因为我们还没有提供适用于我们所提供信息的问题。在我们的SP中没有注射风险,因此,没有回答如何避免它。
无论如何,相反,我要做的是首先展示为什么SP不受注射然后改变它所以它会被修改,以及有限的"修复&#34 ;在其中很容易避免。
首先,让我们从一个简单的表格和数据开始(我强烈建议在Sandbox环境中运行以下任何脚本!):
USE Sandbox;
GO
CREATE TABLE InjectionReady (ID int IDENTITY(1,1), SomeText varchar(500));
INSERT INTO InjectionReady
VALUES ('Here is some text'),
('Life is like a box a chocolates'),
('Milk Chocolate is my favourite'),
('Cheese is dairy product'),
('Chocolate is a dairy product'),
('Cows say "moo"!'),
('English Cat says "Meow"'),
('Japanese Cat says "Nyaa"');
GO
好的,现在让我们创建你的SP(为我们的对象修改)。然后做一些测试:
CREATE PROCEDURE NonInjectionSearch @Wildcard nvarchar(100) AS
SELECT @Wildcard = REPLACE(@Wildcard ,N'--',N'');
SET @Wildcard = REPLACE(@Wildcard ,N'--',N'');
SELECT *
FROM InjectionReady
WHERE SomeText LIKE N'%'+ @Wildcard +N'%';
GO
EXEC NonInjectionSearch 'Chocolate';
EXEC NonInjectionSearch '''; DROP TABLE InjectionReady;--';
EXEC NonInjectionSearch '''; DROP TABLE InjectionReady; SELECT ''';
没有注射。大!好的,现在对于可以遭受注射的SP:
CREATE PROCEDURE InjectionSearch @Wildcard nvarchar(100) AS
SELECT @Wildcard = REPLACE(@Wildcard ,N'--',N'');
SET @Wildcard = REPLACE(@Wildcard ,N'--',N'');
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'
SELECT *
FROM InjectionReady
WHERE SomeText LIKE N''%'+ @Wildcard + N'%'';'; --Yes, intentional non parametrisation
PRINT @SQL;
EXEC (@SQL);
GO
EXEC InjectionSearch 'Chocolate';
GO
EXEC InjectionSearch '''; CREATE TABLE Injection1(ID int);--'; --This'll fail
GO
EXEC InjectionSearch '''; CREATE TABLE Injection2(ID int); SELECT '''; --Oh! This worked!
GO
那么,你怎么能避免这种情况呢?好吧,参数化你的动态SQL:
CREATE PROCEDURE ParamSearch @Wildcard nvarchar(100) AS
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'
SELECT *
FROM InjectionReady
WHERE SomeText LIKE N''%'' + @pWildCard +''%'';'; --Yes, intentional non parametrisation
PRINT @SQL;
EXEC sp_executesql @SQL, N'@pWildcard nvarchar(500)', @pWildCard = @Wildcard;
GO
EXEC ParamSearch 'Chocolate';
GO
EXEC ParamSearch '''; CREATE TABLE Injection1(ID int);--'; --Won't inject
GO
EXEC ParamSearch '''; CREATE TABLE Injection2(ID int); SELECT '''; --Oh! this didn't inject either
动态对象为此带来了另一个层次,但是,如果需要,我只会覆盖它;就像它一样(就像我在开始时说的那样),我们所拥有的场景可能会出现问题。
清理:
DROP TABLE Injection2;
DROP PROC ParamSearch;
DROP PROC InjectionSearch;
DROP PROC NonInjectionSearch;
DROP TABLE InjectionReady;