By session timing I was referring to how long a session is valid for.

For example, a session is valid for 2 hours. This means the session is
valid for last_activity + 2 hours. Completely separate from the
session token process. So, if you leave the site and come back 90
minutes later, what happens is.

Session token is handed to server.
Session token is verified as a valid session token, because now -
last_activity is less than 120 minutes.
Your session token is regenerated because it's older than 5 seconds.
Because of that put operation your last_activity gets updated as well.

What I see as a concern with your approach is what happens when the
server wide variable R gets out of sync with someone's version that
was crypted based off of it? The original reason the 3 valid token
set

Now, one thought I've had is that really, sessions should be used for
logged in users in most cases. So one thing I will add sooner rather
than later is a class that will help you determine if you need to use
session at all.

class session_manager()
    def session_exists():
        """
        Check and see if the browser has a session cookie. Note,
because of the expire time set on the cookie by session, may be all
you ever need.
        """

    def delete_session_cookie():
        """"
        Clears the session cookie. Useful for if you check to see if a
session cookie exists, but the user is not logged in so you want to
clear it.
        """"

I'm using appenginepatch myself, with the django middleware bundled
with gaeutilities. I'll see what I can do about patching this to work
with this class in place when I do it.


Other than that, some approaches I'm considering.

1: I've made a request seeing if Google has some sort of session id
functionality they can give us. I think this should be possible based
off the fact they offer their user api. There has to be something in
the browser the application can access to tie that browser to the
logged in user session.

2: Going with memcache for the session token, with a datastore
fallback. Confirm memcache is working using the method to return the
memcache stats. If it is, then only use memcache. If it is down, use
the datastore. Of course when it goes down this would null out all
active sessions, which is undesirable. I have already seen a case
where memcache was down for applications, so this is a realistic
possibility.

3: A hybrid datastore/memcache solution with 2 cookies.Since there is
the 15 second window already. Store every third token in the database
and as an alternate cookie. Say session_id, and ds_session_id. Include
in the value a count, value--count, split on -- to get the token value
and the count. If the count is > 2, reset to 1 and set up the
ds_session_id cookie and store the value in the datastore. This would
be a write every 15 seconds through constant refreshes. Lengthening
the session token ttl will help reduce the amount writes, but will
increase the attack vector of spoofing.

Also, so many people are behind NAT's and/or using DHCP clients, I may
turn off IP verification by default, though will leave the option in
to use it.

