0

I have a simple stored procedure with one parameter @Name which I want to replace with another variable.

I am actually looking for SQL injection character and if name contains -- then it should replace it with blank. The stored procedure shown below, it is executing without an error, but not replacing the string for example let is say user searches for EXEC John'''select * FROM TEST2 -- which has SQL injection statement in it

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

Updated stored procedure:

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 --

In the second stored procedure, I am always able to inject SQL - not sure it is my system?

19
  • 1
    I think this might be an xy question, as there is no chance of injection in the small SQL statement you have provided. if you're looking for avoid SQL Injection, then post what you're really doing and we can help you with that using a way that isn't trying to avoid the problem using REPLACE. Commented Feb 21, 2018 at 10:01
  • No amount of "sanitization" is going to prevent SQL injection. If you want to search by name, make the client provide the pattern. On the other hand what you typed will scan the entire table without using any index. Use full text searching instead Commented Feb 21, 2018 at 10:01
  • @Larmu, This is the mis conception we have about store procedure they dont give us complete protection about SQL Injection, above SP is vunrable Commented Feb 21, 2018 at 10:04
  • 1
    You may be calling the stored procedure incorrectly. Specifically, you should use whatever your client library has to supply and fill parameters. If you execute the stored procedure manually from T-SQL, you have to do escaping for the literal yourself. If you do, however, the procedure itself has no injection problem: EXEC GetStudentDetails @name='John''''''select * FROM TEST2 --' works fine (and returns nothing). Not only is replacing the text inside the procedure pointless, it would do nothing to prevent problems from misquoting the call. Commented Feb 21, 2018 at 10:45
  • 1
    Considering that we think the problem, now, might be your application, not your SP, you need to post the code you're using to run the SQL (in your application) and tag the relevant language. if the application is suffering injection, then no amount of changes to the SP will fix the problem; much like closing the barn door doesn't help after the horse has bolted. Commented Feb 21, 2018 at 11:08

1 Answer 1

2

As it stands, we can't answer the question, as, well there isn't a question applicable for information we're been provided. There is no risk of injection in the SP we have, thus, there is not answer on how to avoid it.

Anyway, instead, what i'm going to do is show firstly why that SP isn't subject to injection and then change it so it would be, and how the limited "fix" in it could easily be avoided.

Firstly, let's start with a simple table and data (I strongly suggest running any following scripts in a Sandbox environment!):

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

OK, and now let's create your SP (amended for our object). and then do some tests:

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 ''';

No injection. Great! Ok, now for an SP that could suffer injection:

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

So, how could you avoid this? Well, Parametrise your dynamic 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

Dynamic objects bring another level to this, however, I'll only cover this if required; as it stands (like I said at the start) the question asked can't happen for the scenario we have.

Clean up:

DROP TABLE Injection2;
DROP PROC ParamSearch;
DROP PROC InjectionSearch;
DROP PROC NonInjectionSearch;
DROP TABLE InjectionReady;
Sign up to request clarification or add additional context in comments.

7 Comments

You are creating Parameterised SP
@Learning Yes, I did. That's also what you have. CREATE PROCEDURE GetStudentDetails @Name nvarchar(300).... @Name is a parameter and your query is parametrised: SELECT * FROM TABLENAME WHERE Name LIKE N'%'+ @Name +'%'. Again @Name is a parameter. I have no idea what you are trying to say with this comment.
My simple object in this store procedure is to sanitized the parameter before i use it in the query but it is not working i tried following also DECLARE @SafeSearchItem nvarchar(30); SELECT @SafeSearchItem = REPLACE(@Name,N'--',N'') SET @SafeSearchItem = REPLACE(@Name,N'--',N'')
If i use Replace to remove -- from parameter then query will generate error & will not exceute it but in my case it is always executing the injected query also. that part is driving me crazy
@Learning As I've said in my comment on the question, I think the problem is your application. The SP you've posted in your Question is not subject to SQL injection, as I have demonstrated in this answer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.