views:

366

answers:

8

I'm running through my web app and I'm trying to test various parts of the system to make sure they aren't succeptible to SQL injection.

What are some common sql injection checks I can perform on textboxes/textareas, etc that would be good checks for vulnerability?

I'm not worried about damaging my data as I'm running this on a test bench so it's ok if it kills my server or database.

I'm specifically looking for examples I can use. I'm not really looking for overall techniques, although I hope to cover a variety of different techniques with the examples that I hope to get.

+7  A: 

You might find this site helpful

Daniel Elliott
That is slick. Thanks for the reference this is some great material!
Joseph
+1  A: 

Just make sure you are using SqlParameter objects everywhere (assuming .net), and not concatinating sql queries, and you will be completely safe from SQL Injection.

-- Edit

Some people are saying that using 'Stored Procedures' makes a difference. It doesn't. If you still build the query to execute the stored procedure dynamically, you are at risk:

string sql = "exec spFoo @Hello = '" + helloValue + "'";

The only way to execute a query, with parameters, in a modern language (and specifically .net) is by using SqlParameter class, and specifying the appropriate data types.

Noon Silk
Thanks for your comments. Unfortunately I'm having to deal with legacy pages (ASP), so I'm not able to use .NET constructs. My .NET counterparts utilize SqlParameters and are properly structured. I'm more worried about the ASP pages.
Joseph
ASP has parameters too, IIRC: http://www.webconcerns.co.uk/asp/sqlqueries/sqlqueries.asp
Noon Silk
OP never said application language, but your answer only suggests a solution of a particular application language.
KM
KM: Try reading the comments KM.
Noon Silk
@silky Thanks for the reference. I'm more interested in the testing aspect because I want to make sure the legacy code as it stands is not vulnerable. When I migrate the code, I utilize proper techniques, but that's not really my concern with this question.
Joseph
@silky, I did read the comments. OP asks question with no mention of application language, 2 minutes later you answerd the question with a .NET answer, 8 minutes later OP says they use ASP
KM
@Joseph: No worries. But I would use that style of parameters in ASP, even in legacy code, as it's preferable to attempting to secure it yourself.
Noon Silk
@silky Yeah I would too, but I walked into the app (brownfield project), so whenever I'm tasked on the ASP page I just rewrite it in .NET. However, the pages I haven't gotten to yet are still in ASP and I'm not confident in the way they were built based on what I've seen so far.
Joseph
+6  A: 

If you always use parameterized queries or stored procedures, then you don't have to do any checks.

Never use dynamic SQL, where you build the SQL command based in part on input from the user. That's what requires you to sanitize the input.

John Saunders
@Downvoter: if this is incorrect, then please say why.
John Saunders
+1, this is correct
KM
I downvoted both of you, and elaborated in my post. The use of stored procedures is not relevant.
Noon Silk
I said, "parameterized queries or stored procedures", meaning, "parameterized (queries or stored procedures)". Perhaps I should have emphasized the opposite, "no dynamic SQL".
John Saunders
@silky: how's that?
John Saunders
Ah, yes, well that's not how I read it. It's just a common misconception that stored procedures add anything; and I don't want it to be perpetuated.
Noon Silk
I wasn't the downvoter, but it's only half correct - stored procedures doesn't make a difference either way (except for the fact that the usual implementation of sprocs uses parameters).
Tomas Lycken
@Tomas: note the edit.
John Saunders
let's say you've got a stored proc where you pass in a parameter @id. but in the SP itself, you're actually concatenating @id to the end of 'DELETE FROM Customers where ID = ' and then executing it. you can use SqlParameters and check for "injection" and "bad strings", but because of poor SP design, you've left the door open for someone to type "ID" and wipe your table.
dnord
@silky: note how much better it is to say why you downvoted.
John Saunders
@dnord: Give that a try, with @ID defined as integer. You can't pass a string in that case.
John Saunders
John: I always say when I downvote; but before I responded I edited my own post, so that it potentially be obvious before I did comment :)
Noon Silk
@silky: thanks. You're the only other user here (besides myself) who I know always comments.
John Saunders
+2  A: 