On Jan 22, 11:12 pm, jeremy <jeremy.a...@gmail.com> wrote:
> Hmm, I'm not sure what "session timing" is.
>
> I have an idea to reduce writes. Instead of updating the sid of every
> session individually, give each session a random value between 0 and
> C, and have one application-wide value R randomized every
> session_token_ttl seconds to an integer between 0 and C, then hand the
> client the value of this as a token:
>
> t = (session_id+R)%C
>
> then when a client hands the server a token, you can compute
> session_id = (t-R)%C
>
> (you can store the last 3 values of R as is done now for each sessions
> sid)
>
> I'm pretty sure there's no analysis attack that would allow a client
> to figure out either R at any moment or their own (constant)
> session_id. But, i could be wrong about that :\ ... The advantage
> would be you're only updating a single datastore entity every
> session_token_ttl.
>
> On Jan 22, 9:24 pm, "bowman.jos...@gmail.com"
>
> <bowman.jos...@gmail.com> wrote:
> > I've gone with a different approach that currently achieves similar
> > results, that's now available in the trunk. A new variable,
> > last_activity_update has been added. It's the amount of seconds that
> > needs to pass before that field needs to be updated by doing a put().
> > It defaults to 60 seconds, which of course is longer than the duration
> > before a put is required to update the session token with the default
> > settings.
>
> > This will allow developers who wish to lengthen their
> > session_token_ttl to a larger interval to still get their
> > last_activity update in, useful for session timing. It too is
> > customizable so for developers who have no use for this field can set
> > it to a large enough number to be irrelevant.
>
> > I'm trying to flush out an idea I have to limit the amount of writes
> > for the token even further, but am still researching it. If I figure
> > it out I will get it in and do another release. Otherwise I will
> > release what's there now. Before any release I want to go over the
> > refactoring you did as it does look more efficient than what I
> > currently have, thanks.
>
> > On Jan 22, 6:31 pm, jeremy <jeremy.a...@gmail.com> wrote:
>
> > > Ok. I actually modified Session.__init__ locally to do the
> > > last_activity on sid rotation (i also refactored it a bit to reduce
> > > repeated code blocks). Regarding google.com's SID cookie - i'm not
> > > seeing the sid update within minutes. I'm not sure why yours rotates
> > > so quickly, but it's something entirely configurable in your code so
> > > it shouldn't matter. Anyway, here's my version of Session.__init__ :
>
> > >     def __init__(self, cookie_path=DEFAULT_COOKIE_PATH,
> > >             cookie_name=COOKIE_NAME,
> > > session_expire_time=SESSION_EXPIRE_TIME,
> > >             clean_check_percent=CLEAN_CHECK_PERCENT,
> > >             integrate_flash=INTEGRATE_FLASH, check_ip=CHECK_IP,
> > >             check_user_agent=CHECK_USER_AGENT,
> > >             set_cookie_expires=SET_COOKIE_EXPIRES,
> > >             session_token_ttl=SESSION_TOKEN_TTL):
> > >         """
> > >         Initializer
>
> > >         Args:
> > >           cookie_name: The name for the session cookie stored in the
> > > browser.
> > >           session_expire_time: The amount of time between requests
> > > before the
> > >               session expires.
> > >           clean_check_percent: The percentage of requests the will
> > > fire off a
> > >               cleaning routine that deletes stale session data.
> > >           integrate_flash: If appengine-utilities flash utility should
> > > be
> > >               integrated into the session object.
> > >           check_ip: If browser IP should be used for session
> > > validation
> > >           check_user_agent: If the browser user agent should be used
> > > for
> > >               sessoin validation.
> > >           set_cookie_expires: True adds an expires field to the cookie
> > > so
> > >               it saves even if the browser is closed.
> > >           session_token_ttl: Number of sessions a session token is
> > > valid
> > >               for before it should be regenerated.
> > >         """
>
> > >         self.cookie_path = cookie_path
> > >         self.cookie_name = cookie_name
> > >         self.session_expire_time = session_expire_time
> > >         self.clean_check_percent = clean_check_percent
> > >         self.integrate_flash = integrate_flash
> > >         self.check_user_agent = check_user_agent
> > >         self.check_ip = check_ip
> > >         self.set_cookie_expires = set_cookie_expires
> > >         self.session_token_ttl = session_token_ttl
>
> > >         # make sure the page is not cached in the browser
> > >         self.no_cache_headers()
> > >         """
> > >         Check the cookie and, if necessary, create a new one.
> > >         """
> > >         self.cache = {}
> > >         self.sid = None
> > >         string_cookie = os.environ.get('HTTP_COOKIE', '')
> > >         self.cookie = Cookie.SimpleCookie()
> > >         self.output_cookie = Cookie.SimpleCookie()
> > >         self.cookie.load(string_cookie)
>
> > >         dirty = False
>
> > >         # check for existing cookie
> > >         if self.cookie.get(cookie_name):
> > >             self.sid = self.cookie[cookie_name].value
> > >             self.session = self._get_session() # will return None if
> > > sid expired
> > >         else:
> > >             self.sid = self.new_sid()
> > >             self.session = None
>
> > >         if self.session is None:
> > >             # start a new session if there is None.
> > >             self.sid = self.new_sid()
> > >             self.session = _AppEngineUtilities_Session()
> > >             if 'HTTP_USER_AGENT' in os.environ:
> > >                 self.session.ua = os.environ['HTTP_USER_AGENT']
> > >             else:
> > >                 self.session.ua = None
> > >             if 'REMOTE_ADDR' in os.environ:
> > >                 self.session.ip = os.environ['REMOTE_ADDR']
> > >             else:
> > >                 self.session.ip = None
> > >             self.session.sid = [self.sid]
> > >             dirty = True
> > >         else:
> > >             # check the age of the token to determine if a new one
> > >             # is required
> > >             duration = datetime.timedelta
> > > (seconds=self.session_token_ttl)
> > >             session_age_limit = datetime.datetime.now() - duration
> > >             if self.session.last_activity < session_age_limit:
> > >                 self.sid = self.new_sid()
> > >                 if len(self.session.sid) > 2:
> > >                     self.session.sid.remove(self.session.sid[0])
> > >                 self.session.sid.append(self.sid)
> > >                 dirty = True
> > >             else:
> > >                 self.sid = self.session.sid[-1]
>
> > >         self.output_cookie[cookie_name] = self.sid
> > >         self.output_cookie[cookie_name]['path'] = cookie_path
> > >         if set_cookie_expires:
> > >             self.output_cookie[cookie_name]['expires'] =
> > > self.session_expire_time
>
> > >         self.cache['sid'] = pickle.dumps(self.sid)
>
> > >         if dirty:
> > >             self.session.put()
>
> > >         #self.cookie.output()
> > >         print self.output_cookie.output()
>
> > >         # fire up a Flash object if integration is enabled
> > >         if self.integrate_flash:
> > >             import flash
> > >             self.flash = flash.Flash(cookie=self.cookie)
>
> > >         # randomly delete old stale sessions in the datastore (see
> > >         # CLEAN_CHECK_PERCENT variable)
> > >         if random.randint(1, 100) < CLEAN_CHECK_PERCENT:
> > >             self._clean_old_sessions()
>
> > > On Jan 22, 4:38 pm, "bowman.jos...@gmail.com"
>
> > > <bowman.jos...@gmail.com> wrote:
> > > > I think it's a case of it's been that way for so long I haven't
> > > > realized I need to change it. The put on every write to update the
> > > > last activity, I mean. I'll look into modifying it so that it only
> > > > writes when the session token changes.
>
> > > > As for google though, every time I load up my igoogle page, I have
> > > > cookie called SID for thewww.google.comthatchangeseachpage view.
> > > > This is really as it should be for real security, as even the 15
> > > > second window I have configured by default it more that large enough
> > > > for someone to write a script very quickly to sniff and grab the
> > > > cookie to be used to hijack the session.
>
> > > > Modifying the last_activity to update less frequently is a good idea,
> > > > I will try to get that in soon.
>
> > > > On Jan 22, 2:08 pm, jeremy <jeremy.a...@gmail.com> wrote:
>
> > > > > Bowman - I think my issue with gaeutilities may largely be that the
> > > > > default settings seem excessive. Looking at the cookies google.com
> > > > > hands its visitors, their SID cookie lasts a good decade and seems to
> > > > > rotate every few hours, not seconds. So at the moment i'm thinking
> > > > > I'll see if changing the default satisfies me.
>
> > > > > Also, at the moment there's a datastore put() on every session-using
> > > > > request to (at a minimum) update the last activity time stamp. But if
> > > > > my SESSION_TOKEN_TTL is something like 1 hour, then actually i only
> > > > > need to update the last activity time stamp if the last timestamp was
> > > > > more than an hour ago. That would significantly reduce the amount of
> > > > > datastore writes, no?
>
> > > > > re: "I'm just trying to figure out the value in the signed cookie
> > > > > approach, because if I can figure out a way for it to
>
> ...
>
> read more »
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To post to this group, send email to google-appengine@googlegroups.com
To unsubscribe from this group, send email to 
google-appengine+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to