pithos

Session handling for web applications


License
MIT
Install
pip install pithos==0.0.3

Documentation

Pithos

Simple, secure web session handling for Python applications.

WARNING: This project is currently under active development and should not be used in production environments. API's may change without support for previous versions.

Goals:

Straightforward to understand and implement.

Web framework/library independent;

Support for different storage back-ends;

Secure by default;

Why Pithos?

Pithos is ancient Greek for a large terracotta storage jar. While no terracotta has been used in this project, we do provide you with a large jar for cookie related storage ;-)

Overview

Pithos provides three concepts to handle sessions:

A session instance which acts like a Python dictionary and handles session state handling, serialization and encryption;

A storage back-end which knows how to store, retrieve and cleanup sessions;

A handler class which ties session instances and storage together and integrates this with the request and response handling of your web-application.

In addition helper functions are provided to handle login and logout of authenticated users.

Pithos is Python 2.7 and Python >= 3.4 compatible.

Initial setup

Install like this:

pip install pithos

Optionally install storage specific requirements:

pip install pithos[redis]

Usage of a web framework is not required. Pithos can be used in any Python code which provides generic web concepts such as HTTP requests and reponses with cookies.

Pithos provides ready to use integration with Flask. The Flask implementation can be used as a reference implementation for your own setup.

Flask

For Flask one can configure the Flask app like this:

from flask import Flask

from pithos.flask import setup_pithos
from pithos.filesystem import FilesystemStore

app = Flask()
pithos_store = FilesystemStore(root='/my/path/to/sessions')
setup_pithos(app, pithos_store)

Pithos leverages the Flask session interface, and can thus be used as a regular Flask session:

from flask import session

@app.route('/foo')
def foo():
    session['remember'] = 'me'
    return 'bar'

Django

TODO: Implement and document Django integration

Tornado

TODO: Implement and document Tornado integration. Probably needs a async storage backend.

WSGI

TODO: Show plain WSGI integration

Session instances

A session instance works similar to a regular Python dictionary, in fact it inherits from collections.MutableMapping.

Public attributes of sessions:

is_modified which indicates that the session has been modified. This is automatically set to True when manipulating keys on the session directly but should be manually set when modifying mutable data structures stored in the session (such as dictionaries and lists).

The following public methods can be called on a session instance:

set_duration(ttl=<int>): all sessions expire after a default period set in the handler. Specific sessions may have a specific duration which can be set using this method. This can be used to give privileged sessions a shorter duration.

reset(): clear anything stored in the session and forget its ID and encryption key. Most of the time you're better of using the delete_session method of the session handler because that also tries to resets the session cookie in an HTTP response.

Storage

Pithos sessions must be persisted somewhere, because it does not support storage of session content in cookies. Pithos currently provides plain file-system storage, and Redis backed storage. File-system storage is easy on memory usage while the Redis storage has the advantage of automatically removing expired sessions and using a central storage usable by multiple hosts.

Pithos uses JSON to serialize sessions, and in addition to natively supported data types also serializes UUID and datetime instances to strings (deserialization is not implemented).

Authenticated sessions

The pithos.authsession module contains a few helper functions to implement authenticated sessions related functions, such as login and logout.

These function work with the concept of a user checkvalue. This should be a JSON serializable value which changes when sensitive aspects of a user are changed, for example when its password or username changes. Whenever this checkvalue changes, all sessions of that user will become invalid. A sensible checkvalue could be constructed by calculating a digest over the users protected password and username as stored in the user database, or it could be random value stored with the user and which is updated every time the user updates its password.

The following functions are available:

get_user_id(session)

Retrieve the user ID from the session, return None when no user is set. Do not forget to run check_session immediately after retrieving the user instance.

get_user_extra(session)

Return a dictonary with extra user details stored with the user ID in the current session. This could be used to store which authentication method has been used to login.

login(session, user_id, checkvalue, **kwargs)

Login a user identified with user_id onto the session. Also stores the user checkvalue and optionally additional user related data using keyword arguments. The extra keyword arguments can later be retrieved using the get_user_extra function.

logout(session, response=None)

Destroys the current session and (optionally) sets an empty session cookie on the provided response.

keep_login(session, user_id, checkvalue)

Call this function when the users checkvalue deliberately changes, for example directly after the user successfully changes its password. This prevents the user from being logged out while all other sessions for this user become invalid.

check_session(session, checkvalue, response=None)

Checks if the users checkvalue matches. When the check fails, the session is reset and the function returns False.

Security

Pithos uses the excellent Python PyNaCl library which is a Python binding for NaCl.

  • Random 128 bits session ID's;

  • Sessions are stored encrypted and can only be read when in possession of the clients session cookie. Pithos uses authenticated encryption using NaCl Secret-key authenticated encryption (crypto_secretbox) (Salsa20 stream cipher + Poly1305 MAC for authentication);

  • Guaranteed session (server side) expiry in addition to session cookie expiry;

  • Optionally fix session to initial client IP address;

  • Only stores (JSON) data in sessions (not code, such as possible with Pickle);

  • Pithos provides helper functions to bind an authenticated user to a session. These helper functions prevent session fixation, needless session creation and invalidating authenticated sessions for a specific user.

Ideas / plans

  • Extend documentation and test suite

  • Optionally run session engine as daemon to use it from non-Python environments, use ZeroMQ and provide a Python client?;

  • Implement SQLAlchemy, Django ORM, and memcached backends;

  • Django, Tornado, bottle, webpy integration;

  • Provide example for plain WSGI usage.