How to delete session file on logout

913 views
Skip to first unread message

Mandar Vaze

unread,
Oct 14, 2014, 2:18:05 PM10/14/14
to web...@googlegroups.com
(This is related to security issue - I've explained the security issue in detail to Massimo and anthony separately)

I want the session to be "invalid" as soon as after user logs out (as well as after certain period of inactivity)
This is "supposed to be" default behaviour - but somehow doesn't work.
I explictly called session.renew() on logout - but that seems to "clear" the session Storage() object (dict) from the memory, but the session file on the disk remains.

What I want is something like sessions2trash.py script - except that file should deleted right away - even if the session has not expired.

Currently I'm using something like following. Please suggest correct way to handle this (I know this works only for file based sessions, but that is OK)

def post_logout(user):
   
try:
       
import os
        os
.unlink(response.session_filename) # Clear the session from disk
   
except OSError:
       
pass
    session
.renew(clear_session=True)  # Clear the memory/Storage object.

auth
.settings.logout_onlogout = post_logout

I can't call session.renew() before unlink - since original session_filename is lost on renew

-Mandar

Anthony

unread,
Oct 14, 2014, 3:36:43 PM10/14/14
to web...@googlegroups.com
On Tuesday, October 14, 2014 2:18:05 PM UTC-4, Mandar Vaze wrote:
(This is related to security issue - I've explained the security issue in detail to Massimo and anthony separately)

I want the session to be "invalid" as soon as after user logs out (as well as after certain period of inactivity)
This is "supposed to be" default behaviour - but somehow doesn't work.

In the current version of web2py, the default behavior is that upon logout, the session is cleared and renewed (i.e., a new session ID is issued). However, it does not delete the old session file. When you say it "somehow doesn't work," do you just mean the old session file remains, or is something else not working?
 
What I want is something like sessions2trash.py script - except that file should deleted right away - even if the session has not expired.

Currently I'm using something like following. Please suggest correct way to handle this (I know this works only for file based sessions, but that is OK)

def post_logout(user):
   
try:
       
import os
        os
.unlink(response.session_filename) # Clear the session from disk
   
except OSError:
       
pass
    session
.renew(clear_session=True)  # Clear the memory/Storage object.

You shouldn't need that last line, as the logout function already does exactly that by default.

Anthony

Mandar Vaze / मंदार वझे

unread,
Oct 15, 2014, 1:59:34 PM10/15/14
to web...@googlegroups.com
On Wed, Oct 15, 2014 at 1:06 AM, Anthony <abas...@gmail.com> wrote:
On Tuesday, October 14, 2014 2:18:05 PM UTC-4, Mandar Vaze wrote:
(This is related to security issue - I've explained the security issue in detail to Massimo and anthony separately)

I want the session to be "invalid" as soon as after user logs out (as well as after certain period of inactivity)
This is "supposed to be" default behaviour - but somehow doesn't work.

In the current version of web2py, the default behavior is that upon logout, the session is cleared and renewed (i.e., a new session ID is issued). However, it does not delete the old session file.
When you say it "somehow doesn't work," do you just mean the old session file remains, or is something else not working?

Yes. Session file does not get deleted.
The side effect of session file remaining on the disk is that if the "hijacked" session ID is used by the attacker - then "somehow" contents of the session file on the disk are reused (even if session contents from memory (Storage object) are cleaned) Thus allowing the attacker access to logged in page without actually having to login.

So now I'm explicitly deleting the session file.

BTW - which method gets invoked when session has "expired" ?
Is there a "hook" where I can add the code to delete the session file - in addition to post_logout ?
This may be better than too frequent cron job with session2trash script.

-Mandar




 
 
What I want is something like sessions2trash.py script - except that file should deleted right away - even if the session has not expired.

Currently I'm using something like following. Please suggest correct way to handle this (I know this works only for file based sessions, but that is OK)

def post_logout(user):
   
try:
       
import os
        os
.unlink(response.session_filename) # Clear the session from disk
   
except OSError:
       
pass
    session
.renew(clear_session=True)  # Clear the memory/Storage object.

You shouldn't need that last line, as the logout function already does exactly that by default.

Anthony

--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/j-GwnDc0G6g/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Anthony

unread,
Oct 15, 2014, 4:59:13 PM10/15/14
to web...@googlegroups.com

In the current version of web2py, the default behavior is that upon logout, the session is cleared and renewed (i.e., a new session ID is issued). However, it does not delete the old session file.
When you say it "somehow doesn't work," do you just mean the old session file remains, or is something else not working?

Yes. Session file does not get deleted.
The side effect of session file remaining on the disk is that if the "hijacked" session ID is used by the attacker - then "somehow" contents of the session file on the disk are reused (even if session contents from memory (Storage object) are cleaned) Thus allowing the attacker access to logged in page without actually having to login.

It may be worth having web2py delete the file (or database record in the case of database based sessions) automatically upon session.renew(). Maybe submit a Google Code issue about this.

BTW - which method gets invoked when session has "expired" ?
Is there a "hook" where I can add the code to delete the session file - in addition to post_logout ?

First, although login can expire, sessions themselves do not expire (they simply terminate when the browser session ends by virtue of the fact that the browser will no longer transmit session cookies for old sessions).

In any case, there is no process that can monitor sessions/logins for expiration automatically (i.e., no place for a "hook"). The only "events" that the framework can respond to are requests, but an inactive client is not making any requests, so there would be nothing to trigger an expiration check. If you want to monitor logins for expiration and proactively delete session files or database records, you would have to run an external process (i.e., something like sessions2trash), perhaps using the scheduler or some other mechanism.

To prevent session hijacking, keep all logged in activity (including the login itself) over HTTPS. If you're still concerned, delete the session file upon logout (as you are now doing) and run sessions2trash periodically. Trying to delete the session file at the precise instant of login expiration will add little to overall security.

Anthony

Mandar Vaze

unread,
Oct 17, 2014, 2:30:27 PM10/17/14
to web...@googlegroups.com
On Thu, Oct 16, 2014 at 2:29 AM, Anthony wrote:

Yes. Session file does not get deleted.
The side effect of session file remaining on the disk is that if the "hijacked" session ID is used by the attacker - then "somehow" contents of the session file on the disk are reused (even if session contents from memory (Storage object) are cleaned) Thus allowing the attacker access to logged in page without actually having to login.

It may be worth having web2py delete the file (or database record in the case of database based sessions) automatically upon session.renew(). Maybe submit a Google Code issue about this.

 
browser will no longer transmit session cookies for old sessions).

But this is "normal" case - attacker can use/transmit "session cookies for old sessions" (which is where the whole discussion started)

In any case, there is no process that can monitor sessions/logins for expiration automatically (i.e., no place for a "hook"). The only "events" that the framework can respond to are requests, but an inactive client is not making any requests, so there would be nothing to trigger an expiration check.

I understand. I am not looking for "process".

I want to know which place in web2py code "determines" that for a normal request - session has expired and user should be redirected to "login" page - before the requested page is served ? (It attaches appropriate _next to the login form - so that after successful authentication - user is taken to the page s/he requested)

This is for my understanding of web2py innards better (may or may not help my current problem, but may give me some ideas/clues)
I want to put breakpoint, and trace this code - to understand this better.
 
To prevent session hijacking,
keep all logged in activity (including the login itself) over HTTPS.

Done.

If you're still concerned, delete the session file upon logout (as you are now doing)

Done.

and run sessions2trash periodically.

Will adding following (from sessions2trash.py docstring) be better if called immediately after successful login ?
This IMO ensures that session files are deleted after login attempt - especially when login was "forced" by the web2py framework due to expired session

    # Delete session in a module (move to the modules folder)
   
from sessions2trash import single_loop
   
def delete_sessions():
        single_loop
()


-Mandar


 
Trying to delete the session file at the precise instant of login expiration will add little to overall security.

Anthony
--

Anthony

unread,
Oct 17, 2014, 4:15:39 PM10/17/14
to web...@googlegroups.com
 
browser will no longer transmit session cookies for old sessions).

But this is "normal" case - attacker can use/transmit "session cookies for old sessions" (which is where the whole discussion started)

I was simply pointing out that sessions do not technically expire on the server side. The browser expires sessions by ceasing to return the session cookie. If an attacker steals the cookie and keeps sending it, then the server does nothing to expire the session. However, Auth logins can expire, but that is a different matter.
 
In any case, there is no process that can monitor sessions/logins for expiration automatically (i.e., no place for a "hook"). The only "events" that the framework can respond to are requests, but an inactive client is not making any requests, so there would be nothing to trigger an expiration check.

I understand. I am not looking for "process".

I want to know which place in web2py code "determines" that for a normal request - session has expired and user should be redirected to "login" page - before the requested page is served ? (It attaches appropriate _next to the login form - so that after successful authentication - user is taken to the page s/he requested)

This is login expiration, and it is checked in Auth.__init__: https://github.com/web2py/web2py/blob/master/gluon/tools.py#L1279

Note, there is no "hook" that will allow you to determine when login has expired. One trick that might work, though, would be to check for the existence of session.auth (which implies the user is logged in) right before initializing Auth, and then check again right after -- if session.auth exists before but not after, this implies that the login had expired (and auth was therefore removed from the session). You could then use that as a cue to delete the old session file (you must record the session ID prior to initializing Auth, as the session will be renewed by Auth.__init__ if the login has expired).

Of course, this only enables you to delete the session file upon an HTTP request of a logged in user whose login has expired. If the logged in user simply stops making requests, there will be no subsequent expiration checks to trigger the file deletion (you'll need sessions2trash to catch those files).
 
Will adding following (from sessions2trash.py docstring) be better if called immediately after successful login ?
This IMO ensures that session files are deleted after login attempt - especially when login was "forced" by the web2py framework due to expired session

    # Delete session in a module (move to the modules folder)
   
from sessions2trash import single_loop
   
def delete_sessions():
        single_loop
()


I'm not sure you want to run that in your app code, as it will loop through all the session files. You could consider triggering a task via the scheduler, but could be inefficient to do all that checking if you've got lots of logins. Probably better to delete individually identified session files when dealing with requests from individual users.

Anthony

Dave S

unread,
Oct 17, 2014, 5:51:18 PM10/17/14
to web...@googlegroups.com


On Friday, October 17, 2014 1:15:39 PM UTC-7, Anthony wrote:
I was simply pointing out that sessions do not technically expire on the server side. The browser expires sessions by ceasing to return the session cookie. If an attacker steals the cookie and keeps sending it, then the server does nothing to expire the session. However, Auth logins can expire, but that is a different matter.


What's the model for an attacker stealing a cookie?  Does it require access to the user's machine, or would a man-in-the-middle attack (with a wild proxy, for instance) work?

/dps

Anthony

unread,
Oct 17, 2014, 6:18:30 PM10/17/14
to web...@googlegroups.com

Can be done via MITM attack.

Niphlod

unread,
Oct 18, 2014, 2:15:51 PM10/18/14
to web...@googlegroups.com
that's why the whole thing goes away behind SSL. Expiring a session on logout is better than leaving it as it is, but even in that case while userA is logged in there's NO way to prevent a MITM from someone else.

Mandar Vaze / मंदार वझे

unread,
Oct 19, 2014, 2:48:49 PM10/19/14
to web...@googlegroups.com
On Sat, Oct 18, 2014 at 11:45 PM, Niphlod <nip...@gmail.com> wrote:
that's why the whole thing goes away behind SSL. Expiring a session on logout is better than leaving it as it is, but even in that case while userA is logged in there's NO way to prevent a MITM from someone else.

That is why in another email (https://groups.google.com/d/msg/web2py/Z3gjaLzM65E/DYtLhqJQH28J) I asked whether there is a way to "restrict" only one instance of userA logged in at any given point of time.
Off course it has its own issues :(

-Mandar

 


On Saturday, October 18, 2014 12:18:30 AM UTC+2, Anthony wrote:
On Friday, October 17, 2014 5:51:18 PM UTC-4, Dave S wrote:


On Friday, October 17, 2014 1:15:39 PM UTC-7, Anthony wrote:
I was simply pointing out that sessions do not technically expire on the server side. The browser expires sessions by ceasing to return the session cookie. If an attacker steals the cookie and keeps sending it, then the server does nothing to expire the session. However, Auth logins can expire, but that is a different matter.


What's the model for an attacker stealing a cookie?  Does it require access to the user's machine, or would a man-in-the-middle attack (with a wild proxy, for instance) work?

Can be done via MITM attack.

--
Reply all
Reply to author
Forward
0 new messages