

Persistent Login Cookie Best Practice - mickeyben
http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice/

======
Udo
It's a description of how cookies work and why cookie heists are so
devastating. As far as I can tell, the article doesn't contain any actual best
practices. Furthermore, I think cookie stealing is a trivial problem and there
is really only one solution: encryption.

The reason why encrypted connections are not the norm is a purely artificial
one, because technically we could easily have the encryption aspect of HTTPS
enabled by default, just as SSH does it today. We don't have that because
browser makers and certificate authorities are happily running a money-making
scheme that makes authentication mandatory if a site wants to use encryption.
Droves of web developers and users have been brainwashed into thinking that
encryption without an URL identity mechanism is somehow worse than having an
unencrypted link.

However, this all has nothing to do with cookies, the connection is just
incidental.

~~~
tptacek
There is no such thing as meaningful encryption without authentication; it's
like a car with an engine but no steering wheel. Encryption without
authentication is, at best, a trivial form of obfuscation (it's trivial
because everybody knows how to reverse it).

Certificates aren't an elaborate money-making scheme. They're the tie breaking
vote between Bank of America and the man-in-the-middle proxy pretending to be
Bank of America.

Key agreement without some form of tie-breaker (be it key continuity, web-of-
trust, or anchor keys, which is what SSL certificates use) is a fundamental
problem familiar to anyone who has ever built any working cryptosystem. Among
competent engineers, this isn't a debate. If you think anchor keys aren't the
right solution to SSL, the onus is on you to suggest a viable alternative.
"Nothing" is not a viable alternative; key agreement doesn't work with
"nothing".

~~~
Udo
> _They're the tie breaking vote between Bank of America and the man-in-the-
> middle proxy pretending to be Bank of America._

I'm not suggesting a new encryption standard for online banking, I want better
default security for otherwise unprotected web traffic.

> _There is no such thing as meaningful encryption without authentication;
> it's like a car with an engine but no steering wheel. Encryption without
> authentication is, at best, a trivial form of obfuscation (it's trivial
> because everybody knows how to reverse it)._

