A distinctive feature of Web systems is that each visit on an HTTP page is a new action unrelated to the previous action. Therefore, authentication is necessary every time a user attempts to access the system.
A common error is that authentication is done only when the user logs into the system (e.g., accesses the http://www.site.ru/admin.php file). After the primary authentication is done using any of the methods , the authenticated user is redirected to another part of the site. No additional authentication is done on that part.
Such a policy is nothing but a policy of confusion. This type of policy is seldom effective. It is only effective if an attacker doesn't know the URL of the private part of the site.
In addition, it is obvious that legitimate users know this path . Suppose you need to deprive a user of access rights to the system. It won't suffice to delete him or her from the list of users. This user knows the URL of the private part of the site.
In a word, this policy is ineffective because it has all the drawbacks of a long URL.
It won't be wise to require users to enter their logins and passwords every time they are redirected to another page. This would make the system inconvenient for them.
Sometimes the following authorization method is used: For primary authorization, a user enters his or her login and password. If both the login and the password are valid, the user is logged into the system, and the login and the password are written into a cookie.
Cookies are small files that store special server information. Cookies can be stored on the hard disk (these are called persistent) or in the computer memory (session cookies). COOKIE parameters are stored until the browser window is closed.
COOKIE parameters are sent using HTTP without encryption both from the client to the server and from the server to the client. The lifetime can be sent with a cookie. In this case, the cookie "dies" when the lifetime expires . Otherwise, a session cookie is set.
Functionality of this system is identical to that of a system, in which a user has to enter the login and the password before each request to the system. However, in this system, the user doesn't enter anything. Rather, the browser sends the values of the COOKIE parameters set by the site. The subsequent authorization is done using the COOKIE values.
Disadvantages of such a system are that the password is stored on the client computer for an indeterminate amount of time. Because the password is sent unencrypted during each request, it can be intercepted. Because it is stored unencrypted on the client's hard disk, anyone who has access to the disk can read the password.
To avoid sending a password as a COOKIE value, some systems perform authorization based on received POST parameters and, if the authorization is successful, write only the login into a cookie. After that, if the valid login is received as a COOKIE parameter, the system assumes the owner of this login has passed authentication successfully.
Naturally, this is also a confusing policy. It works only until an attacker discloses the internals of the site.
To circumvent this protection, a malicious user only needs to edit files with the COOKIE parameters to set an appropriate variable to the login of a valid user. Then he or she can log into the system. Thus, he or she can obtain the rights of a valid user without knowing this user's password.
You cannot say this system is secure.
Another variant of this method involves writing a hash of the password rather than the password into a cookie.
A hash function is a function that maps the set of all strings to the set of strings with a particular length. The hash function isn't invertible, that is, it is impossible to compute the original string from a hash without trying every possible value.
The subsequent authorization is done as follows : The login and the hash of the password are received as COOKIE parameters. This user's password is retrieved from a database or another repository, and a hash is computed from this password. Authorization is considered successful if the hash received as a COOKIE value is equal to the hash just computed.
Advantages of this authentication method are the following:
Cookies stored on the client's hard disk contain only the login and the password hash, which doesn't allow an attacker to obtain the password quickly.
In subsequent authentication, only the hash is sent, and there is no use of traffic interception. However, if the attacker can intercept all the traffic, he or she can learn the password from the primary authentication.
Practically all authentication systems based on HTTP are vulnerable to traffic interception. To make traffic interception pointless, use HTTPS.
The described system also has a few disadvantages:
An attacker doesn't need to know a password to log into the system. It will suffice to know the password hash, and anyone who has access to the client's hard disk can discover the hash. In addition, the attacker can obtain the password hash through vulnerabilities of the cross-site scripting (XSS) type, which are described later. Having obtained the hash, the attacker only needs to write this hash and the valid user's login into COOKIE parameters to log into the system and gain the rights of an authorized user.
This system stores users' passwords on the server in an unencrypted or revertible form. In other words, anyone who has access to the password database can discover the passwords of all users. Even if the passwords in the database are encrypted, you can suppose that the information necessary for decryption is available to the authorization script and, therefore, to anyone who has access to the password database.
If an attacker steals a password hash, he or she will be able to log into the system until the owner of the password changes the password.
In addition, because a password can be simple or short, it is possible for the attacker to find the hash using a glossary. If the attack is successful, the attacker will know the password. (It is assumed that the attacker knows the hash function used in the system.)
Be aware that changing any cookie data, such as parameter names or values, parameter lifetimes, and the name or URL of the site, or deleting or adding cookie data isn't a challenge for an attacker.
There are many utilities on the Internet that make it easy to change cookies. In addition, the attacker can edit cookie files directly. In Mozilla, for example, to edit a cookie, you should edit the COOKIE.TXT file. In Internet Explorer, cookies are located in the COOKIES folder, and you can edit the files.
One of the best solutions for HTTP authentication is a session approach. After the primary authentication, when the user sends the login and the password (the best method for this is HTTP POST ), a long random number is generated. It is called a session ID.
This ID is bound to the user in the user database and sent to the user using any method. In addition, the session ID has a lifetime during which it is valid. For example, the current time (or the expire time) is also bound to the user.
After that, authorization proceeds as follows: The server receives a session ID issued previously. Then it tries to retrieve the login of the user to whom the session ID belongs. If the user isn't found, authentication is considered unsuccessful .
If the user is found, the timestamp is read to check whether the session ID lifetime has expired. If it has, authentication is considered unsuccessful. If the user is found and the session ID lifetime hasn't expired , the user is authenticated.
The lifetime can be updated every time the user visits another page or once, during the primary authorization. With such an approach, the user will have to enter the login and the password periodically.
This system can be considered reliable if the server generates a long random value for the session ID. The session ID can be bound to the current time and a pseudorandom value. Sometimes, a hash function is computed from these values.
Consider an example of how a session ID can be generated.
Generating a session ID
$token = md5(uniqid("")); $better_token = md5(uniqid(rand(), true));
In the first line, a unique ID is generated and the md5() hash function is computed from it.
In the second line, a more secure approach is implemented. It works as follows: A unique ID with a random prefix obtained from the rand() function is generated. The second parameter of the uniqid() function adds a "combined LCG" entropy to the end of the returned value. This adds a bit more uniqueness to the ID. Then the md5() hash function is computed.
The uniqid() function generates a unique value based on the current time in milliseconds .
In this example, a unique 128-bit session ID will be generated. Because this is a very long number, the task of finding it would be complicated for an attacker. In addition, because the session ID's lifetime is limited, each attempt to try a number will require an attacker to make a new HTTP request to the server.
If functions generating unique values are unavailable to you, you can create your own ones based on pseudorandom values and the current time. It would be a good idea to compute a hash function (such as md5() ) from the resulting value.
Generating a session ID based on pseudorandom values
$sessionid = md5(rand().microtime());
Remember that in some systems you should seed the random number generator before you call the rand() function.
The more precise the value returned by the microtime() function, the better the session ID.
Systems based on session IDs can be either of two types. The first authenticates a user only with a session ID. In the second, the login is used in addition to the session ID. In the second case, both the login and the session ID must be valid for successful authentication. The task of finding the session ID would be more complicated.
When the login isn't sent for authorization, and there are many users in the system, an attacker has a better chance of finding at least one session ID. However, this problem is eliminated by increasing the length of the session IDs. In other words, the security of a system doesn't suffer when the session ID is used for authentication and the login isn't.
In Web systems, the session ID can be sent using HTTP GET , POST , or COOKIE method. The most effective and secure method for sending the session ID is COOKIE . The lifetime of the session ID can be set equal to that of the COOKIE parameter. However, you should remember that the lifetime of a cookie is just the server's recommendation to the client. Nobody can guarantee that the client's browser will follow the recommendation, and the lifetime won't change after the client receives the session ID. So, even if the lifetime of a session ID is set equal to that of the COOKIE parameter, make sure it is fixed on the server by storing this information in a database or another repository with the session ID.
I now describe the pros and cons of this authentication system.
The pros are the following:
You don't need to store unencrypted passwords on the server. It will suffice to store their hashes.
If a malicious person steals a session ID, he or she will probably be unable to use it in time, before the session ID's lifetime expires. Even if the malicious person manages to use it, this won't last long.
You can design the system so that certain important operations require additional confirmation with the password. Then the malicious person won't be able to perform these operations even if he or she intercepts a session ID. For example, you can change the user's password to prevent the attacker from gaining full control over the user's account.
The session ID doesn't carry any information on the user's login, password, status, and so on. The malicious user can obtain additional information about the owner of particular session ID only if he or she logs into the system using this ID.
This authentication system has the following cons:
It isn't secure against traffic interception at the beginning of the authorization procedure when the user enters his or her login and password that aren't encrypted. To avoid this, use asymmetric encryption such as the Secure Sockets Layer (SSL) in HTTP.
Some users disable cookies in their browsers. In these cases, some systems send session IDs as GET parameters. In other words, one parameter, a session ID, is added to each link on the page. This solution allows users who disabled cookies in their browsers to log into the system. However, it has a few disadvantages:
It is more difficult to implement this system. The system becomes less elegant, and it is difficult to separate the authentication and authorization module from the other components of the system.
It becomes possible for an attacker to intercept the session ID in log files. Although interception of a session ID isn't as useful for the attacker as interception of a password, it makes the system less secure.
It is more difficult for search engines to index the pages of a site with links containing various GET parameters.
A session ID can appear in log files of a third-party server through HTTP Referer . If an attacker can pass a necessary link to the protected part of the system (e.g., send an e-mail message in a Web mail system) and follow this link, he or she will access HTTP Referer , which will contain the session ID.
When you need to send an HTTP POST form, you can send the session ID as an HTTP GET or POST parameter.
PHP offers you a built-in mechanism for work with sessions. You can use it for authorization and for other purposes. However, this mechanism has a serious drawback. Session variables associated with the session ID are stored in files in a temporary folder on the server; therefore, any local user with appropriate access rights can read these files.
In Unix-like operating systems, files are usually created with the access rights - rw- --- --- and belong to the user who started the Web server. As a rule, this is a user such as www, apache, or nobody .
In other words, only the root user and the user who started the Web server have rights to read these files. This system can seem secure enough, but remember that all scripts available through HTTP will be executed under this user. In other words, if there is a vulnerability in any script on that server that discloses the contents of files, an attacker will be able to discover the session variables of any user. If authentication is implemented as described previously, the login and the password can be among these variables.