Prepared Statements and sanitizing data - asp-classic

When using a prepared statement with Classic ASP such as this:
SQL = "SELECT user_name, user_sign_up_date FROM tbl_users WHERE this = ? AND id = ? "
Set stmt01 = Server.CreateObject("ADODB.Command")
stmt01.ActiveConnection = oConn
stmt01.Prepared = true
stmt01.commandtext = SQL
stmt01.Parameters.Append stmt01.CreateParameter("#x1", adVarChar, adParamInput, 255, card_pwd)
stmt01.Parameters.Append stmt01.CreateParameter("#x2", adInteger, adParamInput, , this_id)
set myRS = stmt01.Execute
Apart from doing the usual sense checking to e.g. make sure that a number is a number and so on, does the process of using this kind of Parameterised Statement mean that I no longer have to worry about, e.g. for a varchar or text field, sanitising the data input from users - e.g. would I no longer need to use a function to push everything input by a user through Server.HTMLencode?
I'm not sure if the parameterised statement route means I can be less strict re. sanitizing user data now?

You are conflating two different types of sanitisation. SQL parameterization prevents the “Bobby Tables” vulnerability — a maliciously written bit of data that tricks SQL into ending the current query and executing a separate query of the attacker’s choosing.
https://bobby-tables.com
Even with SQL parameters, an attacker could try to run a script on your page by (for example) entering “alert(‘Gotcha!’)” in a field. Display the field data on an HTML page and that script is written out and executed. To prevent that you use Server.HTMLencode

If your concern is SQL injection attacks then parameterization should remove the possibility of the SQL string being tampered with because the values are supplied at execution time.

Others are correct that you don't need to worry about the contents of the parameters. You do have to worry about the length of strings. I would pass Left(card_pwd, 255) to CreateParameter() to avoid exceptions crashing your script. I tend to not worry about calling IsNumeric() on integer parameters but that might be worthwhile (try passing nonsense and see what happens).

Related

Output params and Stored Procedure

I've googled but none of the solutions seems to work for me!
I have a SPROC in SQL Server which has an input param and also an output parameter being set within the SPROC.
using classic ASP, I want to retrieve the value of that output parameter but nothing seems to get set (but I can see the output parameter working correctly when executing in the SQL Server Management Studio)
OpenConnection
Set cmdTemp = Server.CreateObject("ADODB.Command")
cmdTemp.CommandType = 4 'adCmdStoredProc
Set cmdTemp.ActiveConnection = dbConn
cmdTemp.CommandText = "GetCerts"
cmdTemp.Parameters.Refresh
cmdTemp.Parameters(1) = "ABC123"
cmdTemp.Parameters(2).Direction = 2 'Output
Set reader = cmdTemp.Execute
Response.Write(cmdTemp.Parameters(2)) ' Nothing is displayed at all.
CloseConnection
I tried using the named parameters approach but always got an error saying that the parameters are out of range, wrong arguments or wrong type (Something similar to this).
Really... getting a headache. I just want the OUTPUT param value set from the SPROC (2nd parameter in the SPROC)
Check for errors:
Set reader = cmdTemp.Execute
If Err.number <> 0 or dbConn.Errors.Count <> 0 Then
'Do something to handle the error
End If
Do you have permissions to execute the stored procedure? i.e. the credentials of the ASP user...
Execute Stored Procedure from Classic ASP
It seems after a long long investigation that what I am trying to do is not possible (but it is in .NET). Seems I need to execute the command twice, first time getting the output parameters values then the next time to display the results. Awful. Praise .NET!
Most collections in the COM world use zero-based indexing. Try using Parameters(0) as the input parameter and Parameters(1) as the output parameter.

Need a quick and simple classic asp page to query records from a sql server database

I know this seems elementary, but I have been looking for 2 days and all i find is snippets that dont work. I am simply trying to have a web page dynamically display the contents of a table with 4 columns.
Need by tomorrow!
Help!
Thank you!
Here's the simplest way to do it. This is assuming your server is SQL Server. If not, head to http://connectionstrings.com and look up the specifics for your server. That site is awesome and I find myself on it all the time.
set rs = server.CreateObject("ADODB.Recordset")
rs.open "select col1 from table1", "provider=sqloledb.1;uid=user;pwd=password;database=database;Server=server;"
do while rs.EOF = false
response.write rs("col1")
rs.MoveNext
loop
What's going on here is we're using Microsoft's ADO database library. I'm creating a Recordset object and calling its open method. Provided to the open method are the sql statement I want to execute and the specifics on how to connect to that database. The specifics on how to connect to the database is commonly referred to as a "Connection String." The site mentioned above is an invaluable resource in figuring out exactly what this should look like. 99% of the time, any problems I've run into have been an invalid connection string. Once opened, I loop through the returned records in the while loop and write out the data to the page.
DON'T FORGET THE CALL TO rs.MoveNext!!! I've done this a handful of times over the years and you'll wind up with an infinite loop.

classic ASP protection against SQL injection

