ASP Login Advice

Soldato
Joined
8 Oct 2005
Posts
4,184
Location
Midlands, UK
Hi,

Am using 'classic' asp linked to a SQL database with a usernames/passwords table etc. I have a private area of the site where a user needs to login to view content.

Have read several tutorials on this and some recommend using a querystring to redirect to the private page (can't see how this is secure though????) and others say use sessions.

So, after a bit of reading I'm thinking of running the entered user/pass against my database to find a matching record E.g.
Code:
SELECT * FROM Users
WHERE User='entered-user' AND Pass='entered-password'
and then setting some sort of session E.g. Session("Authd") = "Yes". I'll then check that this session is set on every secure page, if not redirect.

When a user hits a log out link, i'll kill the session E.g Session("Authd").Abandon - iirc

As these several pages i need to secure are fairly sensitive is this the most secure way to achieve my aim?



I also read a bit about how bad it is to store paswords in plain text in my db. Now i read an excellent tutorial on how to do this in php, but can't seem to find anothing similar in asp? Can any kind soul provide a good place to start.
 
Personally I always use sessions for private logins in ASP. The way you mentioned of setting a session var at login and then checking for it at the head of each private page is the best method. Also, if you want to have persistant logins, cookies are the way to go for that - but don't store the ids/uid/pwds in plain text always encode them.

And like you say you should always encode passwords whenever you use them ina databse in case someone gets their mits on the db itself - here's the best base64 encode/decode routine I've found. If anyone else has one, feel free to post it up.

Code:
	' -- BASE64 KEY --
	const C_Encode_Key = "iLikeP13"
	
	response.write(encode("hi suarve"))


        ' =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= \/ \/ \/ \/ =-
	'	BASE64 ENCRYPTION!
	' =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
		const BASE_64_MAP_INIT ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
		dim nl
		   dim Base64EncMap(63)
		   dim Base64DecMap(127)
		initCodecs
	
	
		' Encode - ENCODE THE QUERYSTRING ====================================================
		public function Encode(p_QS)
			Encode = base64Encode(SimpleXor(p_QS, C_Encode_Key))
		end function
		' ======================================================================================
		
	
	
		' Decode - DECODE THE QUERYSTRING ====================================================
		public function Decode(p_QS)
			Decode = SimpleXor(Base64Decode(p_QS), C_Encode_Key)			
		end function
		' ======================================================================================

	
	
		' INITCODECS - CREATE THE ARRAYS FOR ENCODING ==========================================
		public sub initCodecs()
			nl = "<P>" & chr(13) & chr(10)
			dim max, idx
			max = len(BASE_64_MAP_INIT)
			for idx = 0 to max - 1
			     Base64EncMap(idx) = mid(BASE_64_MAP_INIT, idx + 1, 1)
			next
			for idx = 0 to max - 1
			     Base64DecMap(ASC(Base64EncMap(idx))) = idx
			next
		end sub
		' ======================================================================================

	
	
		' ENCODE THE STRING ====================================================================
		public function base64Encode(plain)

			call initCodecs

		     if len(plain) = 0 then
		          base64Encode = ""
		          exit function
		     end if

		     dim ret, ndx, by3, first, second, third
		     by3 = (len(plain) \ 3) * 3
		     ndx = 1
		     do while ndx <= by3
		          first  = asc(mid(plain, ndx+0, 1))
		          second = asc(mid(plain, ndx+1, 1))
		          third  = asc(mid(plain, ndx+2, 1))
		          ret = ret & Base64EncMap(  (first \ 4) AND 63 )
		          ret = ret & Base64EncMap( ((first * 16) AND 48) + ((second \ 16) AND 15 ) )
		          ret = ret & Base64EncMap( ((second * 4) AND 60) + ((third \ 64) AND 3 ) )
		          ret = ret & Base64EncMap( third AND 63)
		          ndx = ndx + 3
		     loop
		     ' check for stragglers
		     if by3 < len(plain) then
		          first  = asc(mid(plain, ndx+0, 1))
		          ret = ret & Base64EncMap(  (first \ 4) AND 63 )
		          if (len(plain) MOD 3 ) = 2 then
		               second = asc(mid(plain, ndx+1, 1))
		               ret = ret & Base64EncMap( ((first * 16) AND 48) +((second \16) AND 15 ) )
		               ret = ret & Base64EncMap( ((second * 4) AND 60) )
		          else
		               ret = ret & Base64EncMap( (first * 16) AND 48)
		               ret = ret & "="
		          end if
		          ret = ret & "="
		     end if

		     base64Encode = ret
		end function
		' ======================================================================================

	
	
		' DECODE THE STRING ====================================================================
		public function base64Decode(scrambled)
		     if len(scrambled) = 0 then
		          base64Decode = ""
		          exit function
		     end if

		     ' ignore padding
		     dim realLen
		     realLen = len(scrambled)
		     do while mid(scrambled, realLen, 1) = "="
		          realLen = realLen - 1
		     loop
		     do while instr(scrambled," ")<>0
		         scrambled=left(scrambled,instr(scrambled," ")-1) & "+" & mid(scrambled,instr(scrambled," ")+1)
		     loop
		     dim ret, ndx, by4, first, second, third, fourth
		     ret = ""
		     by4 = (realLen \ 4) * 4
		     ndx = 1
		     do while ndx <= by4
		          first  = Base64DecMap(asc(mid(scrambled, ndx+0, 1)))
		          second = Base64DecMap(asc(mid(scrambled, ndx+1, 1)))
		          third  = Base64DecMap(asc(mid(scrambled, ndx+2, 1)))
		          fourth = Base64DecMap(asc(mid(scrambled, ndx+3, 1)))
		          ret = ret & chr( ((first * 4) AND 255) +   ((second \ 16) AND 3))
		          ret = ret & chr( ((second * 16) AND 255) + ((third \ 4) AND 15) )
		          ret = ret & chr( ((third * 64) AND 255) +  (fourth AND 63) )
		          ndx = ndx + 4
		     loop
		     ' check for stragglers, will be 2 or 3 characters
		     if ndx < realLen then
		          first  = Base64DecMap(asc(mid(scrambled, ndx+0, 1)))
		          second = Base64DecMap(asc(mid(scrambled, ndx+1, 1)))
		          ret = ret & chr( ((first * 4) AND 255) +   ((second \ 16) AND 3))
		          if realLen MOD 4 = 3 then
		               third = Base64DecMap(asc(mid(scrambled,ndx+2,1)))
		               ret = ret & chr( ((second * 16) AND 255) + ((third \ 4) AND 15) )
		          end if
		     end if

		     base64Decode = ret
		end function
		' ======================================================================================

	
	
		' XOR ENCRYPTION =======================================================================
		public function SimpleXor(InString,Key)
		    dim myIN, myKEY, myC, myPub
		    dim Keylist()
			    
		    myIN = InString
		    myKEY = Key
			    
		    redim KeyList(len(myKEY))
			    
		    i = 1
		    do while i<=len(myKEY)
		        KeyList(i) = Asc(Mid(myKEY, i, 1))
		        i = i + 1
		    loop       
			    
		    j = 1
		    i = 1
		    do while i<=len(myIn)
		        myC = myC & Chr(Asc(Mid(myIN, i, 1)) Xor KeyList(j))
		        i = i + 1
		        if j = len(myKEY) then j = 0
		        j = j + 1
		    loop
			 
		    SimpleXor = myC
		end function
		' ======================================================================================
	' =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-	
	'	BASE64 ENCRYPTION!
	' =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= /\ /\ /\ /\ =-

*edit*
let me know if the code above doesn't work - I've had to hack it around a bit as it was integrated into a few systems.
 
Last edited:
cheers for the reply mate.

I have come across another minor problem to :(

If a logged in user changes the querystring of the memberID in url, they are able to view another members details. How can this be avoided, as i followed a fairly simple tutorial.

However, if the user tries to enter a protected page without a querystring they are redirected back to the login page.

Any ideas?
 
Last edited:
You need to do what Spunkey has suggested. After a user has successfully logged in create a session variable on a protected page check if the variable exists if it doesn't redirect them back to the login page.
 
You need to do what Spunkey has suggested. After a user has successfully logged in create a session variable on a protected page check if the variable exists if it doesn't redirect them back to the login page.

That's what i've done as far as i know:

have set a session called session("auth") = 0 in global.asa (application_ on start). ]

At the top of each protected page i have :

Code:
<%
      If Session("Auth") = 0 Then
        Response.Redirect ("Login.asp")
      End If
      %>

However, say if i member ID 1 logs in, he can change the querystring to memberid = 2 and view details about the other member.
 
You shouldn't be using the querystring to store account IDs.

In the page which processes user logins (ie. checks their username and password against the database) if 1 match is found you need to change session(Auth") = true.
 
You shouldn't be using the querystring to store account IDs.

In the page which processes user logins (ie. checks their username and password against the database) if 1 match is found you need to change session(Auth") = true.

Yer, after a bit of gooling this morning I set another session variable once the user had logged in.

Thanks for replies btw.
 
Back
Top Bottom