views:

736

answers:

7

Lets say on MySQL database (if it matters).

+3  A: 

No, as you could still use D-SQL in your stored procedures... and validating and restricting your input is a good idea in any case.

Ilya Komakhin
+7  A: 

It depends what your stored procs do. If they dynamically generate SQL based on their parameters, and then execute that SQL, then you're still vulnerable. Otherwise, you're far more likely to be fine - but I hesitate to sound 100% confident!

Jon Skeet
I can't think of a reason for wanting this done in a stored procedure. Interesting to know that it can be done though.
Allain Lalonde
@Allain: Do you mean that you can't see a reason for generating dynamic SQL in a stored procedure, or that you can't see a reason for generating dynamic SQL in a stored procedure using parameters supplied to the procedure?
Michael Madsen
@Michael... must be a client side guy. Thinks of the database as just a broom closet with lots of space for storing the relational representation of his objects.... hehe
Yes, it's a broom closet. Seriously though, doing this kind of thing inside a stored procedure just seems odd. Not that I can't think of some convoluted requirement for it, I just can't think of a situation where this would be easier than constructing it client side then sending it down. Correct me.
Allain Lalonde
An SP allows for more concise PHP/ASP(.NET) code, if, for example, you want to keep old revisions of a record, inserting a new one when you're actually updating an old record. The SP can then figure out what fields refer to your table, and use dynamic SQL to update them with the new record ID.
Michael Madsen
+5  A: 

nope. If you're constructing SQL that invokes a stored procedure you're still a target.

You should be creating parametized queries on the client side.

Allain Lalonde
Every SQL should be in the database. Clients should have a procedures to run queries. Any other way means that there's dependencies on the database structure that the architect is unaware of. Couldn't tell your preferred RDBMS from your website but this is the strong recommendation of Oracle
@Mark: even if all queries are in the database, the client app must run an EXECUTE PROCEDURE statement. SQL injection can occur here, for example if you interpolate an application variable in for the name of the procedure.
Bill Karwin
+14  A: 

You are only immune to SQL injections if you consistenly use parameterized queries. You are nearly immune to SQL injections if you use proper escaping everywhere (but there can be, and has been, bugs in the escaping routines, so it's not as foolproof as parameters).

If you call a stored procedure, adding the arguments by concatenation, I can still add a random query at the end of one of the input fields - for example, if you have CALL CheckLogin @username='$username', @password='$password', with the $-things representing directly concatenated variables, nothing stops me from changing the $password variable to read "'; DROP DATABASE; --".

Obviously, if you clean up the input beforehand, this also contributes to preventing SQL injection, but this can potentially filter out data that shouldn't have been cleaned.

Michael Madsen
+1 for saying stored procedures can secure you, -100 for being a posting hypocrite.
RandyMorris
@RandyMorris: I am not saying that. What I'm saying is that, if you are calling a stored procedure, then it doesn't matter if it's safe or not, unless your call is also safe. In other words, *it's not enough to just use SPs* as you're still susceptible to SQL injection if you're creating the query to call the SP by concatenation, and you're also susceptible if the SP builds a dynamic query and executes it. This is no different from my point in the comment you're thinking of: http://stackoverflow.com/questions/2768692/will-these-security-functions-be-enough-php/2768737#2768737
Michael Madsen
@Michael, thats like saying "downvote for saying a password helps security, it only works if it is not blank."
RandyMorris
+12  A: 

No, you will not be completely safe. As others have mentioned, parameterized queries are always the way to go -- no matter how you're accessing the database.

It's a bit of an urban legend that with procs you're safe. I think the reason people are under this delusion is because most people assume that you'll call the procs with parameterized queries from your code. But if you don't, if for example you do something like the below, you're wide open:

SqlCommand cmd = new SqlCommand("exec @myProc " + paramValue, con);
cmd.ExecuteNonQuery();

Because you're using unfiltered content from the end user. Once again, all they have to do is terminate the line (";"), add their dangerous commands, and boom -- you're hosed.

(As an aside, if you're on the web, don't take unfiltered junk from the query string of the browser -- that makes it absurdly easy to do extremely bad things to your data.)

If you parameterize the queries, you're in much better shape. However, as others here have mentioned, if your proc is still generating dynamic SQL and executing that, there may still be issues.

I should note that I'm not anti-proc. Procs can be very helpful for solving certain problems with data access. But procs are not a "silver-bullet solution to SQL injections.

John Rudy
+2  A: 

Stored Procedures are not a guarantee, because what is actually vulnerable is any dynamic code, and that includes code inside stored procedures and dynamically generated calls to stored procedures.

Parameterized queries and stored procs called with parameters are both invulnerable to injection as long as they don't use arbitrary inputs to generate code. Note that there is plenty of dynamic code which is also not vulnerable to injection (for instance integer parameters in dynamic code).

The benefits of a largely (I'm not sure 100% is really possible) stored procs-based architecture, however, is that injection can even be somewhat defended against (but not perfectly) for dynamic code at the client side because:

Only EXEC permissions are granted to any user context the app is connecting under, so any SELECT, INSERT, UPDATE, DELETE queries will simply fail. Of course, DROP etc should not be allowed anyway. So any injection would have to be in the form of EXEC, so ultimately, only operations which you have defined in your SP layer will even be available (not arbitrary SQL) to inject against.

Amongst the many other benefits of defining your database services as a set of stored procedures (like any abstraction layer in software) are the ability to refactor your database underneath without affecting apps, the ability to better understand and monitor the usage patterns in your database with a profiler, and the ability to selectively optimize within the database without having to deploy new clients.

Cade Roux
+2  A: 

Additionally, consider using fine grained database access, (also called generally Role Based Access Control) The main user of your database should have exactly the permissions needed to do its job and nothing else. Don't need to create new tables after install? REVOKE that permission. Don't have a legitimate need to run as sysdba? Then don't! A sneaky injection instructing the user to "DROP DATABASE" will be stymied if the user has not been GRANTed that permission. Then all you need to worry about is data-leaking SELECT statements.

Omniwombat