I've inherited a large amount of Classic ASP code that is currently missing SQL injection protection, and I'm working on it. I've examined in detail the solutions offered here: Classic ASP SQL Injection Protection
On the database side, I have a Microsoft SQL server 2000 SP4
Unfortunately stored procedures are not an option.
After studying php's mysql_real_escape_string ( http://www.w3schools.com/php/func_mysql_real_escape_string.asp ) , I've replicated its functionality in ASP.
My question(s) are:
1) Does Microsoft SQL server 2000 have any other special characters that need to be escaped that are not present in MySQL ( \x00 , \n , \r , \ , ' , " , \x1a )
2) From an answer in Can I protect against SQL Injection by escaping single-quote and surrounding user input with single-quotes? I read "One way to launch an attack on the 'quote the argument' procedure is with string truncation. According to MSDN, in SQL Server 2000 SP4 (and SQL Server 2005 SP1), a too long string will be quietly truncated."
How can this be used for an attack (I really can't imagine such a scenario) and what would be the right way of protecting against it?
3) Are there any other issues I should be aware of? Any other way of injecting SQL?
Note: A 30-min internet search said that there are no libraries for classic ASP to protect against SQL injection. Is this so, or did I really fail at a basic task of searching?
The best option is to use parameterized queries. On how that is done, you must check out:
SQL Injection Mitigation: Using Parameterized Queries
In PHP also, the PDO (and prepared statements) allows developers to use parameterized queries to avoid sql injection.
Update
Yes you can specify parameters in WHERE clause and for that you can use ADODB.Command object like below example:
' other connection code
set objCommand = Server.CreateObject("ADODB.Command")
...
strSql = "SELECT name, info FROM [companies] WHERE name = ?" _
& "AND info = ?;"
...
objCommand.Parameters(0).value = strName
objCommand.Parameters(1).value = strInfo
...
For more information, see the article link that I have posted above or you may want to research a little more on the topic if you want.
I use two layers of defense:
create a 'cleanparameter' function, and every call that gets from querystring or form values, use it calling that function. The function at the very least should replace simple quotes, and also truncate the string to a value you pass. So, for example, if the field can't be longer than 100 chars, you would call it like x = cleanparameter(request.querystring("x"), 100). That's the first line of defense
Use parameterized queries to run SQL instructions

Insert using ADO with classic ASP

' Setting variables
Dim con, sql_insert, data_source
data_source = "project_db"
sql_insert = "insert into cart ( UserID,Count,ProductName,ProductDescription,ProductPrice) values ('"&user_id&"','"&count&"','"&product_name&"','"&product_description&"','"&product_price&"')"
' Creating the Connection Object and opening the database
Set con = Server.CreateObject("ADODB.Connection")
con.Open data_source
' Executing the sql insertion code
con.Execute sql_insert
' Done. Now Close the connection
con.Close
Set con = Nothing
AS you can see , it is a simple code . and it worked in my local host for 5 or 6 times. but now it didn't work. What's the problem ? I think , it's about my database or memory. i setup 2 different iis in 2 different computer and they behave same... please help..
Thanks
Does it give you any error message? Make sure all the values you are inserting actually have values and are not blank or null. You can check this by response.write all the values and then response.end to see if they contain any values.
I bet it's a data-dependent error. You should be using ADO parameters. Those will ensure that extraneous SQL-unfriendly characters in your input do not adversely affect your database operation. You should also use them to guard against SQL injection issues.
Some docs are available at http://msdn.microsoft.com/en-us/library/ms675869(VS.85).aspx, and you can google for "ADO parameters" and find many relevant examples.
I believe that 'data_source' should be focused on (and agreed with Tom Gullen as regards to error messages. Always use Option Explicit at the top of your pages).
con.Open either expects some DSN parameters or a database connection string to be passed within 'data_source'.
Examples, respectively :
data_source = DSN_Database, DSN_User, DSN_Password
(these 'DSN_' parameters are found/set in your DSN configuration)
OR :
data_source = "Driver={SQL Server};Server=server.domain.com;Database=project_db;uid=MyUser;pwd=MyPass;""

Classic ASP SQL Injection

I recently inherited a classic asp website with a ton of inline SQL insert statements that are vulnerable to SQL injection attacks.
These insert statements are executed via the ADO command object.
Will setting the ADO Command Object's Prepared property to true ensure that the query is parameterized before execution, thus mitigating the risk of SQL injection?
This Link should prove useful.
Classic ASP SQL Injection Protection
No, if you build a SQL string with values that you get directly from "outside", then a "prepared statement" will not help you.
a
sSQL = "SELECT * from mytable where mycolumn = '" + querystring("value") + "'"
is still asking for trouble.
The only way to solve this is by using parameters in your query.
You can also look at an asp classic open source project called 'Owasp stinger'. That not only helps with Sql injection, but header injection and lots of other security issues common to all web apps.
http://www.owasp.org/index.php/Classic_ASP_Security_Project
Here's another good link and example.
http://blogs.iis.net/nazim/archive/2008/04/28/filtering-sql-injection-from-classic-asp.aspx
In the past we just created a couple functions to handle any outside input for SQL injections and XSS. Then slowly we converted all the inline SQL to stored procedures.
What I would suggest you do is write a function to sanitize the user input, then run all the request variables through that. When I wrote mine I did stuff like:
escape single quotes,
remove ; and other special characters and
make sure that you couldn't -- (comment) out the end of the statement.
Most SQL injection would try something like ' or 1=1 or a='
so the SQL code would be :
SELECT * from mytable where mycolumn = '' or 1=1 or a=''
So escaping single quotes is the real big one you need to worry about.

Resources