Example:
1. User receives credits, stored in his session
2. User buys something
3. User gets his new, lower credits stored in his session
4. Evil hacker takes his saved cookie from step #1 and pastes it back
in his browser's cookie jar. Now he's gotten his credits back.
This is normally solved using something called nonce - each signing
includes a once only code, and the signer keeps track of all of the
codes, and rejects any message with the code repeated. But that's
very hard to do here, since there may be several app servers
(mongrels).
Of course, we could store the nonce in the DB - but that defeats the
entire purpose!
You and I think alike. I was just considering this the other day as
well. The trivial fix is to say "don't store sensitive transient data
in the session". I think that leaves something to be desired, but it
is probably the preferred route unless there is a clean technical
solution.
Interesting, I hadn't considered that scenario.
> This is normally solved using something called nonce - each signing
> includes a once only code, and the signer keeps track of all of the
> codes, and rejects any message with the code repeated. But that's
> very hard to do here, since there may be several app servers
> (mongrels).
This sounds like something you could perform at the application level.
jeremy
On Mar 21, 3:28 pm, "Jeremy Kemper" <jer...@bitsweat.net> wrote:
> On 3/21/07, S. Robert James <srobertja...@gmail.com> wrote:
>
> > I'm concerned about the possibility of replay attacks with cookie
> > sessions. This is a standard security issue.
> Interesting, I hadn't considered that scenario.
IMO, we need to rethink moving to cookie sessions by default, then -
if a core member hadn't thought about, what can we expect from
beginners? Last thing we need is a reputation for being weak in
security.
Before everyone responds: "It will help performance, and good
developers don't store volatile data in the session, anyway!" I'll say
that we've seen lots of companies (who won't be named) sacrifice
security in order to gain out of the box performance or ease of use -
and it comes back to haunt them. Secure by default, and let the
advanced users make it less secure to improve performance - not the
other way around.
>
> > This is normally solved using something called nonce - each signing
> > includes a once only code, and the signer keeps track of all of the
> > codes, and rejects any message with the code repeated.
> This sounds like something you could perform at the application level.
I don't think so - as long as step 2 (in my example) goes to one
Mongrel, and step 4 goes to another, the attack succeeds. I can try
repeatedly with a script until this happens. The only way to protect
is to use a shared backend like the DB or DRB - but then you've lost
the point of cookie sessions.
I think that's a bit sensational. The cookie store has gone through a
couple of evolutionary steps already and is ready for more, if need
be.
> Before everyone responds: "It will help performance, and good
> developers don't store volatile data in the session, anyway!" I'll say
> that we've seen lots of companies (who won't be named) sacrifice
> security in order to gain out of the box performance or ease of use -
> and it comes back to haunt them. Secure by default, and let the
> advanced users make it less secure to improve performance - not the
> other way around.
Let's see a brainstorm of solutions and other potential vulnerabilities.
> > > This is normally solved using something called nonce - each signing
> > > includes a once only code, and the signer keeps track of all of the
> > > codes, and rejects any message with the code repeated.
>
> > This sounds like something you could perform at the application level.
> I don't think so - as long as step 2 (in my example) goes to one
> Mongrel, and step 4 goes to another, the attack succeeds. I can try
> repeatedly with a script until this happens. The only way to protect
> is to use a shared backend like the DB or DRB - but then you've lost
> the point of cookie sessions.
To some degree. I'm sure there's more to this, though. I'm not a crypto expert.
jeremy
I'm saddened that many recent Rails books don't seem to cover this
issue. If the problem had more clarity and direction I think that'd
go a long way to easing enterprises into the Rails community.
Preston
On Mar 21, 2:26 pm, "Jeremy Kemper" <jer...@bitsweat.net> wrote:
You and I think alike. I was just considering this the other day as
well. The trivial fix is to say "don't store sensitive transient data
in the session".
Heh... how about a user ID? What if an evil hacker sets it to 1, assuming that the first user is likely to be admin?
He can't, the HMAC wouldn't verify.
> I'm neither a Rails nor cryptography expert, but the threat of
> session hijacking is a very important issue
It's an important issue when you're trying to have a secure session.
When you're just using the session for some flash variables I don't
see the point in using an overly secure session system.
I think we should document the various session stores very well and
tell people what to use in which circumstances.
Developers aren't small children, we don't have to make their
decisions for them.
Manfred
--
Fingertips - http://www.fngtps.com
Phone: +31 (0)6 24204845
Skype: tvandervossen
MSN Messenger: th...@fngtps.com
iChat/AOL: t.vande...@mac.com
Jabber IM: th...@jabber.org
Your example scenario is unrealistic. If you really think it's a good
idea to store such important stuff as your user's credit in a session
instead of in your database you probably have bigger issues to worry
about. :)
As long as you only use the session to maintain the id of the
authenticated user and for flash messages there's absolutely nothing
to worry about.
Kind regards,
Thijs
P.S. If you really _do_ think it's a good idea to store your user's
credit in the session, please google for 'share-nothing' and
'database transactions' and do some reading.
As long as you only use the session to maintain the id of the
authenticated user and for flash messages there's absolutely nothing
to worry about.
It's even more complicated. Defining "sensitive or transient data" is
not at all trivial.
The standard use case for a cookie session is store only flash and
user id. Not sensitive or transient? Okay.
Now, I click "Log Out", and get up from the library's computer, only
to let the person waiting after me to retrieve the old cookie.... That
innocuous user id just became both sensitive and transient.
The point is, answering these questions is hard. Witness the
confusion in this thread alone. DIY cryptosystems are hard:
professionals fail. WEP failed. Does it make sense to push all these
questions onto each new Rails developer's shoulders?
And I think that is exactly what it comes to. That's kind of where I
landed with that post when I started considering what user_id really
meant.
As neat as cookie sessions are, I don't think I'm going to use them
to store authentication info anymore. Too many question marks.
Have an after_filter that adds a "single-use" token to the cookie after a request and a before_filter that checks for the "single-use" token when a user makes a new request.
You click 'log out' and it deletes the cookie.
This is no different to a normal server-based session.
court3nay
Oh, but it is. With a server-based session, I "Log Out" and my
session can be purged from the server, leaving the old session ID
worthless. With cookie sessions, the cookie is still valid to the
server even if deleted from the browser's cookie repo. There is no
way to selectively expire sessions from the server.
Server-side: someone gets my session ID, I log out, they present the
session ID to the server -> worthless.
Client-side: someone gets my session cookie, I log out, they present
the cookie to the server -> impersonation!
You're forgetting that:
(a) sessions already use cookies to store the session ID, so any
issues with cookie interception or other attacks apply to all session
storage methods.
(b) you can't change the contents of the cookie or it will fail the HMAC.
If you're overly concerned with "user_id" haxoring, just use a guid
instead of DB id in your User.find
court3nay
Umm... did you read the thread? No, I'm not forgetting any of that,
and those are not my points at all.
(a) Cookie sessions are vulnerable to replay attacks, because the
client can present *any* cookie that it has seen to the server, not
just the most recently sent one. On the other hand, server-side
storage methods are not vulnerable because the session ID always
references the latest version of the session.
(b) Of course the HMAC would fail if you change the session. I'm not
talking about changing the session. I never was. What worries me is
this:
1. I log in; I get session cookie A which corresponds to
"user_id=12345" with the HMAC and everything.
2. I log out and my session cookie is "deleted" -- in the sense of
not being presented to the server anymore. It may hang out on disk or
memory.
3. Someone finds the session and presents it to the server. Since it
is signed by the server, it is accepted and that user is logged in.
Suddenly, a token which had no value after logout (a session ID) now
has immense value (session cookie) because possession of it allows
one to impersonate me at any time in the future.
It's possible mitigate the problem somewhat by having an expiration
time put into the session (which cannot be modified by an attacker due
to the HMAC). However, you still won't be able to manually expire
sessions (i.e. log out).
Jeremy
This is the best idea I've seen so far, but it still requires
balancing the attack window (as small as possible) against the
maximum allowed time between requests. Given that replay attacks can
be automated, the acceptable values for these numbers may or may not
overlap, depending on the application.
On Mar 22, 3:08 pm, Courtenay <court3...@gmail.com> wrote:
> You're forgetting that:
> (a) sessions already use cookies to store the session ID, so any
> issues with cookie interception or other attacks apply to all session
> storage methods.
Not true. Example: if, on logout, you update the session in the DB to
state "No User", the cookie is worthless.
> (b) you can't change the contents of the cookie or it will fail the HMAC.
Yes, but you can replay them. See my first post.
> If you're overly concerned with "user_id" haxoring, just use a guid
> instead of DB id in your User.find
Won't help - see earlier posts.
On Mar 22, 3:21 pm, "Jeremy Evans" <jeremyeva...@gmail.com> wrote:
> It's possible mitigate the problem somewhat by having an expiration
> time put into the session (which cannot be modified by an attacker due
> to the HMAC). However, you still won't be able to manually expire
> sessions (i.e. log out).
This will only help in cases where the attacker wants to steal
someone's identity. But there are other uses of a replay attack -
like the example I initially mentioned - where this won't help at
all. And even in the identity theft case - what's to stop the
attacker from using the computer 5 minutes after I leave?
In general, I'd offer the amount of confusion on this thread as the
best evidence that the average developer shouldn't have to deal with
these issues by default.
Avoiding a single database lookup isn't the purpose of the cookie store.
> As for the opt-in, if you're the type of user that would know enough about
> security to opt in to such a plan, you're probably not storing account
> balances in a client-side cookie. The discussion we are having concerns
> sensible defaults.
This discussion skipped plugging the session replay hole. I understand
your concern, but I think you underestimate the average Rails
developer.
For example: to prevent user_id replay, store a last access timestamp
in session that's updated on login and logout.
jeremy
(b) you can't change the contents of the cookie or it will fail the HMAC.
If you're overly concerned with "user_id" haxoring, just use a guid
instead of DB id in your User.find
court3nay
It's worth remembering the downsides to our current default.
Deploying to a 'real' production setup with it is a shortcut to a
heart attack. File locking, mongrel deadlocking, NFS churn. All of
those are real problems which hurt developers every day.
That most applications *already* change their session store indicates
that it's not that big a deal. If you're currently doing something
which is incompatible with the assumptions of the cookie store,
switch. I'm still using sql sessions and intend to continue doing so
:).
--
Cheers
Koz
>
> On 3/22/07, Brad Ediger <br...@bradediger.com> wrote:
>> This was discussed earlier in the thread. The problem is that such
>> a nonce
>> would require communication between the backend servers via DRb or
>> the
>> database, which removes any benefit from storing the cookies
>> client-side.
>> You might as well store the whole session in the database or DRb
>> store.
>
> Avoiding a single database lookup isn't the purpose of the cookie
> store.
Sure, but you do remove a lot of the glamour of the cookie store if
it has to be tied to a database for a nonce lookup anyway.
>> As for the opt-in, if you're the type of user that would know
>> enough about
>> security to opt in to such a plan, you're probably not storing
>> account
>> balances in a client-side cookie. The discussion we are having
>> concerns
>> sensible defaults.
>
> This discussion skipped plugging the session replay hole. I understand
> your concern, but I think you underestimate the average Rails
> developer.
I might be over-concerned here, but I'm not talking about the average
Rails developer. I'm talking about the worst ones. I can tell you
that while the average Rails developer I've worked with would
certainly be able to understand this and work around it, I'm not sure
that the worst ones would even understand what the issue was if it
were explained to them.
> For example: to prevent user_id replay, store a last access timestamp
> in session that's updated on login and logout.
If I understand you correctly, you would also keep a copy of the
latest timestamp server-side. I would submit that for many
developers, storing a timestamp for each session on the server is not
much more attractive than just storing the whole session on the server.
be
This is a good point. The CookieStore is a major improvement over
PStore from a functional perspective. We are arguing over things that
are important to discuss, but still very, very small compared to that.
On Mar 22, 8:27 pm, "Jeremy Kemper" <jer...@bitsweat.net> wrote:
> For example: to prevent user_id replay, store a last access timestamp
> in session that's updated on login and logout.
Store the last access *where*?
In Mongrel? But only one Mongrel can know that without them talking to
each other.
In the DB? So we need to hit the DB each time, only we need to do it
manually?
In a temp file? That's back to the default session store.
In the cookie itself? We haven't solved the problem. If the attacker
fishes out an older cookie - and, believe me, they're still on the
disk - he does a replay attack.
I think this is a fair question: most of the people arguing that
cookie stores are safe have also pointed out that they're not crypto
experts. Or security experts. Which is fine - I'm sure their top
notch developers. Before making something which relies on crypto the
Rails default, doesn't it make sense to have at least _one_ crypto or
security consultant review it? Perhaps Schneier will take a look...
SRJ, over-and-out
If you'd like to coordinate this, I'd definitely be glad to hear from
them. As it stands I think your complaint boils down to the lack of
server-side invalidation of a session. Most everything else flows
from that. I'm not sure that there's a shared nothing way to take
care of that, but the crypto experts would know for sure.
Please do investigate having someone conduct a review.
--
Cheers
Koz
My feeling (this is what I did) is that this happens because they *got
bitten* by the default session store problems, the effects are visible
(mainly the performance issues).
> If you're currently doing something
> which is incompatible with the assumptions of the cookie store,
> switch.
this could be solved by clearly documenting this assumptions (and
perhaps giving suggestions)
> I'm still using sql sessions and intend to continue doing so
> :).
hmm... how about defaulting to these (at least for the production
environment)?
Luca
--
Web: http://spazidigitali.com - http://thetyper.com
Email mailto://luca.m...@gmail.com
Skype callto://l.mearelli
--
>
> Pulling two IDs (session id + nonce) from the DB is better than
> pulling 80k that could go in cookies. Why not include nonce in the
> default, and if the developer wants the blazing speed (and
> corresponding dangers), they can disable it?
80k cannot go in cookies. On most platforms the limit is 4k. The
CookieStore raises an error if you try to store too much.
And it's a difference between grabbing the data from the DB to
deserialize it and grabbing it from a cookie to deserialize it. The
main driver isn't performance -- it's not having to keep all of those
sessions around on the web server.
Smudge her mascara a little; she's still sexy in the morning.
I already User.find(session[:user_id]) per request, so perhaps my
expectations are different from yours.
> > This discussion skipped plugging the session replay hole. I understand
> > your concern, but I think you underestimate the average Rails
> > developer.
>
> I might be over-concerned here, but I'm not talking about the average
> Rails developer. I'm talking about the worst ones. I can tell you
> that while the average Rails developer I've worked with would
> certainly be able to understand this and work around it, I'm not sure
> that the worst ones would even understand what the issue was if it
> were explained to them.
I don't think you're over-concerned. However, attempts to find a
solution are not argument that session replay isn't a problem.
> > For example: to prevent user_id replay, store a last access timestamp
> > in session that's updated on login and logout.
>
> If I understand you correctly, you would also keep a copy of the
> latest timestamp server-side. I would submit that for many
> developers, storing a timestamp for each session on the server is not
> much more attractive than just storing the whole session on the server.
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.
Anyone care to try a generic, automatic nonce and benchmark the results?
jeremy
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
Good points. I worked up a quick plugin that uses DRb to store the nonce, and I'm doing some benchmarks on it now. I don't have time for anything fancy, but we can at least get in the ballpark.
...
> > 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.
That assumption is stated at the beginning of the example:
> > An application-level solution to user_id replay:
You reason that touching the database "makes the cost the same as
using the database for session storage" which is likely wrong and
certainly unsubstantiated.
Criticism is great and welcome, everyone, but let's add some
creativity and code to the mix, please.
> 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:
We all agree on this. We're working on it.
> 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
Good ideas.
> 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.
Not in the scenario above: the legitimate user logging out invalidates
the attacker's session, which is the same behavior as a server-side
session.
jeremy
http://tools.ietf.org/html/rfc2109
"at least 4096 bytes per cookie ... at least 20 cookies per unique
host or domain name"
Is there something in today's cookie implementation that prevents
someone from doing 20 cookies at 4k each?
I defer to my original statement:
>> The CookieStore raises an error if you try to store too much.
There is a hard-coded 4k limitation in the store, and the store will
only use one cookie per session.
Will do - I'll speak to some of my contacts and see if they're willing
to do a short review, pro bono.
> I'm not sure that there's a shared nothing way to take
> care of that
Exactly. Basically, you can mathematically prove that the only way to
avoid replay attacks is with some type of trusted store. Which of
course needs to be shared.
@Brad - Great work on setting up some code for benchmarking. I
haven't reviewed your code, but doing nonces correctly gets into some
sticky synchronization and concurrency. Basically, the system needs
to make sure that:
* The nonces used by all of the Mongrels are kept track of (eg one
counter per Mongrel)
* No Mongrel uses the same nonce (eg prefix the nonce with the
Mongrel's pid)
* That the issuing a nonce, restoring a session, and then invalidating
the nonce are all done in the correct order. This can get very
tricky:
Specifically, we need to make sure that once the session has been
modified, its nonce is invalidated immediately. At the same time, we
can't invalidate it before a new session has been assigned, or those
requests will be incorrectly rejected. This gets very, very tricky
when you're dealing with multiple overlapping requests: invalidate too
soon, and you've broken pipelining. Invalidate too late, and you're
subject to replay attacks. Like I said, crypto is hard: amateur
cryptosystems are usually broken with relish.
@Jeremy - you're raising a good issue. I think it would be beneficial
to define exactly what the goals of cookie sessions are. Performance?
Less administrative setup? Simplicity (I think that's been lost
already)? Not having to store dormant sessions? I'll add that, IMO,
an attraction to coolness and clever code is *not* a goal worth
pursuing.
On Mar 22, 11:42 pm, "Michael Koziarski" <mich...@koziarski.com>
wrote:
> If you'd like to coordinate this, I'd definitely be glad to hear from
> them. As it stands I think your complaint boils down to the lack of
> server-side invalidation of a session. Most everything else flows
> from that. I'm not sure that there's a shared nothing way to take
> care of that, but the crypto experts would know for sure.
>
> Please do investigate having someone conduct a review.
To get started, here's a good link on the concept of replay attacks
and nonces:
http://www.openidenabled.com/openid/replay-attack-prevention
And here's a nonce implementation by Sam Ruby (not a crypto expert by
any means, but a smart Ruby dev for sure - the implementation is in
Python, though):
http://www.intertwingly.net/blog/1585.html
> @Brad - Great work on setting up some code for benchmarking. I
> haven't reviewed your code, but doing nonces correctly gets into some
> sticky synchronization and concurrency. Basically, the system needs
> to make sure that:
>
> * The nonces used by all of the Mongrels are kept track of (eg one
> counter per Mongrel)
>
> * No Mongrel uses the same nonce (eg prefix the nonce with the
> Mongrel's pid)
>
> * That the issuing a nonce, restoring a session, and then invalidating
> the nonce are all done in the correct order. This can get very
> tricky
Don't use that code. I had the wrong approach about this, and just
saw my mistake. We will need to rethink the approach, probably after
review from an expert. I'll be thinking about this in the meantime,
and I'll try to at least think a little next time before I start coding.
http://www.cs.vu.nl/~ast/books/ds1/toc.html (chapters 5, 6, and 8 are
good backgrounders)
The downsides of the cookie approach:
*) It causes more lookups/coordination overhead on the server side.
You still need a db or distributed transaction coordinator lookup
(each server in a cluster needs to know some sort of cluster protocol
for token or timestamp management), so we're not saving a db lookup
and have to maintain coordinator and recovery logic.
*) It puts state unencrypted in a client device we have no control
over (open to attack, reduces the usefulness of the store if we can't
put anything we want in there and feel safe about it)
*) It puts state in an unreliable device (browsers crash - especially
firefox with a few add-ons ;) that would require recovery logic
What is so broken that requires all of this messy overhead and
limitations?
In my mind there needs to be an overwhelming pain to justify the cost
and I can't see/feel the pain to justify this effort and wasted time
on the core list.
SamB
On Mar 23, 11:18 am, "Jeremy Kemper" <jer...@bitsweat.net> wrote:
Would using Ajax requests throw a wrench into the works?
The example I'm thinking of is:
1. Request 1 hits the server invalidating the nonce for the session,
and runs for a bit
2. Request 2 comes in and gets rejected, hence the request fails and
something expected to happen doesn't
3. Request 1 completes and a new session cookie is set so that the
next action completes successfully.
Thanks,
~Wayne
So you actually want to start designing the framework for its _worst_
users? :)
Kind regards,
Thijs
--
Fingertips - http://www.fngtps.com
Phone: +31 (0)6 24204845
Skype: tvandervossen
MSN Messenger: th...@fngtps.com
iChat/AOL: t.vande...@mac.com
Jabber IM: th...@jabber.org
>
> On Mar 23, 2007, at 1:51, Brad Ediger wrote:
>> I might be over-concerned here, but I'm not talking about the average
>> Rails developer. I'm talking about the worst ones. I can tell you
>> that while the average Rails developer I've worked with would
>> certainly be able to understand this and work around it, I'm not sure
>> that the worst ones would even understand what the issue was if it
>> were explained to them.
>
> So you actually want to start designing the framework for its _worst_
> users? :)
From a security standpoint, absolutely. Certainly there is some
responsibility on the developer's part to learn how the web works,
but the framework should be as forgiving as possible to new users.
--be
Here, here!
I did some more work over the weekend and have come up with some other
serious problems, which I want to discuss after I've looked into them
more.
Koz asked me to try to get a professional review done. To do this, I
need two things (preferably
from core):
1. A short but precise spec on how the cookie sessions work. The
people doing the review may never have seen a line of Ruby in their
lives. The spec should be specific and technical, just not assume
knowledge of Ruby. It should also be brief, if we want anyone to go
over it pro bono.
2. A sample app, with src code and full configuration. It can be
simple or even trivial, but it should show how the cookie session is
designed to be deployed. But it has to follow the type of use that
would be recommended - nothing like "in real life, of course, we'd do
it in a more secure way". The configuration and the like are just as
important as the app src.
> Koz asked me to try to get a professional review done. To do this, I
> need two things (preferably
> from core):
>
> 1. A short but precise spec on how the cookie sessions work. The
> people doing the review may never have seen a line of Ruby in their
> lives. The spec should be specific and technical, just not assume
> knowledge of Ruby. It should also be brief, if we want anyone to go
> over it pro bono.
I would be willing to draft a spec if the core team is too busy. We
could always run it by them for editing / approval.
be
There seems to be an assumption that 'session' handles all this
automatically, when in reality it is nothing more than a fancy hash.
A login session exists at a point in time for a particular period of
time. It should expire. It is related to a particular user ID (and
possibly a browser/IP sequence) and a particular set of transaction
sequences. You don't get that with 'session' - you have to model it
properly. If you haven't modelled the functionality, then you can't
expect to use it.
I suspect the name 'session' is the problem. It's an overloaded
concept with a load of built-in expectations. However
'semi_persistent_hash' isn't anywhere as easy to type.
NeilW
On Mar 22, 3:44 pm, Brad Ediger <b...@bradediger.com> wrote:
> I can't come up with an
> attack other than the replay attack, but that "I am logged in as Joe
> User" message seems too general to make me feel completely
> comfortable about authentication via cookie sessions for the time being.
You shouldn't be storing ID references to the User model in the
session hash; you should be storing ID references to the
AuthenticatedSessions model.
That way when you click 'LogOut' the relevant AuthenticatedSession
object is deleted from the database, and then it doesn't matter one
jot what the next persion does with the cookie.
If something doesn't fit, then look to the model. You've probably
missed a relationship that should be a first class model object.
On Mar 22, 5:15 pm, "S. Robert James" <srobertja...@gmail.com> wrote:
> On Mar 22, 10:44 am, Brad Ediger <b...@bradediger.com> wrote:
>
> > This is the crux of the issue... of *course* it's a terrible idea to
> > store sensitive or transient data in the session, but the question is
> > one of API design. Do we want the penalty for ignoring best practices
> > to be compromised security?
>
> It's even more complicated. Defining "sensitive or transient data" is
> not at all trivial.
>
> The standard use case for a cookie session is store only flash and
> user id. Not sensitive or transient? Okay.
>
> Now, I click "Log Out", and get up from the library's computer, only
> to let the person waiting after me to retrieve the old cookie.... That
> innocuous user id just became both sensitive and transient.
>
> The point is, answering these questions is hard. Witness the
> confusion in this thread alone. DIY cryptosystems are hard:
> professionals fail. WEP failed. Does it make sense to push all these
> questions onto each new Rails developer's shoulders?
session[:user_id] is perfectly safe with a server-side session. It is
not with a client-side session.
User session expiration has almost nothing to do with this
discussion. Expiring user sessions doesn't prevent sessions from
being replayed during the validity period. And there's no way to
expire user sessions with only a client cookie. We're looking first
for a general solution.
I do have a bigger problem with your statement that "If you haven't
modelled the functionality, then you can't expect to use it." It is
the job of the framework to give developers functionality that they
don't have to model. Otherwise Rails would just punt and say "Here's
how you set and read a cookie. If you want to use sessions, model
them yourself."
What I'm saying is that now you have client side session data, you
have exposed the limited semantics of 'session' and there is an issue
that was simply masked by the server side stores.
Rails has never offered authenticated anything. That's why there is no
standard login mechanism.
Why not switch to session side stores and mask the issue, or implement
an AuthenticatedSession that does what you want it to do (and release
it as a plugin if you so desire). Complex cookie encryption might be
an interesting technical puzzle, but is it really required by default?
It's a question again of where the framework ends and the application
begins. I don't believe that there is justification for foisting
complex default encryption mechanisms on the framework when the
'problem' is that you are using the wrong model. Just use a server
side session store.
Now I may be wrong about 'session'. Perhaps it is a much more complex
object than it appears. Perhaps it should be. That is not for me to
decide.
NeilW
> >> questions onto each new Rails developer's shoulders?- Hide quoted text -
>
> - Show quoted text -
On Mar 26, 7:40 pm, Brad Ediger <b...@bradediger.com> wrote:
> How, exactly, would you model the login session so as to be immune to
> replay attacks with shared-nothing on the server side?
Use a server side session store, not a client side one.
> I do have a bigger problem with your statement that "If you haven't
> modelled the functionality, then you can't expect to use it." It is
> the job of the framework to give developers functionality that they
> don't have to model. Otherwise Rails would just punt and say "Here's
> how you set and read a cookie. If you want to use sessions, model
> them yourself."
Why not go the whole hog and provide us with a default fifteen level
login system with access control lists?
The issue is where the framework ends and the application begins. A
Rails app that just uses the flash and a setting to determine whether
to show the welcome page doesn't need nonces and anti-replay devices.
Perhaps the first job is to step back a little and ask how much you
*really* should stuff into session. What is the job of that little
semi-persistent-hash?
NeilW
Comments follow.
On Mar 27, 2007, at 10:24 AM, Neil Wilson wrote:
> I understand the distinction very well. I would suggest that you have
> ascribed more capability to 'session' than the semantics of that
> facility allow.
>
> What I'm saying is that now you have client side session data, you
> have exposed the limited semantics of 'session' and there is an issue
> that was simply masked by the server side stores.
(snip)
> Why not switch to session side stores and mask the issue, or implement
> an AuthenticatedSession that does what you want it to do (and release
> it as a plugin if you so desire). Complex cookie encryption might be
> an interesting technical puzzle, but is it really required by default?
I think we're on the same page here, but maybe coming at it from
opposite directions. I think the session abstraction, as exposed by
the server-side stores, worked fine. I don't think it was masking
anything -- I wouldn't say that every aspect of an application's
semantics needs to be captured explicitly in the model. As an
abstraction, the server-side stores provided everything that
developers needed, even considering sensitive and volatile data
(i.e., authentication information).
The problem comes when you try to change the abstraction. Storing
sensitive data with an untrusted client is always tricky -- it's the
reason that ATM cards are fundamentally more secure than any
anonymous e-cash system. "Complex cookie encryption" covers a lot of
ground... the HMAC will definitely be required if you want any
integrity at all, and some sort of nonce is (provably) required if
replayed sessions can hurt you in any way.
However, I think that it is too much to ask of new developers to
implement the whole AuthenticatedSession thing (along with the
requisite security analysis) themselves. As Robert James pointed out
in this thread, security analysis is really tricky -- there are N
ways to get it wrong and 1 way to get it right. And forcing
developers to consider security at this level isn't too friendly, IMO.
I believe that CookieStore should be either (1) secure against replay
attacks by default, or (2) not the default session store. Anything
else is asking too much of non-security-aware developers.
--be
+ 1
Jonathan
--
Jonathan Weiss
http://blog.innerewut.de
As I said earlier, I'm waiting for a spec and sample app before
working on a full review. If those never happen, I'll eventually post
the sketches that I already have. But I think the community would be
happier with a material "this is how the app can be compromised" over
"theoretically, depending on the implementation, this might be the
problem." Anyway, if I don't here back on those things, I'll post my
notes from conversation - if I do, I'll try to get a full review done.
On Mar 27, 12:05 pm, "Alexey Verkhovsky" <alexey.verkhov...@gmail.com>
wrote:
> (a) Cookie sessions are vulnerable to replay attacks, because the
> client can present *any* cookie that it has seen to the server, not
> just the most recently sent one. On the other hand, server-side
> storage methods are not vulnerable because the session ID always
> references the latest version of the session.
+1 for hitting the nail on the head.
As I said earlier, I'm waiting for a spec and sample app beforeworking on a full review.
I'm probably missing something here, but what exactly is your goal
for this?
Short summary: someone made a well meaning change to sessions that is
broken and creates more pain than it solves.
Desired result: rollback the patch.
DHH, what say you?
On Mar 29, 12:02 am, Thijs van der Vossen <t.vandervos...@gmail.com>
wrote:
Just adding my $0.02:
I like the shared-nothing cookie store as an option, for
performance/scalability reasons. Just document the vulnerability to
replay attacks and maybe add a timestamp to limit how long the cookie
remains valid.
The nonce thing adds a lot of complexity, and if you need to hit
shared storage anyway there's just no point. As far as I'm concerned,
updating a nounce or the actual session data has similar overhead.
I'd prefer a db backed session store replacing the current default.
Ideally it would be automatically created, indexed and purged of stale
data.
Isak
The 'someone' was [1] bitsweat aka Jeremy Kemper who works for
37signals where David Heinemeier Hansson is a partner. I suspect
they've talked about this... ;)
Kind regards,
Thijs
[1] http://dev.rubyonrails.org/changeset/6184
>
> On Mar 29, 2007, at 3:48, Brad Ediger wrote:
>> On Mar 27, 2007, at 9:46 PM, S. Robert James wrote:
>>> As I said earlier, I'm waiting for a spec and sample app before
>>> working on a full review.
>>
>> I went ahead and wrote up a spec. Here's my first crack at it.
>>
>> Everyone: Please feel free to make suggestions / corrections.
>
> I'm probably missing something here, but what exactly is your goal
> for this?
Koz asked for a security review, Robert James said he might be able
to get one, so I wrote a summary of what has been said / done so far.
I was trying to be neutral but detailed, so that's why it might seem
bland.
--be
+ 1 It sounds like the decision to make cookie store the default was
premature, at best.
By the way, just because this 'feature' is in EdgeRails does not mean
it will make it to a *stable* release, which makes some of the
hand-wringing on periphery of this thread seem a little premature
also.
Planting the seed here led to quick ripening and plenty of pesticide.
> By the way, just because this 'feature' is in EdgeRails does not mean
> it will make it to a *stable* release, which makes some of the
> hand-wringing on periphery of this thread seem a little premature
> also.
Thanks for the fish, all.
jeremy
Ok, that _is_ really funny. ;)
Kind regards,
Thijs
> On Mar 29, 2007, at 21:35, Jeremy Kemper wrote:
>> On 3/29/07, Obie Fernandez <obiefe...@gmail.com> wrote:
>>> On 3/29/07, Tomas Jogin <tom...@gmail.com> wrote:
>>>> How about just NOT changing the default setting to this less secure
>>>> option? Problem solved.
>>>
>>> + 1 It sounds like the decision to make cookie store the default
>>> was
>>> premature, at best.
>>
>> Planting the seed here led to quick ripening and plenty of pesticide.
>
> Ok, that _is_ really funny. ;)
I think he's trying for two quotes on project.ioni.st this week. :-)
So, does that mean this will likely be taken out? If so, I would vote
that it at least be provided as an option if not the default. It's
certainly useful for developers who understand the security concerns
and still feel that it would be an appropriate method of session
storage for their application.
--
Regards,
John Wilger