The truth about Sessions
Almost each PHP-application uses sessions. This clause{article} in details considers{examines} realization of the safe mechanism of management by session on PHP. After base introduction in the architecture underlying web'b, after acquaintance to a problem of preservation of a status, to the basic application and sense kuk, I shall show you some simple and effective methods which can be used for increase in safety and reliability of the PHP-applications requiring for preservation of a status.
Wrong performance is distributed, that PHP provides the certain level of safety with the help of own opportunities of management of session. PHP, on the contrary, simply gives the convenient, suitable mechanism, and maintenance of the finished decision is care of the developer; and, as you will see, there is no uniform method of the decision, the best for all.
Impossibility of preservation of a status
The hypertext transfer protocol (HTTP), being driving force web'b, is a report without preservation of a status. It is connected to that, that in him there is nothing, that demands from a browser to identify itself at each search, and also there is no constantly established connection between a browser and the web-server which would be saved from page to page. When the user visits{attends} a web-site, the browser sends HTTP-search to the web-server which in turn returns the HTTP-answer. Interaction also is limited to it, it and represents the completed HTTP-transaction.
As information interchange in web'S is based on HTTP, preservation of a status in the web-application can be for developers very much a challenge. Cooks are an expansion of report HTTP, which has been entered to help with maintenance of HTTP-transactions saving a status, but the care of confidentiality induces many users to disconnect support kuk. The information on a status can be transferred{handed} through URL, however its{her} casual disclosing represents serious threat of safety. Actually, the essence of preservation of a status demands, that the client identified itself, however those from us who reflects on safety, know, that we never should trust the information sent by the client.
Despite of all this, there are graceful ways of the decision of a problem of preservation of a status. Certainly, the ideal decision does not exist, as well as a way which can satisfy needs of everyone. This clause{article} represents some ways which can reliably provide an opportunity of preservation of a status, and also protect from the attacks based at session, such as VSD {B.S.: in the original - impersonation.} - delivery of for another (a fake of session). In passing you study, as actually work kuki, that do{make} PHP sessions and that is required for a fake of session.
Common view about HTTP
That it is good to understand a problem of preservation of a status, and also to choose the best for your needs the decision, it is important a little to understand in underlying web'b to architecture - the hypertext transfer protocol (HTTP).
Visit on http://www.example.org/ <http: // www.internet-technologies.ru/? url=http%3A%2F%2Fwww.example.org%2F> demands from a web-browser to send HTTP-search to www.example.org on port 80. Syntax of search is similar to the following:
GET / HTTP/1.1
Host: www.example.org
The first line is called as line - search, and the second parameter in her (a slash in our example) is a way to a required resource. The slash designates a root of a tree of documents; the web-server transforms it to a concrete way to file system. Users Apache'b can be familiar with the instruction{indication} of this way DocumentRoot directive. If it is requested http://www.example.org/path/to/script.php, <http: // www.internet-technologies.ru/? url=http%3A%2F%2Fwww.example.org%2Fpath%2Fto%2Fscript.php%2C> that set in search by to a resource is/path/to/script.php. If the root of a tree of documents is determined as/usr/local/apache/htdocs, a full way to a resource, used by the web-server, -/usr/local/apache/htdocs/path/to/script.php.
The second line illustrates syntax of HTTP-heading. In our case it is heading Host; he defines{determines} the domain host name from which a browser requests a resource. This heading according to report HTTP/1.1 is obligatory and helps to provide the mechanism of support of a virtual hosting - sets of the domains served from the unique IP-address (often - with the unique server). There are many other (unessential) headings which can be switched on in search; to you it can be familiar the reference{manipulation} to them in your PHP-code, for example, $ _SERVER [' HTTP_REFERER '] and $ _SERVER [' HTTP_USER_AGENT '].
Pay special attention, that in a search - example there is nothing, that can be used for unequivocal recognition of the client. Some developers resort to the information received from TCP/IP (such, for example, as the IP-address) for unique identification, but this approach is connected to set of difficulties. Greatest of them - one user can potentially use various IP-addresses for each search (as it occurs to users AOLa), and different users can use the same IP-addresses (as in case of use in many computer laboratories of a HTTP-proxy). These situations can serve as the reason of that the unique user can look as set, or set of users - as one. For a little reliable and safe method of maintenance of a status the information received from HTTP can be used only.
First step in a problem of preservation of a status - somehow unequivocally to identify each client. As the unique solid data which can be used for this purpose, should come from HTTP-search, something should be in the search that can be used for such identification. There are some ways of realization of it, but the decision developed for this problem, are kuki.
Cooks
Understanding of that there should be a method of unequivocal identification of clients, has led to to the creative decision of a problem - to creation kuk. Cooks it is the easiest to understand, if you will take into account, that they are expansion of the HTTP-report which defines{determines} precisely, that this such. Cooks are defined{determined} in RFC 2965 though the initial specification written in Netscape wp.netscape.com/newsref/std/cookie_spec.html, is closer to supported by the industry.
There are two HTTP-headings which are necessary for realization of the mechanism kuk, - Set-Cookie and Cookie. the Web-server includes heading Set-Cookie in reply to search that the browser included this kuku in the subsequent searches. The browser in which are resolved{allowed} kuki, includes heading Cookie in all subsequent searches (which satisfy to the conditions determined in heading Set-Cookie) while kuka will not become outdated (yet will not expire its{her} term). The typical script will consist of two transactions (four HTTP-messages):
1. The client sends HTTP-search.
2. The server sends the HTTP-answer including heading Set-Cookie.
3. The client sends the HTTP-search including heading Cookie.
4. The server sends the HTTP-answer.
Addition of heading Cookie in the second search the client (item{point} 3) gives the information which the server can use for unequivocal identification of the client. As during this moment (or the PHP-script on the party of the server) can define{determine} the server, whether are resolved{allowed} at the user kuki. Though the user can prefer an interdiction kuk, it will be safe enough to assume, that adjustments of the user do not change during interaction with your application. This fact as it will be soon shown, can appear very useful.
GET-And the POST-given
There are two more methods which the client can use for sending the data on the server, and these methods exist much longer kuk. The client can place the information in required URLe in a line of search or is direct in a way though last case demands specific programming which is not covered in this clause{article}. As an example of use of a line of search we shall consider the following:
GET/index.php? foo=bar HTTP/1.1
Host: www.example.org
The accepting script index.php can address to $ _GET [' foo '] for reception of an option value foo. Thereof, the majority of PHP-developers speak about these data as about the GET-given (others sometimes refer to them as on the data from search or URL-variable). The widespread reason of mess is that the GET-given can exist and in POST-search as they are simply a part required URLja and do not depend on a method of search.
Other method which the client can use for sending the information, use of contents of HTTP-search is. This way demands, that a method of search was POST:
POST/index.php HTTP/1.1
Host: www.example.org
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
foo=bar
In this case the accepting script index.php can address to $ _POST [' foo '] for reception of an option value foo. PHP-developers usually refer to these data as on the POST-given and so the browser passes the data sent by the form in which it is specified method = "post".
In general speaking, the search can contain and both types of the data:
POST/index.php? getvar=foo HTTP/1.1
Host: www.example.org
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
postvar=bar
ti two additional methods of sending of the data in search can provide replacement kukam. As against kuk, support GET-and the POST-given is not opcional`noj, therefore these methods can be more reliable also. We shall consider the unique identifier named PHPSESSID {B.S. Beginning{starting}: in general, this name - po-umolchaniju can be changed by the developer of the PHP-application to another.}, switched on in required URL:
GET/index.php? PHPSESSID=12345 HTTP/1.1
Host: www.example.org
{B.S. Beginning{starting}: actually built - in PHP-shnyj the mechanism of management of session generates longer, than 12345, identifiers of session.}
It reaches{achieves} the same purpose, as by heading Cookie as the client identifies itself; however such way demands much more participation of the developer. As soon as kuka it is established, - a duty of a browser is to return her in the subsequent searches. For transfer of the unique identifier by means of URLja the developer should provide, that all links, buttons of sending of forms, etc. contained a corresponding line of search (however, PHP can help him with it if you switch on session.use_trans_sid directive). Besides, the GET-given are displayed in URLe and is much more vulnerable, than kuki. Actually, nothing suspecting users can save such URL in bookmarks, send his friend or make with it everything, that can casually open the unique identifier.
Though the POST-given can be opened with smaller probability, transfer of the unique identifier as demands a POST-variable, that all searches of the user were carried out by method POST. Usually this variant is not convenient, though the design of your application and can make his more viable.
Management of session
Till now I discussed a status - a little nizkourovnevoe the concept concerning binding of one HTTP-transaction to anothers. More useful opportunity with which you, probably, are familiar, management of session is. Management of session not only is based on an opportunity of preservation of a status, but also requires preservation of the client data for each user session. These data in most cases name the sessional data because they are connected to concrete session of the user. If you use built - in in PHP the mechanism of management of session, the sessional data are saved for you (by default - in a directory/tmp) and are accessible in a superglobal file $ _SESSION. The simple example of use of sessions concerns preservation of the sessional data from one page to another. The listing 1 representing a script session_start.php, shows, how it can be made.
Listing 1
<? php
session_start ();
$ _SESSION [' foo '] = ' bar ';
<a href = "session_continue.php"> session_continue.php </a>
?>
If the user will click under the link in session_start.php {B.S. Beginning{starting}: certainly, it means under the link to the page generated by this script.}, the accepting script session_continue.php will have an opportunity access to the same sessional variable $ _SESSION [' foo ']. It is shown in listing 2.
Listing 2
<? php
session_start ();
echo $ _SESSION [' foo '];/* bar */
?>
{B.S. Beginning{starting}: that has taken place above described, the second script should receive the identifier of session generated by the first script for what session.use_trans_sid directive should be switched on or at the user should be resolved{allowed} kuki.}
Serious threat of safety exists, when you write the code similar on resulted, without understanding of that for you does{makes} PHP. Without this knowledge you will find out, that it is difficult to debug sessional mistakes or to provide any level of safety.
Delivery of for another (VSD)
Wrong performance is distributed, that native PHP-shnyj the mechanism of management of session itself undertakes security measures against the attacks based at session. On the contrary, PHP only gives the mechanism suitable to it. The responsibility for maintenance of corresponding security measures lozhitsja on the developer. As it was mentioned earlier, there is no faultless, ideal way of the decision, as well as the best decision, correct for everyone.
For an explanation of danger VSD we shall consider the following sequence of events:
1. Mal`chish-Kibal`chish comes on http://www.example.org/ and avtoriziruetsja.
2. The Web-site establishes kuku PHPSESSID=12345.
3. Mal`chish-Plokhish comes on http://www.example.org/ and gives kuku PHPSESSID=12345.
4. The Web-site wrongly thinks, that Mal`chish-Plokhish actually is Mal`chishom-Kibal`chishom.
Certainly, this script demands, that Plokhish has somehow learned{has somehow found out} or has guessed correct PHPSESSID, belonging Kibal`chishu. Though it also seems maloobehhajuhhim, is an example of a safety with help NDP {B.S.: in the original - obscurity.} - uncertainty for the stranger; he is not something, on what it is necessary to rely. Such uncertainty - a thing, certainly, quite good, and she can help, but something is necessary more essential, that will offer reliable protection against similar attack.
Prevention VSD
There are many ways which can be used for difficulty VSD or other attacks based at session. The general{common} approach here is creation of systems so as far as it is possible, convenient for your lawful users and, so, as far as possible, - complex and confusing for attacking. It can appear very much trudnodostizhimym balance, and substantially the ideal balance depends on design of the application. Therefore, finally, the best judge are you.
The elementary correct from point of view HTTP/1.1 the search as it was mentioned earlier, will consist of line - search and heading Host:
GET / HTTP/1.1
Host: www.example.org
The client can pass the identifier of session PHPSESSID in heading Cookie:
GET / HTTP/1.1
Host: www.example.org
Cookie: PHPSESSID=12345
As alternative the client can pass the identifier of session in URLe search:
GET/? PHPSESSID=12345 HTTP/1.1
Host: www.example.org
The identifier of session also can be switched on in the POST-given, but it is usual less user-friendly and is distributed least.
As the information received from TCP/IP, cannot be reliably used in amplification{strengthening} of safety of the mechanism it seems, that the web-developer a little that can make for difficulty VSD. After all, attacking the same unique identifier, as the legal, lawful user should give only to give out itself for this user and to forge session. Thus, it is represented, that unique protection - or to hide the identifier of session, or to do{make} his difficult for guessing (and it is better - both that, and another).
PHP generates the casual identifier of session which cannot be guessed, thus, about it it is possible to not care almost. To prevent disclosing attacking the correct identifier of session it is much more complex , as the most part of the responsibility for it lays outside of area of the control of the developer.
There are many situations which can lead to to disclosing of the user identifier of session. The GET-given can be erroneous kehshirovany, are noticed by the casual observer, saved in bookmarks or transferred{handed} on email. Cooks provide a little more safe mechanism, but users can disconnect their support, excepting an opportunity of their use, and vulnerability of browsers are known for casual information leakage from kuk on the non-authorized sites (look www.peacefire.org/security/iecookies/ and www.solutions.fi/iebug/for the additional information).
So, the developer can be quite convinced, that the identifier of session cannot be guessed, however an opportunity, that he can be found out attacking, is much more probable irrespective of a method used for his transfer. Any additional means are necessary for prevention VSD.
In practice the typical HTTP-search besides Host contains set of unessential headings. For example, we shall consider the following:
GET / HTTP/1.1
Host: www.example.org
Cookie: PHPSESSID=12345
User-Agent: Mozilla/5.0 Galeon/1.2.6 (X11; Linux i686; U;) Gecko/20020916
Accept: text/html; q=0.9, */*; q=0.1
Accept-Charset: ISO-8859-1, utf-8; q=0.66, *; q=0.66
Accept-Language: en
This search contains four unessential headings: User-Agent, Accept, Accept-Charset and Accept-Language. that these headings are unessential, it will be not so reasonable to hope for their presence. However if the browser of the user nevertheless has sent these headings whether safely to believe, what they will be present and at the subsequent searches from the same browser? The answer is "yes" with very few exceptions. Assuming, that the previous example is the search sent by the user with active session, we shall consider the following search sent shortly after that:
GET / HTTP/1.1
Host: www.example.org
Cookie: PHPSESSID=12345
User-Agent: Mozilla/5.0 (compatible; IE 6.0 Microsoft Windows XP)
As the same unique identifier is given, access to the same PHP-session will be received. If the browser identifies itself differently, than in the previous interaction, whether it is necessary to believe, what is it the same user?
I hope to you understandably, nevertheless, it what is it is not desirable that will take place if you write a code which does not check specially such situations. Even in cases when you cannot be sure, that the search is VSD-ATTACK, the simple requirement of input by the user of the password can help to prevent VSD without causing special inconvenience to your users.
You can add check of a browser of the user in your model of safety with the help of the code similar submitted on listing 3.
Listing 3
<? php
session_start ();
if (md5 ($ _SERVER [' HTTP_USER_AGENT '])! = $ _SESSION [' HTTP_USER_AGENT ']) {
/* Search of the password */
exit;
}
/* Other code */
?>
Certainly, before it it is necessary for you to save MD5-khehsh from the full name of a browser of the user every time when you for the first time begin session, as shown in listing 4.
Listing 4
<? php
session_start ();
$ _SESSION [' HTTP_USER_AGENT '] = md5 ($ _SERVER [' HTTP_USER_AGENT ']);
?>
Though and it is not necessary, that you used MD5-khehsh instead of the full name of a browser of the user, it will help to provide the certain constancy and to exclude necessity of check of correctness of value $ _SERVER [' HTTP_USER_AGENT '] before his preservation in session. As these data undertake from the client, to trust them blindly it is impossible, but format MD5-khehsha is independent of the entrance data.
Now, when we have added check of a browser of the user, attacking should carry out two steps to forge session:
* To receive the correct identifier of session.
* To give at VSD-ATTACK the same heading User-Agent.
Though it, undoubtedly, and is possible, at least, it more difficultly, than if the second step has been missed. Thus, we already have a little strengthened safety of the sessional mechanism.
Other headings can be added by the same way, and you can even use in quality of " prints of fingers " a combination of headings. If you also will add a certain additional confidential prefix such "prints" cannot be guessed. See an example on listing 5.
Listing 5
<? php
session_start ();
$fingerprint = ' SECRETSTUFF '. $ _SERVER [' HTTP_USER_AGENT ']. $ _SERVER [' HTTP_ACCEPT_CHARSET '];
$ _SESSION [' fingerprint '] = md5 ($fingerprint. session_id ());
?>
Heading Accept should not be used in " prints of fingers " as Microsoft'ovskij Internet Explorer it is known for a divergence in values of this heading in cases when the user updates page and when he clicks under the link.
With difficultly guessed by " prints of fingers " some prize is reached{achieved} and without complication of this information by other, than shown till now, way. At the existing mechanism for VSD the same two steps though the second step now is much more complex as attacking should reproduce plural headings as a matter of fact are required.
For increase in safety it is necessary to start to include the data in addition to the unique identifier. We shall consider the mechanism of management of session at which the unique identifier is passed in the GET-given. If " prints of fingers ", generated in the previous example, also are passed as the GET-given, attacking should carry out the following three steps for a successful fake of session:
* To receive the correct identifier of session.
* To give the same HTTP-headings.
* To give correct " prints of fingers ".
If also the unique identifier, and " prints of fingers " are passed as the GET-given, that, it is possible, that attacking which can receive something one of them, also will get access and to another. More safe approach is use of two various methods of transfer - the GET-given and kuk. Certainly, it depends on the user adjustments, but for those who has allowed kuki, the additional level of protection can be provided. Thus, if attacking will receive the unique identifier through vulnerability of a browser, " prints of fingers ", probably, to him will be still unknown.
There are many other ways, which can be used to increase safety of your mechanism of management of session. We shall hope, you will become successful on a way of creation of some own tekhnik. After all, you are the expert of your own applications, therefore, armed with good understanding of sessions, you are the most suitable person for realization of additional safety.
Uncertainty for stranger (NDP)
I would like to disseminate the widespread myth about NDP. He will consist that ostensibly by means of such uncertainty is impossible to provide safety. As it was mentioned earlier, NDP is not something, that offers adequate protection, and on what it is necessary to rely. Nevertheless, it does not mean, that with the help of such uncertainty safety at all cannot be provided. On the contrary, already having as a basis the safe mechanism of management of session, NDP can offer a small degree of additional reliability.
Simple use of misleading names of variables for the unique identifier and " prints of fingers " can help. You can pass also the false data to misdirect potential attacking and to confuse it . On these of technics{technical equipment} for protection, certainly to rely never costs{stands}, but you not for nothing will waste time, if organize a little NDP in your own mechanism. For who does not have base understanding of safety of sessions, probably, it is the best way to support a myth about NDP, differently somebody can be entered into error, having believed that she gives a sufficient level of protection.
The important remark
B.S: it is added in April of 2004 from submission RomikChef'b after discussion of clause{article} on webscript.ru.
Once again (it is important!):
(a) If a print to put in session (as it is made in listing 5) we do not receive any third item{point}, and for VSD it is necessary to execute only first two (the author speaks about it above) as having given the identifier of session attacking automatically the print will give also;
(b) (the author does not mention it) the variant of transfer of a print in kukakh disappears in general as users with switched - off kukami cannot work; it is necessary to pass a print a GET-ohm, and then:
(v) For users with switched - off kukami GETom the identifier of session so, time attacking could pass the first item{point} will be passed also and learn{find out} the identifier, - he knows that both we again do not receive a print, and the third item{point} (the author himself speaks and about it);
(g) (this most important and a unique case when we receive the third item{point}!) for those who has allowed kuki, " the additional level of protection " (about what the author too speaks), but (the author does not mention it), as well as for item{point} (v) transfer of print GETom demands from the developer "hands" to do{make} that in a case with the identifier of session is automatically done{made} by inclusion session.use_trans_sid, i.e. avtodopolnjat` will be really provided with a print of the link and the form.
Besides if and to realize item{point} (g) to put in a print headings of special sense no (in fact at realization of the second item{point} of protection in session it is possible to put and some headings); probably, will be also a confidential prefix with the identifier quite enough.
The resume
I hope, that you have taken something for yourselves from this clause{article}. In particular, now you should have base understanding of how works web as the opportunity of preservation of a status is reached{achieved}, than actually are kuki as work PHP sessions and the some people of technics{technical equipment} which you can use for improvement of reliability of your sessions.
If you have any questions or comments, - my contact information is accessible on my web-site shiflett.org; also you can place your responses on this clause{article} in forum PHP Magazine'b forum.php-mag.net. I would like to hear about your own methods of safe management of session and I hope, that this clause{article} will provide the introduction information which is required to you for support of own creativity.

|