I understand that a session is server side, and not externally visible.
For this reason can it be used to store a User class (username/ hashed
password) safely?
Or do I need to check whats in the session against the user table every
time I access a controller?
I’m not sure what the Rails philosophy is on this, but I typically just
check for a :login attribute in my session hash and if it doesn’t exist,
redirect the user to a login controller in order to authenticate them.
I’d also love to hear if there’s a better or more secure way to do this.
Seems ok to me. If you’re not storing the User object, you’d need to
store something in there to remember their credentials anyway. Either
way, your session data is critical to your security.
As with all security, it’s a trade off. Checking the database makes it
more difficult for an attacker who can modify session data somehow, but
it’s an extra database query each time.
I’m confident enough that my code won’t allow an attacker to modify
session data. I think I’d have to really fsck up for that to happen.
I understand that a session is server side, and not externally visible.
For this reason can it be used to store a User class (username/ hashed
password) safely?
Or do I need to check whats in the session against the user table every
time I access a controller?
You’re correct, session data only exists on the server, so it’s safe, so
you can
store whatever is convienient in it for identifying authenticated users.
On the other hand, the way you map users to session data is via a key
that is
stored in a cookie on the client side, and that key is transmitted over
the
network in the clear (unless you’re using https), so the session key is
a
possible source of mischief. For example, there are attacks where the
attacker
tries to intercept the user’s session key in transit, or off the user’s
machine,
and then uses it to masquerade as that user. There are also “session
fixation”
attacks (see AWDR p. 445-446, and http://www.windowsecurity.com/whitepaper/uplarticle/11/session_fixation.pdf)
that you have to watch out for.
If you’re worried about these kinds of attacks there are some simple
things you
can do; for example:
Delete session data (reset_session) when the user logs out, so their
session
key can’t be used again.
Store the user’s IP address in their session hash; every time invoke a
controller, verify that their current IP address (request.remote_ip)
matches
what the session hash says it should be. This prevents (or at least,
makes it
more difficult) for someone who intercepts the key to use it.
Store an expiration date/time in the session; when a controller is
invoked,
check that the session hasn’t expired; again, this just makes life more
difficult for an attacker.
I understand that a session is server side, and not externally visible.
For this reason can it be used to store a User class (username/ hashed
password) safely?
Or do I need to check whats in the session against the user table every
time I access a controller?
You’re correct, session data only exists on the server, so it’s safe, so
you can
store whatever is convienient in it for identifying authenticated users.
On the other hand, the way you map users to session data is via a key
that is
stored in a cookie on the client side, and that key is transmitted over
the
network in the clear (unless you’re using https), so the session key is
a
possible source of mischief. For example, there are attacks where the
attacker
tries to intercept the user’s session key in transit, or off the user’s
machine,
and then uses it to masquerade as that user. There are also “session
fixation”
attacks (see AWDR p. 445-446, and http://www.windowsecurity.com/whitepaper/uplarticle/11/session_fixation.pdf)
that you have to watch out for.
If you’re worried about these kinds of attacks there are some simple
things you
can do; for example:
Delete session data (reset_session) when the user logs out, so their
session
key can’t be used again.
Store the user’s IP address in their session hash; every time invoke a
controller, verify that their current IP address (request.remote_ip)
matches
what the session hash says it should be. This prevents (or at least,
makes it
more difficult) for someone who intercepts the key to use it.
Store an expiration date/time in the session; when a controller is
invoked,
check that the session hasn’t expired; again, this just makes life more
difficult for an attacker.
–Forrest
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.