In the context of my comment I was referring to the top-down cert authority
structure (sorry if that wasn't clear), I didn't mean to imply that a
webserver shouldn't have any certificate at all. I guess it comes down to
disagreeing with you about self-signed certificates. I believe they would have
been a good idea as a default mechanism for connecting to web servers and I
still think they're way more secure than having nothing at all.

I believe that giving people exactly two choices, between cryptographic
perfection and making transfers completely public, is wrong. And asserting
that self-signed certificates are worse than no protection at all seems
misguided to me. But in the end, you're the competent engineer and I'm just
some guy posting inane comments on a message board over an unsecured link. And
in any case, it's not like we'll change the way browser-based encryption works
in the foreseeable future, so I kinda regret starting this whole discussion.

> _If you think anchor keys aren't the right solution to SSL, the onus is on
> you to suggest a viable alternative. "Nothing" is not a viable alternative;_

I'm sorry to say this but I suspect you are, maybe inadvertently, attacking a
straw man here...

~~~
tptacek
Self-signed certificates do not solve the problem and it's fairly
straightforward to see why: anybody can create them. How does a browser know
to pick your real self-signed certificate from the one generated by the man-
in-the-middle proxy?

 _Every single free and commercial web security testing tool already does this
on the fly_. We are not talking about some complex, unlikely-to-occur threat.
It's a pushbutton attack.

So... what's the point of a self-signed cert?

------
dfox
This system looks overly complex to me. What I use is:

Cookie = (user id, timestamp of cookie, random number, hash(rest of cookie
contents, user password from database (in whatever encrypted form it's there))

With hash being something like HMAC-SHA1 with per-application key. Purpose of
signing encrypted password together with all other data is to invalidate
persistent login cookies when user changes password. Timestamp is there as to
accommodate expiration of cookies in secure manner. This system has large
advantage in that you don't have to store any additional data pertaining to
persistent logins.

~~~
tptacek
(1) I don't know what the value of exposing any plaintext in a security cookie
is.

(2) I don't know what the value in having structured data, encoded or not, in
a front-end security cookie; you are virtually always better with an opaque
random number token.

(3) If you are going to play thermonuclear chicken with cryptography (point me
to any code you wrote to generate and verify that token), I don't know what
the point of a per-app HMAC key is; you are better off with a server-side per-
cookie HMAC key.

(4) You haven't protected the timestamp, and so cannot do secure cookie
expiration.

(5) The random number in that design doesn't appear to do anything.

~~~
dfox
Whole idea is that with opaque random number token requires having some
database of valid tokens while this design does not. All data that this scheme
exposes (user id, cookie creation time) as plaintext are probably going to be
exposed anyway by normal operation of application or in metadata of said
cookie. Timestamp is protected by the HMAC (which may not be entirely clear
from my previous description).

And yes, the random number does not do anything significant and is probably
useless. My reasoning was that it makes the structure of plain-text data
slightly less evident from the cookie contents.

~~~
tptacek
The reason not to expose plaintext in a cookie is not simply that it discloses
things, but that it creates opportunities for bugs on the serverside.

Virtually everybody reading this thread would be far better served by `head
/dev/random | openssl sha1` than by any other scheme.

------
mickeyben
Sorry for the dumb question, but I see some negative comment about this link
... so what's the good approach to implement secure persistent login in a web
application ?

~~~
angelbob
If you need to ask, I recommend starting with an existing implementation that
has been vetted by security folks smarter than you or I.

I use Devise, based on Warden, for Ruby on Rails. Depending on your platform,
that may not work for you.

~~~
mickeyben
After many years of Rails (and other frameworks), I know now that I NEED to
review the code of plugins written by folks smarter than you or I. I don't
count the times I had to remove plugins from my application.

I use Warden and saw there was a rememberable strategy in Devise that I could
use.

I also read I can secure the cookies to be only send over SSL. I was hoping
some further explanations on that since Devise doesn't seem to do it.

~~~
angelbob
That's true. And yes, devise doesn't do that by default. Basically, you'll
want to have Devise (or better yet, all of Rails) set to only use secure
cookies.

Unfortunately, most Rails apps run without SSL, so that's not going to be the
default any year soon. At this point, you really do have to pay money for a
good SSL certificate, or self-sign and then people have to click through an
ominous-looking dialog to use your site.

------
ak1394
My favourite format for auth cookies is auth_tkt:
<http://www.openfusion.com.au/labs/mod_auth_tkt/> it's widely supported, and
even if you can't find module for your favourite language, it's pretty easy to
implement yourself.

------
weavejester
_The cookie should consist of the user's username, followed by a separator
character, followed by some large random number_

Why not just use a random number on its own? There's no reason I can see to
bother with the username.

~~~
mkenyon
If you use a random number by itself, then you have to worry about possible
collisions. When the cookie does not contain the username, you, the server,
need to look up in your table to whom you gave the random number. This works,
but in this case the attacker must create a random number and hope it collides
with an existing one (even for significantly large fields).

However, if the cookie consists of a username and a random number, the
previous strategy is no longer feasible. The Cartesian product of usernames
and random numbers from a large field is too great a set to consider
attacking. An attacker's only hope in this implementation would be sniffing or
MitM attacks (which I should add are much scarier than brute force attacks).

~~~
jerf
The probability of collisions with 128 truly random bits is less than the
probability of your CPU incorrectly executing a given opcode. And by that I
don't mean an unanticipated logic error, I mean literally that your CPU is
instructed to add 2 and 3 and gets 1029.

Once you push the odds of some event below the noise threshold of CPU error,
it ceases mattering, because you've pushed past the point where you can't do
anything about it anyhow anymore. CPUs are very reliable but their failure
probability is not 0.

------
kirbman89
Why not just put the username in the cookie and make the user enter their
password each time? If a user doesn't want to enter their password then they
must not give that site much value.

~~~
Sidnicious
That would only last one page load.

If you want links to work, you need a more-persistent way of being identified.
That's where cookies some in.

------
bconway
Hate to be that guy, but...

 _tail -f /dev/mind > blog_

If you change that to 'tail -F', it will seamlessly pick up again if you
replace (change?) your mind.

