This is a discussion on Session theft? within the PHP Language forums, part of the PHP Programming Forums category; Dani CS <contusiones.merluza@yahoo.es.quita-la-merluza> wrote: [one time sessionids] Pretty simple and yet effective. ...
|
|||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
|
|||
|
Dani CS <contusiones.merluza@yahoo.es.quita-la-merluza> wrote:
[one time sessionids] Pretty simple and yet effective. But if one depends on clientside scripting one might use a public/private encryption (there are RSA scripts for both javascript and php), only problem is remembering the public key on the client. Alternatively one time keys could be generated serverside kinda like your scheme. |
|
|||
|
"Dani CS" <contusiones.merluza@yahoo.es.quita-la-merluza> wrote in message
news:cpuaqq$khj$1@news.ya.com... > Robert Tweed wrote: > > Does anyone know a good resource discussing the issues involved in session > > theft? I've read a couple, but none that really address the problem apart > > from acknowledging that it is a problem; you just don't seem to be able to > > do much about it. > > Session theft can be avoided with some scripting both in the client and > the server, at the expense of making the 'back' button unusable on the > client's side. Let me explain before you think I'm mad :-) > > The trick is not to use one _fixed_ session id during the wholesession, > but rather a _different_ session id for every client->server interaction > (i.e. every time a new page is fetched from the server). In other words, > multiple single-use session-ids for each session. > > A (single use) session id can be calculated from previos session ids and > a secret shared between client and server (e.g. the password used for > authentication of the user). This means that client and server must be > in sync. Along with each request, the client must send the next session > id that the server expects. This is why the 'back' button must not be > used: the session id of the previous page would be sent to the server, > but the server expects to get the session id for a new page. (I haven't > worked at fixing this at the moment.) > > The generated session ids must be difficult to guess just by looking at > previous session ids, so a one-way hash can be very useful (my > implementation uses MD5). > > To summarise, the steps are: > > 1. > - The (still anonymous) client requests the login page. > - The server sends back a login page, along with a random session id. > > 2. > - The user fills in a login/password (or similar). > - The client generates a new session id by mixing the received session > id and the password given by the user (i.e. new_sid = > hash(old_sid+password)). The username and the new session id are sent to > the server. > - The server gets the username, generates its own new session id by > mixing the (previously sent) old session id with the local copy of the > password. If both client and server agree on the same new session id, > the user is logged in. The server sends back to the client a welcome > page. The generated new session id is stored on the server. > > 3. > - When the (already authenticated) client requests another page, it uses > a new session id built from the previous session id and the shared > secret: new_sid = hash(previous_sid+password). > - The server works out its own new session id (same process of mixing > the previous sid and the shared secret). If both client and server agree > on the same new_sid, then the client is allowed to see the next page > requested. > > 4. Repeat #3 above until finished. > > > This method effectively prevents session theft when the thief has not > access to the computer. Each session id sniffed on the net is useless, > because the server will accept it exactly one time. The session thief > will find it very difficult to guess the next session id, because it > depends on the secret shared by the legitimate user and the server. > > The main concern (appart from breaking the 'back' button) is hiding the > password on the client to prevent cross-site scripting attacks that > could retrieve it. This is caused by the need to keep the shared secret > in the client's memory to generate each one of the new session ids. > > > A working implementation (sorry, no demo) can be seen at > <http://mipagina.ath.cx/diario/adm/>. You can poke at the client-side > javascript to see the details. If enough people are interested I will > set up a demo site with multiple users and make the full source code > available (probably GPL'ed). > > Any (constructive) comments will be welcome. > > > <snip rest of interesting OP> I too have given this idea some thought over the past couple years. I would add to this with making sure that the first time the SID's don't match that the user is immediatelty logged out. Unless the hacker is on wireless w/laptop or sitting right in front of the computer and managed to figure out the next SID and then managed to jump in before the real user reloads a page, it should be a very secure system. Second, set the sessions to time-out after a few minutes (or whatever you deem fit for normal usage. Then you prevent a hacker from waiting too long before attempting access. Norm --- FREE Avatar Hosting at www.easyavatar.com |
|
|||
|
.oO(Dani CS)
>- When the (already authenticated) client requests another page, it uses >a new session id built from the previous session id and the shared >secret: new_sid = hash(previous_sid+password). How is the password stored on the client, so that it will be accessible on every page to calculate the next ID, but not send to the server along with each request? Micha |
|
|||
|
Dani CS wrote:
> The trick is not to use one _fixed_ session id during the wholesession, > but rather a _different_ session id for every client->server interaction > (i.e. every time a new page is fetched from the server). In other words, > multiple single-use session-ids for each session. > > A (single use) session id can be calculated from previos session ids and > a secret shared between client and server (e.g. the password used for > authentication of the user). This means that client and server must be > in sync. Along with each request, the client must send the next session > id that the server expects. This is why the 'back' button must not be > used: the session id of the previous page would be sent to the server, > but the server expects to get the session id for a new page. (I haven't > worked at fixing this at the moment.) > > The generated session ids must be difficult to guess just by looking at > previous session ids, so a one-way hash can be very useful (my > implementation uses MD5). > Why the clientside calculations really ? Why not just have the server generate a new UID that the client must use for the next page view ? And if you store the generated session history you'll have some extra options. - Let's say a UID was stolen or sniffed. When the user tries to access the next page he will be asked to login, sending along the invalid UID. If login succeed it will take precedence over the latest used UID's and you'll have a track from the real users, former, invalid UID up to the latest. - If you want to relax security a bit, you could allow the last or the last n sessions to be valid within a time span, allowing for Back button functionality. /Johnny |
|
|||
|
Michael Fesser wrote:
> .oO(Dani CS) > > >>- When the (already authenticated) client requests another page, it uses >>a new session id built from the previous session id and the shared >>secret: new_sid = hash(previous_sid+password). > > > How is the password stored on the client, so that it will be accessible > on every page to calculate the next ID, but not send to the server along > with each request? You can check the working code to see that the password is MD5-hashed when entered and then stored in a global javascript variable on the top of a frameset. This frameset provides a getNextSid() function that makes the calculations, and functions to output links and forms in the child document so that they use the correct next_sid. > > Micha |
|
|||
|
Johnny Elvers wrote:
> Dani CS wrote: > > > The trick is not to use one _fixed_ session id during the wholesession, > > but rather a _different_ session id for every client->server interaction > > (i.e. every time a new page is fetched from the server). In other words, > > multiple single-use session-ids for each session. > > > > A (single use) session id can be calculated from previos session ids and > > a secret shared between client and server (e.g. the password used for > > authentication of the user). This means that client and server must be > > in sync. Along with each request, the client must send the next session > > id that the server expects. This is why the 'back' button must not be > > used: the session id of the previous page would be sent to the server, > > but the server expects to get the session id for a new page. (I haven't > > worked at fixing this at the moment.) > > > > The generated session ids must be difficult to guess just by looking at > > previous session ids, so a one-way hash can be very useful (my > > implementation uses MD5). > > > > Why the clientside calculations really ? Why not just have the server > generate a new UID that the client must use for the next page view ? A session thief could retrieve the UID when it travels down to the cliend, and use it right before the legitimate client uses it. > > And if you store the generated session history you'll have some extra > options. > > - Let's say a UID was stolen or sniffed. When the user tries to access > the next page he will be asked to login, sending along the invalid UID. > If login succeed it will take precedence over the latest used UID's and > you'll have a track from the real users, former, invalid UID up to the > latest. I don't keep a history because I didn't see the need when I developed this experiment, but the idea sounds good to me. Apart from that, anytime that a user sends a wrong UID, they are presented the login window again, just like you say. > > - If you want to relax security a bit, you could allow the last or the > last n sessions to be valid within a time span, allowing for Back button > functionality. This could work, but I'll keep searching for a while on ways to make the 'back' button usable. Maybe the onunload() javascript event can help. > > /Johnny |
|
|||
|
"Dani CS" <contusiones.merluza@yahoo.es.quita-la-merluza> wrote in message
news:cpuaqq$khj$1@news.ya.com... > > The main concern (appart from breaking the 'back' button) is hiding the > password on the client to prevent cross-site scripting attacks that > could retrieve it. This is caused by the need to keep the shared secret > in the client's memory to generate each one of the new session ids. I _think_ (not 100% certain about this) that you can avoid XSS attacks as follows: - When user goes to admin URL, open a new window to begin the session in. - Ensure that the name of the new window is _blank; or, if using window.open, create a totally random name based on the time - the more entropy the better. - Try to ensure that users only enter the admin system via this "window with no name". This should prevent any script from accessing values on your admin system pages, as they are entirely contained in a window with no known target name. It would not stop a specially written trojan, but then if you've got trojans on your system then you've got more to worry about than session theft. - Robert |
|
|||
|
>> Why the clientside calculations really ? Why not just have the server >> generate a new UID that the client must use for the next page view ? > > > A session thief could retrieve the UID when it travels down to the > cliend, and use it right before the legitimate client uses it. > Right, but the same applies to the client side algorithms. For measurements against generic theft your point is taken though. > This could work, but I'll keep searching for a while on ways to make the > 'back' button usable. Maybe the onunload() javascript event can help. Could be. Take a look at the XMLHttpRequest object. /Johnny |
|
|||
|
Johnny Elvers wrote:
> >>> Why the clientside calculations really ? Why not just have the server >>> generate a new UID that the client must use for the next page view ? >> >> >> >> A session thief could retrieve the UID when it travels down to the >> cliend, and use it right before the legitimate client uses it. >> > > Right, but the same applies to the client side algorithms. > For measurements against generic theft your point is taken though. I was assuming that the thief can see the data, but not touch it. In this case, even if the thief gets the new_sid that travels from the client to the server, it will be worthless, because that new_sid has already arrived to the server and is no longer valid. If there is someone in the middle who can manipulate the data, only SSL or similar would be good. |
|
|||
|
>>> >>> A session thief could retrieve the UID when it travels down to the >>> cliend, and use it right before the legitimate client uses it. >>> >> >> Right, but the same applies to the client side algorithms. >> For measurements against generic theft your point is taken though. > > > I was assuming that the thief can see the data, but not touch it. In > this case, even if the thief gets the new_sid that travels from the > client to the server, it will be worthless, because that new_sid has > already arrived to the server and is no longer valid. > But the thief can do the same calculations as the client. But you are right of cause, as this is about session theft and not hacking attempts :) /Johnny |