Re: Replay attacks with cookie session

Jeremy Evans
2007-03-23T16:45:14Z

On 3/23/07, Jeremy Kemper <jeremy@bitsweat.net>
wrote:
> Let''s talk about practical fixes rather than whether we should
write
> it off entirely.
>
> An application-level solution to user_id replay:
>
>   Per request:
>     @current_user > User.find_by_id_and_last_seen_at(session[:user_id],
> session[:last_seen_at])
>
>   On login:
>     @current_user.update_attribute :last_seen_at, Time.now
>     session[:user_id] = @current_user.id
>     session[:last_seen_at] = @current_user.last_seen_at
>
>   On logout:
>     @current_user.update_attribute :last_seen_at, Time.now
>     reset_session
>
> This requires one additional database query on logout to invalidate
> future reuse of that session and no additional per-request queries.

This assumes you are doing a query per request anyway, and basically
piggy backing on it for the security.  If your application is already
doing a query for the current user for every request, sure, there''s
almost no additional cost.  However, if your application isn''t doing a
query per request, you have to add one to get the security, which
makes the cost the same as using the database for session storage.

IMO, this is not a problem that the application developer should need
to deal with manually, any more than application developers should
handle database transactions manually.  If cookie based session
storage is going to remain the default:

1) There should be a configurable timeout set automatically, with a
reasonable default (to partially mitigate the replay issue)
2) It should be documented that replay attacks are still possible
3) Advice on creating application specific solutions such as the one
you mentioned should be included in the documentation

Note that timeouts provide only slight additional security, as they
only protect against attackers who get access to a session cookie
after it has already expired.  If an attacker gets access to any
session cookie before it expires, they can keep that session open
indefinitely.

Jeremy