1) if you only use stored procedures (and call them in a paramatized manner) that contain no dynamic SQL you are good to go.
2) if you only use prepared statements in your application language you are good to go.
3) if none of the above, you must do alliciation langauge specific commands to scan your text, but you don't say which application language.

EDIT
morale of the story. never build and execute a SQL sommand in a string if it contains any text given to you by the user. pass the user given text to the sql command as a parameter. SQL injection is the user changing your SQL command by the text they give you.

example:

Query="select * from users where userName='"+givenUserName+"'"

you think Query will be:

 select * from users where userName='your_friend'

but it if givenUserName is

'x';delete from users --

Query will end up being:

select * from users where userName='x';delete from users --'
KM
Thanks for that example. I'm trying "x'; delete from user--" style all over the app. That technique I was aware of =) Have any other ones?
Joseph
use __x' OR 1=1--__ for trying to login when query is: __SELECT * FROM Users Where Login='+string1+' AND password='+string2+'__
KM
A: 

SQL injection checks? As in, strings you should be scared of?

Much better in the long run to

  1. use .NET's SqlParameters (which check themselves for injection shenanigans more completely than you could hope to in ad hoc checks)
  2. avoid dynamic SQL in your SPs (because even parameterized queries can be jacked by unexpected input if you're concatenating strings and then executing them on the back end)
dnord
A: 

Anything with a ' in it.

wefwfwefwe
-1: Please elaborate why that character is important.
John Saunders
-1: Even if you did elaborate, this would still be incorrect - there are more dangers than the ' character, and string sanitizing will never be as safe as parametrization.
Tomas Lycken
It's almost certainly the most common danger and not every query can be paramaterised. Spotting why it's important is left as an exercise for the asker.
wefwfwefwe
Give an example of a query that cannot be parameterized.
John Saunders
Just about any case where you have to drop down to executing dynamic SQL. Try joining to a table in another database where the name of that database is a user supplied variable.
wefwfwefwe
In fact, dynamic sql within a stored procedure is a case where a parameterised query can look safe but isn't...
wefwfwefwe
A: 

You can use parameters in classic ASP as well, using the ASP ADO objects.

Here's a small example:

Dim conn, cmd, SQL, connstr
connstr = "My Connection String"
SQL = "SELECT Username FROM Users WHERE UserID = @UserID"

' Setup Connection and Command objects
Set conn = Server.CreateObject("ADODB.Connection")
conn.ConnectionString = connstr
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.CommandText = SQL

' Create and add the parameter
cmd.Parameters.Append(cmd.CreateParameter("UserID", adParamInput, 50, ID))        

' Execute
cmd.Execute ()

It's been a long time since I wrote any classic ASP, so this code will probably not work as is. However, it gives an idea of how parameters can be used in classic ASP as well to prevent SQL injections.

Tomas Lycken
A: 

The use of parameters is handy, but it is not the only way to protect oneself against SQL injection, nor is it foolproof.

If the stored procedure internally dynamically creates and performs an EXEC() on SQL code, you lose all of that protection. You also lose that protection if you have a single query in your application that includes those fields without using parameters or escaping.

Parameters aren't magic, and you can protect yourself by simply using an escape function when building your SQL:

Public Shared Function StringToSql(ByVal s As String) As String
   If s Is Nothing Then Return "NULL"
   Return "N'" & Replace(s, "'", "''") & "'"
End Function

Usage:

Sql = "INSERT INTO mytable(name) VALUES(" & StringToSql(username) & ")"

Boom. Easy as pie. Even takes care of the nvarchar quoting.

You can convert dates, numbers, GUIDs, etc to strings and pass them to the function above, but you're better off creating separate functions for each data type you use.

There is one caveat: you have to use it every single time you build a query-- every CRUD that includes this data, whether produced at the application layer or generated dynamically inside a stored procedure.

But you have to do the same thing to benefit from parameters! So either way, you have to change your habits and review your code. There is no escaping that (lame pun intended).

richardtallent
Why would you not use parameters in that insert query?
John Saunders