
Handmade Rails Authentication - KevinMS
http://kswope.wordpress.com/2010/08/06/hand-made-rails-authentication/
======
hopeless
Personally, I feel authentication is one area where it's best to have "many
eyes". Sure, rolling your own is easy enough but have you really thought of
every edge case, every security exploit? It is also one area where most
applications are extremely similar and there's (not usually) any business
advantage gained by rolling your own.

Still, always good to see how others approach authentication code (personally,
I use Clearance).

~~~
ichverstehe
This is one of my pet peeves. I can implement some basic authentication in
something like 25 lines of code. AuthLogic: 2500 LOC. Devise: 2200 LOC.
Clearance: 690. And yet, both times I tried to use AuthLogic, it actually
didn't work for my case–login and password in different tables–without some
weird hacks, at least not back then. My own custom authentication code can do
that by simply modifying an existing LOC, and I know what is going on. There's
no way I am going to ever feel comfortable with e.g. AuthLogic's code, simple
because I can't justify spending time getting comfortable with it, when I can
write it myself in 15 minutes.

It's the same issue I have with RSpec, actually. Too much code.

~~~
tptacek
I actually kind of agree. Rails Auth isn't a hard problem. As long as you're
not rolling your own password hash and you're not rolling your own session
store, I'm comfortable saying "authentication code in Rails is just glue; do
the simplest thing that can work".

Now, authori _zation_ is a radically different story; unfortunately, though,
there's no good Rails solution for getting "off-the-shelf" access control and
permissioning, so you may be kind of stuck anyways.

(Pet peeve of mine? Mixing up authorization and authentication.)

~~~
euroclydon
I hear, "Don't roll your own session store" frequently, but I wonder, is there
any way to not roll your own session store when you are creating a single-
sign-on application across multiple server technologies (PHP, ASP.NET, Rails)?

~~~
tptacek
Nope. Be really, really careful. This is one of the top game-over problems
that happens to smart dev teams.

~~~
ichverstehe
Can you elaborate on that?

~~~
euroclydon
Go back and read through Thomas's comments here regarding attacks on encrypted
passwords.

Try this:
[http://www.google.com/search?q=bcrypt+tptacek+site%3Anews.yc...](http://www.google.com/search?q=bcrypt+tptacek+site%3Anews.ycombinator.com&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-
US:official&client=firefox-a)

Find all his warnings, and don't make any of the mistakes he mentions, and
I'll bet you will be fine.

~~~
tptacek
I'd be more worried that:

* The session token you come up with will be insecure, like PHP's have been as recently as (I think?) this year

* That you'll end up reinventing session fixation vulnerabilities

* That you'll screw up session timeouts and logouts and succumb to "permanent" session hijacking flaws

* That you'll try to encode encrypted information into the session cookie itself, rather than just an opaque random token, and open _that_ whole kettle of worms.

------
tptacek
auto_hash is an inferior password hash; use bcrypt or scrypt instead.

~~~
KevinMS
I don't really understand your phrasing, "auto_hash is an inferior password
hash", its a rails plugin that uses SHA2 (256). If you mean "auto_hash" uses
an inferior password hash, could somebody please point me to some info on why
it shouldn't be a good enough option for almost all websites? I really don't
want to go imposing an obscure hashing algorithm on users of the plugin,
especially with hashing algorithms that deliberately impose a speed penalty
for extra security.

I'm not interesting in changing the world of password hashing with my trivial
rails plugin by using anything other than the most secure of the common
hashing algorithms, SHA2. I'm also under the impression that SHA2 is now the
most widely recommended security hash.

~~~
tptacek
There's no such thing as a "security hash". You mean to say "secure hash
function". The term "security" refers to the integrity of the hash itself;
SHA256 is "secure" against attempts to cause collisions (and several other
attacks).

None of that has anything to do with the security that SHA256 provides _to
your application_. SHA256 knows how to take care of itself. It doesn't know a
damn thing about passwords. SHA256 isn't a secure password hash.

You already know that, because you're not just using SHA256; you're also
adding a random salt to it. That's because if you didn't do that, attackers
could just aim a precomputed dictionary at your database rows and smite it. So
your hash _isn't_ SHA256; it's a construction called "salted SHA256" (or
"SHA256 with a nonce").

Nonced SHA256 still sucks, though, because SHA256 is lightning fast. Attackers
can't throw precomputed dictionaries at your password hash, because you
randomized them. But they can take each hash in turn and run a large
dictionary against each hash. This is a brute force attack, but it's not a
brute force against the 256 bits of the hash; it's an attack against the (low)
entropy of the passwords themselves.

This is how _all_ password cracking got done in the '90s, which was a bit of a
golden age for password cracking. It's how John the Ripper (the most famous
password cracker) works. John the Ripper is extraordinarily fast against Unix
password hashes, which are _slower_ (by a lot) than SHA256. Incremental
crackers tear through naked SHA256 hashes like a knife through butter.

That you don't know any of this --- and I say this respectfully --- tells me
that maybe you should be using someone else's password hashing library instead
of reinventing your own. But you're welcome anyways for the quick and dirty
lesson in password hashing.

~~~
seiji
Short version (you almost got around to it, but didn't explicitly state it :))
-- Don't use straight hash functions because they are _made to be fast_. Even
if you salt/nonce them, you can generate private rainbow tables quickly.

Use a password hiding method that's slow to compute (slow being "this
operation isn't implemented in hardware or optimized assembly") which is what
bcrypt or scrypt provides.

Differences in speed/effort are mentioned at
<http://www.tarsnap.com/scrypt.html> \-- _scrypt enc is approximately 100
billion times more than the cost of cracking the same password on a file
encrypted by openssl enc_

~~~
lonestar
Actually, slow in this case does not at all mean "this operation isn't
implemented in hardware or optimized assembly".

The slowness of an algorithm like bcrypt is a tunable property of the key
expansion algorithm. A step in this process will be repeated 2^n times, where
n can be configured by the user.

If a password function was only slow because it wasn't implemented in assembly
on your server, an attacker would obviously just go implement it in assembly
for his brute-force crack.

~~~
tptacek
Actually, the major contribution in Colin's scrypt work is to find primitives
that don't admit as well to hardware acceleration; his hypothesis is that one
of bcrypt's weaknesses is that even though it's very slow in software, it
might be possible to massively accelerate it with FPGAs.

------
pkulak
What, no salt?

~~~
KevinMS
Its one of the things that is the "auto" in "auto_hash".

