Wednesday, September 12, 2007

Classic ASP Application Security

In today’s world security is everything! That’s why I’ll take you through some basic ways to secure your Classic ASP web application.

1. Database Security

The First thing you need to do is secure your Access Database. Since Access databases can be easily downloaded from the Internet it is always smart practice to put the database in the root directory of the website. This way the Access database won’t be able to be downloaded and you will still be able to access to the database. Below is an example of Database Security.



This is a sample of website directory. Now the site Folder holds your entire site. This includes the Home page, images, and various other pages. Now as you see the database is located outside of the actual site. In order to get this to work you need the URL pointed to the site folder. To connect to the database use the following code.


dbconn = "PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE="
dbconn = dbconn & Replace(server.mappath("/"),"website","") & "/database.mdb"
set Conn = server.createobject("adodb.connection")
Conn.open dbconn

2. Login Interface Security Permissions

Some applications that you create will require multiple Interfaces. This includes a Manager Interface and Employees Interface. You don’t want the Employees to have the same access as the Manager so you need to create multiple interfaces. I will show you an example below.


The first thing to do is build a database and put it into the root of your website. Following that, open your database and design the tables. Below is the Logins table for this project:


Obviously, the Logins table would require a Username and a Password column, however we also need third column, Status, which would be used to determine the permissions of any particular user. For example, a user with the status of "Manager" would be able to view all information, whereas a user with the status of "Employee" would only be able to see their information.

You now want to create the first page called index.html


<HTML>
<HEAD>
<TITLE>Login</TITLE>
</HEAD>
<BODY>
<FORM ACTION="login.asp" METHOD="post">
<TABLE BORDER="0">
<TR>
<TD VALIGN="Top">Username:</TD>
<TD VALIGN="Top"><INPUT TYPE="text" NAME="txtUsername"></TD>
</TR>
<TR>
<TD VALIGN="Top">Password:</TD>
<TD VALIGN="Top"><INPUT TYPE="password" NAME="txtPassword"></TD>
</TR>
<TR>
<TD VALIGN="Top"></TD>
<TD VALIGN="Top"><INPUT TYPE="submit" VALUE="Login"></TD>
</TR>
</TABLE>
</FORM>
</BODY>
</HTML>

It is very important that you use the POST method to send the login data, not GET, as users would be able to see passwords in the client's browser history, amongst other things that would pose a major security threat.

The next file that needs to be created is login.asp, which will process the login information and set the login state. Here's the code.


<%
‘-------------------------------------------Get Form Fields--------------------------------‘
txtUsername = request.form("txtUsername ")
txtPassword = request.form("txtPassword ")
‘--------------------------------------------Connect to Database-------------------------‘
dbconn = "PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE="
dbconn = dbconn & Replace(server.mappath("/"),"website","") &amp;amp;amp;amp;amp;amp; "/database.mdb"
set Conn = server.createobject("adodb.connection")
Conn.open dbconn
‘-------------------------------------------SQL Statement---------------------------------‘
sqlstr = "SELECT Username,Password,Status FROM logins WHERE Username='" & txtUsername &amp;amp;amp;amp;amp;amp; "' AND txtPassword ='" & txtPassword &amp;amp;amp;amp;amp;amp;"'"
set rs = Conn.execute(sqlstr)
‘-----------------------------------------Check if user exists---------------------------------‘
if rs.bof and rs.eof then
response.write "<h2><br>Acces denied,sorry.<br>Return to the login screen and try again.</h2>"
else
‘---------------------------User Exists we will now redirect to Interface-----------------‘
Status = rs("Status")
if Status = "Manager" then
‘--------------------------------------------Manger Interface---------------------------------‘
response.write "<h2>Welcome!<br>Click <a href='manager/index.asp'><u>here</u></a> to enter</h2>"
else
‘----------------------------------------------Employee Interface----------------------------‘
response.write "<h2>Welcome!<br>Click <a href='employee/index.asp'><u>here</u></a> to enter</h2>"
end if
end if
%>

The script is fairly basic and simply opens a database, requests a recordset, checks to see if it's empty or not using the EOF(End of Recordset) property (which is true if the recordset is empty), returns errors if appropriate, and allows the user to click to the next page. The next page will take the user to the appropriate interface.

This is part 1 of creating a Secure Classic ASP Web Application. If you have any questions please post them below.

AddThis Social Bookmark Button

2 comments:

Josh said...

Thanks for the great post. Another way is to use the hiddeninput flag. Such as:

(script)
If Request("hiddenInput") = "true" Then
If rs.bof and rs.eof Then
response.Write("Access denied")
Else
response.Redirect("welcome.asp")
End If
End If
(/script)
"
And just include this under the submit button:
(html)input type = "hidden" name = "hiddenInput" value = "true" (/html)

James Knowles said...

You should still validate the inputs in the database. Otherwise when you take your access database into SQL Server. Which happens more often than not, you have a perfect SQL injectable application.