A System For Secure User Identification
Introduction
This paper proposes A system for identification of users in a load balanced web server environment, where session and application environments are unreliable and the use of cookies is not possible. User identification is carried along through URL encoding by the use of an ID number mixed with a random “salt” number to add security. The user ID number can be used to access user information stored in a database on the web server side of the Internet connection. The salt number blocks the use of the ID number more than once. This makes it difficult for intruders to intercept and use user ID numbers. The second use of an ID number forces both users to reauthenticate, blocking out the intruder and alerting the true user and the system.
Background
The need for increased web server capacity and for web server scalability has encouraged the development of hardware systems that allow the combining of several servers together to act as a single large server. These systems multiplex transaction requests between several different servers. This allows the traffic load to be spread across the systems as a whole, increasing the load capacity of the total web plant. Web plants of this sort, commonly called “load balanced systems”.
The asynchronous nature of web transactions can make the carrying forward of a session context from web page to web page difficult. Originally, when the web server stood alone as a single server, session context could be carried forward through the session object. The web server would identify the user through their IP address, allowing the web server to keep a section of memory set aside for each user to store variables in. The session object allowed access to this memory to server side scripts which used the state information kept there to customize the users web pages as they were sent to them.
Unfortunately, in a load balanced environment, any of several servers can be used to service client web page requests. At present there is no way for web servers in a load balanced environment to share their session areas. Variables stored in the session area on one server are not visible to the other web servers in the web plant. This causes user variables to appear to appear and disappear in web server scripts as the user’s page requests are shifted from server to server.
The common solution to this problem is to store user information on the client’s web browser in the form of cookies. In this way, the user carries session state along with them instead of on the web server. Unfortunately cookies are not secure. The current designs of web browsers seem to be all to willing to give up any information stored in cookies to any web server they visit. Some, less scrupulous web designers use this weakness to collect information about the browsing habits of their customers. Because of this, the use of cookies is not always popular with clients.
What is needed is a way to store user data without resorting to cookies or the now obsolete session object.
Description Of The Solution
User data can be passed between each web page in a client’s session through the URL he/she uses to call the next page. This is accomplished by adding a question mark and a variable assignment to the end of the URL.
http://www.yoursite.com?ID=123
The called page can retrieve the value of the variable, use it to identify the user, and then pass it on again to the next page. Because the ID value is unique to each user, it can be used as an index to database tables that store user specific information that needs to be carried forward through the user’s web server session.
Each time a new user enters the site without an ID number, the user will be authenticated, a new session will be created, and that user will be assigned a number that will identify that user throughout the session. The user ID is associated with a row in a table in a database that keeps a list of active user sessions. Each row in the active users list keeps track of user IDs, the last access time each user accessed a web page on the site, the user’s IP address, and a salt value.
User sessions on web sites must be bounded by a time out period. The asynchronous nature of browser/server connections leaves no indication when a user has moved on or shut down his/her browser. Timing user sessions out allows inactive sessions to be deleted. Every time a user accesses a page in the site with a user ID, the active users list is consulted. If the time since the last access is greater than the time out period, then the user’s entry is deleted, the user is reauthenticated, and assigned a fresh ID number. If the user hasn’t timed out, the last access time is updated. Expired user entries can be deleted periodically through a batch job or background process.
Users can be impersonated through theft of their user ID, which is transmitted in plan text with the URL. To help prevent this, the user ID is “salted” with a random number. This number is passed along with the user’s ID number. Each time a user accesses a web page, the salt number is compared with the active users table. If it matches, the user is assigned a new random salt number and is allowed to pass on to the next page unchallenged. If it doesn’t match, then all instances of that user in the active user list are forced to reauthenticate. Intruders will not authenticate and will thus be ejected from the system.
Users that are ejected from the system leave behind their IP addresses, tying their active users list entry to the log files created by the web server. In this way all of their activity can be tracked.
Detailed Description
In this explanation, our preferred embodiment is a pure Microsoft environment using Internet Information Server as the web server and SQL Server as the database. All examples will use this technology. The solution provided here will work just as well with Oracle and Apache.
Each web page in the web site shares a common include file that takes care of authentication. The include file looks for an ID number in the page’s URL and uses it to check each user’s session state. If the user’s session had expired or they have yet to log in, then they are shunted over to the login page before. The login page is only necessary when users must be authenticated. The purpose of this system is only to identify a user and to allow the web server to create a session workspace in a load balanced system. What is important is that the user receives an ID number, with or without the optional salt number.

This means that a user could enter the site at any point, not just the entrance and would still have to log in. Users bookmarking pages within the site will still have to be authenticated in when they exercise their bookmarks.
The include file receives the user’s ID from the page’s URL or through authentication. It then passes this value on to the page itself through a script variable. The page passes it along to the next page by appending it onto the URLs in the anchor tags.
http://www.site.com/page.asp?ID=<%=ID%>
In the above example, the value of the script variable “ID” is appended onto the URL in the href tag. Variables can be passed in this manner into Flash files too. What is important is that the ID variable not be lost from page to page.
The ID number is linked to a table entry in a database in the Active Users Table. Users log in and an entry is created in the table. Each entry contains their ID, a last access time, and an optional IP address, salt number, and perhaps a user profile ID number. Each time they access a page, their last access time is advanced. If too much time has passed since their last access, then their session is considered to have expired, their temporary ID number is deactivated and they are required to log in again to receive a new one.
The include file looks like this:
Dim DE
Dim ID
Dim ret
Set DE = Server.CreateObject("DERuntime.DERuntime")
DE.Init(Application("DE"))
ID = Request.QueryString("ID")
ret = DE.ValidateUser(cint(ID))
if ret <> 0 then
Response.Redirect "login.asp?caller=" & _
Request.ServerVariables("URL")
end if
The include file looks for the ID variable in the user’s URL. It passes it to a stored procedure in the database who returns a yea or nea. If the user is not logged in, then the user is shunted over to the login page along with the return URL.
The user validation stored procedure is by far the most complicated piece of this:
CREATE PROCEDURE validate_user(@active_user_id int) AS
if exists (select * from activeusers where active_user_id =
@active_user_id)
begin
if datediff(minute, (select
last_access from activeusers
where active_user_id = @active_user_id),
getdate()) < 3
begin
update activeusers set last_access = getdate() where
active_user_id = @active_user_id
return 0
end
else
begin
delete from activeusers where active_user_id =
@active_user_id
return 100
end
end
else
return 100
It receives the user’s temporary user id. If it’s in the active user table, then the user has logged in. It then checks to see if they’ve timed out.
At the start of the login page is another small piece of code:
Dim DE
Dim ID
Set DE = Server.CreateObject("DERuntime.DERuntime")
DE.Init(Application("DE"))
ID = cstr(DE.AddUser(request.login)
while len(ID) < 3
ID = "0" & ID
wend
This calls another stored procedure that adds the user to the active user table and receives back their temporary ID. Padding the ID with zeros is unnecessary. It just makes it look nicer.
The add user stored procedure looks like this:
CREATE PROCEDURE add_user AS
insert into activeusers (last_access) values (getdate())
return @@identity
It adds the user and returns its temporary ID.
The active users table looks like this:
| Column Name | Type | Size |
|---|---|---|
| active_user_id | Int | 4 |
| last_access | Datetime | 8 |
| user_id | Int | 4 |
The last is the addition of an additional eleven character extension to each href tag in the application. Href tags occur in anchors and image maps and direct the flow of the application.
href=”booths/Toshiba/index.asp?ID=<%=ID%>
The extension is necessary to pass the ID number on to the next page.