serversession/yesod-persistent-session/README.md
2015-05-22 23:34:24 -03:00

132 lines
5.2 KiB
Markdown

# yesod-persistent-session
Server-side session backend using persistent.
This package implement traditional server-side sessions. Users
who don't have a session yet are assigned a random 144-bit
session ID that is the key on a database table kept by
persistent. All session data is saved on the database.
The session ID stays fixed most of the time. Anonymous users
receive session IDs unless their session remains empty (as an
optimization). The session ID can be invalidated in order to
prevent
[session fixation attacks](http://www.acrossecurity.com/papers/session_fixation.pdf),
either automatically (see below) or manually (via
`forceInvalidate`).
## Authentication integration
We have special support for `yesod-auth`:
* The `_ID` session key used by `yesod-auth` is recognized and
saved separately on the database. This allows you to quickly
identify all sessions of a given user. For example, you're
able to implement a "log out everywhere" button.
* Whenever the `_ID` changes, the backend will also invalidate
the current session ID and migrate the session data to a new
ID. This prevents session fixation attacks while still
allowing you to maintain session state accross login/logout
boundaries.
If you wish to use a different authentication mechanism and still
enjoy the advantages above, just use the same `_ID` session key.
## Current limitations
* All sessions use persistent cookies.
* We support SQL backends only, such as
`persistent-postgresql`. The code has to fix upfront which
persistent backend is used.
## Background
Yesod has always support client-side sessions via the
[`clientsession`](http://hackage.haskell.org/package/clientsession)
package: the session data is encrypted, signed, encoded and sent
to the client inside a cookie. When receiving a request, the
cookie is decoded, verified and decrypted. The server does not
have to maintain any state, so the client-side session backend is
as fast as the cryptographic primitives.
However, there are some disadvantages to client-side sessions:
* _Replay attacks_. It's not possible to invalidate a session,
for example. When logging out, a new cookie is sent with
logged out session data. However, as the server doesn't
maintain state about sessions, it will still accept the old,
logged in cookie until it expires. One could set very small
expiration times to mitigate this, but this would force users
to relogin frequently. This server-side backend allows you
to maintain long expiration times while still having secure
logouts.
* _Cookie size_. As the cookie contain the whole session data
plus some overhead, care must be taken not to create too much
session data. Yesod already saves the logged in user ID via
`yesod-auth` and a XSRF token via `yesod-form`. This
server-side backend uses a cookie of fixed size (24 bytes).
* _No remote logout_. In many instances it is desirable to
invalidate sessions other than the current one. For example,
the user may have changed their password, or the the site
provides a button to cancel all logged in sessions besides
the current one. This server-side backend allows you to
invalidate sessions other than the current one via
`forceInvalidate`.
* _Missing key rotation_. Ideally, `clientsession`'s keys
should be rotated periodically. In practice, support for key
rotation has never been implemented on `clientsession`. This
server-side backend does not need to do key rotations, and
the session ID CPRNG is automatically reseeded.
If you're concerned about any of the points above, you've come to
the right package!
## Comparision to other packages
At the time of writing (2015-05-22), these are the session
packages that do not use either `clientsession` or
`serversession`:
* `mysnapsession` (via `Memory` module, also supports
`clientsession` mode): Server-side sessions. Works for
`snap`. Weak session ID generation. Vulnerable to session
fixation attacks. Cannot invalidate other sessions.
* `salvia-sessions`: Server-side sessions. Works only for
`salvia`. No built-in support for DB-backed sessions, only
memory-backed ones. Weak session ID generation. Vulnerable
to session fixation attacks. Cannot invalidate other
sessions.
* `simple-session`: Client-side sessions. Works for `simple`
framework. No encryption. Authentication vulnerable to
timing attacks.
* `Spock` (formely `scotty-session`): Server-side sessions.
Works for `Spock` (code is not packaged separately). Only
supports memory-backed sessions persisted on a file. Weak
session ID generation. Vulnerable to session fixation
attacks. Cannot invalidate other sessions.
* `wai-session`: Server-side sessions. Works for `wai`
applications. Weak session ID generation. Vulnerable to
session fixation. Cannot invalidate other sessions.
Out-of-the-box support for TokyoCabinet only.
* `yesod-session-redis`: Server-side sessions. Works for
Yesod and Redis. Weak session ID generation via `random`.
Vulnerable to session fixation. Cannot invalidate other
sessions.
We apologize in advance if any information above is incorrect.
Please contact us about any errors.