How to delete a particular key(for current session) from Flask-KVSession?
Question: I am using Flask kvsession to avoid replay attacks, as the client side cookie
based session used by Flask-login are prone to it. Eg: If on /index page your
cookie in the header is set for your app header like myapp_session : 'value1'
and if you navigate to /important page you will get a new header like
myapp_session : 'value2' so if a hacker gets 'value1' he can perform replay
attacks and misuse it, as it is never invalidated.

To solve this I am using flask-kvsession which stores the session cookie
header value in a cache or some backend. SO basically only one myapp_session
is generated and invalidated when you logout. But the problem is :-

    
    
    __init__.py 
    
    from simplekv.memory.redisstore import RedisStore
    import redis
    
    store = RedisStore(redis.StrictRedis())
    #store = memcache.Client(['127.0.0.1:11211'], debug =0)
    store.ttl_support = True
    app = create_app(__name__)
    current_kvsession = KVSessionExtension(store, app)
    

If you look at the cleanup_session part of the code for kv-session
<http://pythonhosted.org/Flask-
KVSession/#flask_kvsession.KVSessionExtension.cleanup_sessions>

It only deletes the expired sessions. But If I want to explicitly delete the
value for the current myapp_session for a particular user on logout, how do I
do that?

    
    
    @app.before_request
    def redirect_if_logout():
      if request.path == url_for('logout'):
          for key in app.kvsession_store.keys():
            logger.debug(key)
            m = current_kvsession.key_regex.match(key)
            logger.debug('found %s', m)
            app.kvsession_store.delete(key)
    

But this deletes all the keys as I don`t know what the unique key for the
current session is.

Q2. Also, how to use memcache instead of redis as it doesn`t have the
app.kvsession_store.keys() function and gives i/o error.


Answer: I think I just figured the 1st part of your question on how you can delete the
specific key on logout.

As mentioned in the docs:

> Internally, Flask-KVSession stores session ids that are serialized as
> KEY_CREATED, where KEY is a random number (the sessions “true” id) and
> CREATED a UNIX-timestamp of when the session was created.

Sample cookie value that gets created on client side (you can check with that
cookie manager extenion for firefox):

> c823af88aedaf496_571b3fd5.4kv9X8UvyQqtCtNV87jTxy3Zcqc

and session id stored in redis as key:

> c823af88aedaf496_571b3fd5

So on logout handler, you just need to read the cookie value, split it and use
the first part of the string:

Sample Code which worked for me:

    
    
    import redis
    from flask import Flask
    from flask_kvsession import KVSessionExtension
    from simplekv.memory.redisstore import RedisStore
    
    store = RedisStore(redis.StrictRedis())
    
    app = Flask(__name__)
    KVSessionExtension(store, app)
    
    #Logout Handler
    @app.route('/logout', methods=['GET'])
    def logout():
        #here you are reading the cookie 
        cookie_val = request.cookies.get('session').split(".")[0]
        store.delete(cookie_val)
    

and since you have added ttl_support:

    
    
    store.ttl_support = True
    

It will match the TTL(seconds) value from permanent_session_lifetime, if you
have set that in config file or in the beginning of your app.py file.

For example, in my application I have set in the beginning of app.py file as:

    
    
    session.permanent = True
    app.permanent_session_lifetime = timedelta(minutes=5)
    

now, when I logout, it deletes the key in redis but it will not be removed
until TTL for that turns to 0 from 300 (5 Min as mentioned in
permanent_session_lifetime value ).

If you want to remove it from redis immediately, for that you can manually
change the app.permanent_session_lifetime to 1 second, which will in turn
change TTL for redis.

    
    
    import redis
    import os
    from flask import Flask
    from flask_kvsession import KVSessionExtension
    from simplekv.memory.redisstore import RedisStore
    
    store = RedisStore(redis.StrictRedis())
    
    app = Flask(__name__)
    KVSessionExtension(store, app)
    
    #Logout Handler
    @app.route('/logout', methods=['GET'])
    def logout():
        cookie_val = request.cookies.get('session').split(".")[0]
        app.permanent_session_lifetime = timedelta(seconds=1)
        store.delete(cookie_val)
    

Using the above code, I was able to thwart session replay attacks.

**and solution to your 2nd question:**

3 possible mistakes that I can see are:

1: In the beginning of your code you have created:

    
    
    store = RedisStore(redis.StrictRedis())
    

but in the loop you are using it as kvsession_store instead of just store:

    
    
    app.kvsession_store.keys()
    

  2. To use it without any errors/exceptions you can use it as `store.keys()` instead of app.store.keys():
    
        from flask_kvsession import KVSessionExtension
    from simplekv.memory.redisstore import RedisStore
    store = RedisStore(redis.StrictRedis())
    
    for key in store.keys():
        print key
    

  3. `store.delete(key)` is not deleting the all keys, you are running it inside the loop which is one by one deleting all keys.

