Take the 2-minute tour ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

Is it true that stored procedures prevent SQL injection attacks against PostgreSQL databases? I did a little research and found out that SQL Server, Oracle and MySQL are not safe against SQL injection even if we only use stored procedures. However, this problem does not exist in PostgreSQL.

Does the stored procedure implementation in PostgreSQL core prevent SQL injection attacks or is it something else? Or is PostgreSQL also susceptible to SQL injection even if we only use stored procedures? If so, please show me an example (e.g. book, site, paper, etc).

share|improve this question
1  
just a note: postgres doesn't have stored procedure's it has stored functions, there are subtle differences between the two –  xenoterracide Jan 4 '11 at 11:12
    
@xenot can you explain the diff? –  Am1rr3zA Jan 4 '11 at 12:58
    
me? not really wikipedia can though it would also make a good question of it's own IMO. postgres's stored functions serve all the same purposes. –  xenoterracide Jan 4 '11 at 14:14
8  
The answers below are pretty good, so I'll add two things. 1 trust nothing that comes back from the user. Just because a field is hidden doesn't mean that the value can be trusted. 2. I've got a book coming out in February where I talk about SQL Injection (among other things). The book is for SQL Server, but the concepts should be similar. amzn.to/hAPaEd –  mrdenny Jan 5 '11 at 1:31
    
To prevent SQL injection. You must check all input parameters within stored functions one by one. The drawback is to impact your database's performance. So you should do some extra work on application code rather than database. –  Moon_of_father Feb 14 at 7:10

5 Answers 5

up vote 50 down vote accepted

No, stored procedures do not prevent SQL injection. Here's an actual example (from an in-house app someone created where I work) of a stored procedure that unfortunately permits SQL injection:

CREATE PROCEDURE [dbo].[sp_colunmName2]   
    @columnName as nvarchar(30),
    @type as nvarchar(30), 
    @searchText as nvarchar(30)           
AS
BEGIN
    DECLARE @SQLStatement NVARCHAR(4000)
    BEGIN
        SELECT @SQLStatement = 'select * from Stations where ' 
            + @columnName + ' ' + @type + ' ' + '''' + @searchText + '''' 
        EXEC(@SQLStatement)
    END      
END
GO

The developer's idea was to create a versatile search procedure, but the result is that the WHERE clause can contain anything the user wants, allowing a visit from little Bobby Tables.

Whether you use SQL statements or stored procedure doesn't matter. What matters is whether your SQL uses parameters or concatenated strings. Parameters prevent SQL injection; concatenated strings allow SQL injection.

share|improve this answer
3  
Very good point! –  jcolebrand Feb 9 '11 at 20:38
2  
+1 : I've also seen some stored procedures that build the string so they can alter the fields being selected, or even the table being selected from. –  Joe Feb 10 '11 at 2:09
7  
Good example. +1 for Little Bobby Tables reference. –  Joel Brown Sep 12 '11 at 19:27
    
+1 for very cool answer. –  Soner Gönül Dec 18 '12 at 22:57

Yes, to some extend.
Stored Procedures alone will not prevent SQL Injection.

Let me first quote about SQL Injection from OWASP

A SQL injection attack consists of insertion or "injection" of a SQL query via the input data from the client to the application. A successful SQL injection exploit can read sensitive data from the database, modify database data (Insert/Update/Delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file present on the DBMS file system and in some cases issue commands to the operating system. SQL injection attacks are a type of injection attack, in which SQL commands are injected into data-plane input in order to effect the execution of predefined SQL commands.

You have to sanitize user inputs and do not concatenate SQL Statements, even if you are using Stored Procedure.

Jeff Attwood explained consequences of concatenating sql in "Give me parameterized SQL, or give me death"

Following is the interesting cartoon which comes to my mind whenever I hear SQL Injection alt text I think you got the point :-)

Have a look at SQL Injection Prevention Cheat Sheet, prevention methods are neatly explained...

share|improve this answer
    
Beat me to it :) –  Brian Ballsun-Stanton Jan 4 '11 at 9:10
    
@Brian Ballsun-Stanton - :) –  Coder Hawk Jan 4 '11 at 9:13
    
Epic comic! +1 for it and Jeff's post about parametrized SQL –  BrunoLM Jan 5 '11 at 13:34
    
Superb!! +1 for the cartoon.Never would i forget SQL Injection :) –  balu Jan 14 '11 at 8:34

SQL-Injection attacks are those where untrusted input is directly appended queries, allowing the user to effectively execute arbitrary code, as illustrated in this canonical XKCD comic.

Thus, we get the situation:

userInput = getFromHTML # "Robert ') Drop table students; --"

Query = "Select * from students where studentName = " + userInput

Stored Procedures are, in general, good defenses against SQL injection attacks because the incoming parameters are never parsed.

In a stored procedure, in most DBs (and programs, don't forget that precompiled queries count as stored procedures) look like the following:

 

create Stored procdure foo (
select * from students where studentName = :1
);

Then, when the program desires access, it calls foo(userInput) and happily retrieves the result.

A stored procedure is not a magical defense against SQL-Injection, as people are quite able to write bad stored procedures. However, pre-compiled queries, be they stored in the database or in the program, are much more difficult to open security holes in if you understand how SQL-Injection works.

You can read more about SQL-Injection:

share|improve this answer
5  
+1 for code, and a link to how to attack your own code. –  xenoterracide Jan 4 '11 at 11:13
    
+1 "if you understand how SQL-Injection works" :) –  bsoist Jan 4 '11 at 15:37
1  
"How to attack your own code" site. Apparently passwords are stored in plaintext there. –  Matthew Schinckel Jan 6 '11 at 10:26

String concatenation is the cause of SQL Injection. This is avoided using parametrisation.

Stored procedures add an additional layer of security by enforcing invalid syntax when you concatenate, but are not "safer" if you use, say, dynamic SQL in them.

So, your code above is caused by concatenation of these strings

  • exec sp_GetUser '
  • x' AND 1=(SELECT COUNT(*) FROM Client); --
  • ' , '
  • monkey
  • '

This gives invalid syntax, luckily

Parametrising it would give

exec sp_GetUser 'x'' AND 1=(SELECT COUNT(*) FROM Client); --' , 'monkey'

This means

  • @UserName = x' AND 1=(SELECT COUNT(*) FROM Client); --
  • @Password = monkey

Now, in the code above you'll get no rows because I assume you have no user x' AND 1=(SELECT COUNT(*) FROM Client); --

If the stored proc looked like this (using concatenated dynamic SQL), then your parametrised stored proc call will still allow SQL Injection

...
SET @sql = 'SELECT userName from users where userName = ''' + 
               @UserName + 
               ''' and userPass = ''' +
               @Password +
               ''''
EXEC (@sql)
....

So, as demonstrated, string concatenation is the main enemy for SQL injection

Stored procedures do add encapsulation, transaction handling, reduced permissions etc, but they can still be abused for SQL injection.

You can look on Stack Overflow for more about parametrisation

share|improve this answer

"SQL injection attacks happen when user input is improperly encoded. Typically, the user input is some data the user sends with her query, i.e. values in the $_GET, $_POST, $_COOKIE, $_REQUEST, or $_SERVER arrays. However, user input can also come from a variety of other sources, like sockets, remote websites, files, etc.. Therefore, you should really treat everything but constants (like 'foobar') as user input."

I've been investigating thoroughly on this subject recently and would like to share with others quite interesting material, thus, making this post more complete and instructive for everyone.



From YouTube


From Wikipedia


From OWASP


From PHP Manual


From Microsoft and Oracle


Stack Overflow


SQL injection scanner

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.