# Beating the authentication horse (dead yet?)

**URL:** <https://www.ruby-forum.com/t/beating-the-authentication-horse-dead-yet/97124>\
**Category:** Rails\
**Created:** [July 5, 2006, 3:56am UTC](https://www.ruby-forum.com/t/beating-the-authentication-horse-dead-yet/97124 "2006-07-05T03:56:55Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![BA\_Baracus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e5b9ba/32.png) [@BA\_Baracus](https://www.ruby-forum.com/u/BA_Baracus)\
**Post date:** [July 5, 2006, 3:56am UTC](https://www.ruby-forum.com/t/beating-the-authentication-horse-dead-yet/97124/1 "2006-07-05T03:56:55Z")

</div>

Guys,

I’m frankly overwhelmed by the number of Rails authentication options(?)  
out there…from ActiveRBAC to acts\_as\_authenticated to LoginEngine and  
so on…so many options, yet on resource I’ve found really distinguishes  
between each.

This is sad, as authentication and user management is really an area  
where some Rails simplicity pixie dust could be a real boon to  
developers. Can anyone point me in the direction of a good comparison,  
or can you recommend a particular approach? I’m very wary of chosing the  
coat tail to ride and not realizing it until two weeks after grabbing  
ahold…

Thanks!

## B.A.

B.A. Baracus: I thought you weren’t crazy no more?  
Murdock: Only on paper.

---

<div class="post-metadata">

**Author:** ![BA\_Baracus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e5b9ba/32.png) [@BA\_Baracus](https://www.ruby-forum.com/u/BA_Baracus)\
**Post date:** [July 5, 2006, 4:15am UTC](https://www.ruby-forum.com/t/beating-the-authentication-horse-dead-yet/97124/2 "2006-07-05T04:15:04Z")

</div>

On Jul 4, 2006, at 6:55 PM, BA Baracus wrote:

> developers. Can anyone point me in the direction of a good comparison,  
> or can you recommend a particular approach? I’m very wary of  
> chosing the  
> coat tail to ride and not realizing it until two weeks after grabbing  
> ahold…

Hey B.A. - an acute observation. Perhaps there are so many  
authentication systems because they are so simple to implement? The  
proliferation of options doesn’t imply the need to choose 🙂

jeremy

---

<div class="post-metadata">

**Author:** ![BA\_Baracus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e5b9ba/32.png) [@BA\_Baracus](https://www.ruby-forum.com/u/BA_Baracus)\
**Post date:** [July 5, 2006, 4:21am UTC](https://www.ruby-forum.com/t/beating-the-authentication-horse-dead-yet/97124/3 "2006-07-05T04:21:13Z")

</div>

I have used acts\_as\_authenticated a number of times, I am pretty happy  
with  
it. It’s very adaptable and pretty much stays out of the way. Just  
experiment a little and see what approach you like best. ActiveRBAC is  
pretty smooth too.

On 5 Jul 2006 01:55:56 -0000, BA Baracus  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![BA\_Baracus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e5b9ba/32.png) [@BA\_Baracus](https://www.ruby-forum.com/u/BA_Baracus)\
**Post date:** [July 5, 2006, 5:24am UTC](https://www.ruby-forum.com/t/beating-the-authentication-horse-dead-yet/97124/4 "2006-07-05T05:24:51Z")

</div>

On Tue, 4 Jul 2006 19:13:34 -0700, Jeremy K. wrote:

> Hey B.A. - an acute observation. Perhaps there are so many  
> authentication systems because they are so simple to implement? The  
> proliferation of options doesn’t imply the need to choose 🙂

Except to the extent that it makes developing compatible components  
difficult, because you can’t rely on any one authentication scheme.

But it’s early days with Rails yet; it’s my personal hope that a few  
complementary schemes will win the natural-selection game, and perhaps  
they’ll even be compatible. Remember how long it took for even basic  
infrastructure like TCP/IP to go from “prevalent” to “omnipresent”? You  
might have AppleTalk, token ring, Banyan Vines, Novell, all fighting for  
your cabling infrastructure. Rails 1.0 is less than a year old; we’ve  
got  
time to see what works and what doesn’t.

Jay L.

---

<div class="post-metadata">

**Author:** ![BA\_Baracus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e5b9ba/32.png) [@BA\_Baracus](https://www.ruby-forum.com/u/BA_Baracus)\
**Post date:** [July 5, 2006, 1:51pm UTC](https://www.ruby-forum.com/t/beating-the-authentication-horse-dead-yet/97124/5 "2006-07-05T13:51:29Z")

</div>

On Tue, 4 Jul 2006 23:48:28 -0500, David Heinemeier H. wrote:

> > But it’s early days with Rails yet; it’s my personal hope that a few  
> > complementary schemes will win the natural-selection game, and perhaps  
> > they’ll even be compatible.
> 
> Don’t hold your breath. People have chased the component pipe dream  
> for decades. It hasn’t arrived yet. I don’t think it ever will. I’ve  
> written about this twice on LT:

Yep, and I respectfully disagreed both times! As I said at the time,  
it’s  
natural for you to be a pessimist about componentization. After all,  
you  
were fed up enough with what you found that you rolled your own freaking  
framework. But you’re happy with what you created, so you don’t  
recommend  
that others do the same.

And I do agree that some things are too easily created, and too, er,  
difficultly configured, to be true components. But a lot of simple  
things  
DO make good plugins, just because they’re so simple and everyone wants  
to  
do them. I’m sure any of us could roll our own form helpers, and before  
1.1, we did - yet now we have form\_for, and it’s nicer. I think of  
authentication in that vein.

In the “real” authentication space, LDAP seems to finally be taking hold  
after, what, 13 years of languishing in nice-theory-land. I’ve been  
massively wrong before, but I’m willing to bet you that Rails will  
converge  
on a few common authentication solutions in half that time. Dinner in  
2013?

Jay L.

---

<div class="post-metadata">

**Author:** ![BA\_Baracus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e5b9ba/32.png) [@BA\_Baracus](https://www.ruby-forum.com/u/BA_Baracus)\
**Post date:** [July 5, 2006, 6:50am UTC](https://www.ruby-forum.com/t/beating-the-authentication-horse-dead-yet/97124/6 "2006-07-05T06:50:39Z")

</div>

> infrastructure like TCP/IP to go from “prevalent” to “omnipresent”? You  
> might have AppleTalk, token ring, Banyan Vines, Novell, all fighting for  
> your cabling infrastructure. Rails 1.0 is less than a year old; we’ve got  
> time to see what works and what doesn’t.

Don’t hold your breath. People have chased the component pipe dream  
for decades. It hasn’t arrived yet. I don’t think it ever will. I’ve  
written about this twice on LT:  
[http://www.loudthinking.com/arc/000335.html](http://www.loudthinking.com/arc/000335.html) and  
[http://www.loudthinking.com/arc/000407.html](http://www.loudthinking.com/arc/000407.html)

## Regarding authentication, I’ll strongly encourage people to try rolling their own. It’s probably simpler than trying to compare the prepackaged options out there. And you’ll learn a lot about Rails and filters in the process.

David Heinemeier H.  
[http://www.loudthinking.com](http://www.loudthinking.com) – Broadcasting Brain  
[http://www.basecamphq.com](http://www.basecamphq.com) – Online project management  
[http://www.backpackit.com](http://www.backpackit.com) – Personal information manager  
[http://www.rubyonrails.com](http://www.rubyonrails.com) – Web-application framework

---

<div class="post-metadata">

**Author:** ![BA\_Baracus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e5b9ba/32.png) [@BA\_Baracus](https://www.ruby-forum.com/u/BA_Baracus)\
**Post date:** [July 5, 2006, 2:04pm UTC](https://www.ruby-forum.com/t/beating-the-authentication-horse-dead-yet/97124/7 "2006-07-05T14:04:01Z")

</div>

David Heinemeier H. wrote:

> Regarding authentication, I’ll strongly encourage people to try  
> rolling their own. It’s probably simpler than trying to compare the  
> prepackaged options out there. And you’ll learn a lot about Rails and  
> filters in the process.

Implementing basic session-based authentication is a breeze (and it’s  
covered nicely in the Agile Web D. book). Here’s a few things  
to have in mind when creating secure logins and cookie-based  
authentication, though. Bear in mind, I’ve only been on rails for a  
week, and I’m making assumptions here. 🙂

# Storing user data in sessions

You’ll probably want to store the hashed password along with the user ID  
in the session data. That way, a session will be rendered invalid if the  
password is changed.

# Session fixation / session stealing

The ID of an existing, authenticated session is all an attacker would  
need to access protected data. There’s a few ways this could happen:

- The attacker establishes a session with the site (ie, points the  
browser to the site), and reads out the session id from the headers or  
the browser’s cookies. He/she then cons an unsuspecting user to login  
using his session. (in php, this is as simple as a link like  
[http://site.com/?PHPSESSID=](http://site.com/?PHPSESSID=) - i’m not sure if rails even  
supports supplying session ids via url parameters). This is called  
session fixation.

- Cross-site scripting. There’s a number of ways a malicious user could  
make a javascript execute in your browser, read up on XSS for the  
details. The result? The attacker is able to read data from your  
cookies, including the session ID. Voila, instant backstage pass.

- Sniffing on shared networks. Use HTTPS if you’re worried about network  
sniffing.

The solution to blocking session fixation is dead simple: change the  
session id or start a new session on login.

Making sure the session id is coming from the correct client is a bit  
hairier. You could store the ip-adress in the session and verify that  
aswell. That’ll make it more secure in many cases, but bear in mind:  
some ISPs use proxy servers sharing a pool of ip-addresses, meaning the  
requests could come from different ip-addresses. Also, the attacker  
could be sitting on a local network sharing the same external  
ip-address.

It’s probably safe to assume that there’s something fishy going on if  
the User-Agent header string changes from request to request.

Change the session ID on every request if you’re absolutely paranoid,  
though that will break concurrent requests.

And remember to clear out stale sessions as often as possible.

# Storing logins in cookies

Storing the username and password in a cookie is asking for trouble. If  
your site is vulnerable to cross-site scripting, not only would the  
attacker be able to retrieve the session id - the clear text password  
would be accessible as well. Plus, the clear text password would be  
transmitted over the air on each and every request along with the HTTP  
headers. Anyone with physical access to the machine would be able to  
read the clear text password from the cookies. Don’t store sensitive  
data in long-term cookies on shared terminals whatsoever.

In my PHP setup, I use a system with two tables:

## users

username  
hashed\_password

## users\_login

user\_id  
remote\_address  
token  
hashed\_password  
last\_seen\_at

On authentication check, I first try to find the username and hashed  
password in the session. If they’re not present, I check if the username  
and a token are provided via cookies. If the token is provided, I try to  
get the hashed password from the user\_login table with username, ip  
address and token as keys. I then check the hashed password against the  
real hashed password in the users table. If they match up, the user is  
authenticated.

When a user successfully logs in (via the login form), I do two things:

1. Store the username and hashed password in the session
2. Unless the user already has a token set in the cookies, I generate a  
new one. The token is a random hash. I set token and username in the  
cookies, and create a new entry in the users\_login table.

This solution assumes the user have a static IP-address. If the IP  
changes, the user will have to reauthenticate on the next session. Not  
much of an inconvenience for my users, but most are on broadband access  
with more or less static addresses.

If I change my password, sessions and tokens on other machines would no  
longer be valid. IMHO, this is desirable. (I might forget about logging  
out of a public access computer, and change my password to ensure that  
the old session no longer would be valid)

You could up the paranoia on this solution too… For example, if  
authentication fails for a user (wrong password, wrong IP), you could  
wipe that users tokens from the users\_login table to reduce the chance  
of a successfull hacking attempt, at the expense of having the user  
relogin on the next session.

There’s no such thing as bulletproof security. The trick is to add as  
much complication as you can to the authentication process without  
inconveniencing the users too much. It all depends on how sensitive the  
data in your application is, and how much the attacker would gain on  
getting access (ie, how much effort he/she is willing to put in). Also,  
remember: Less Software. An authentication scheme is as strong as it’s  
weakest link, ie. the ugliest bug.

Inge Jørgensen  
web developer/designer  
removed\_email\_address@domain.invalid  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![BA\_Baracus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e5b9ba/32.png) [@BA\_Baracus](https://www.ruby-forum.com/u/BA_Baracus)\
**Post date:** [July 6, 2006, 2:27am UTC](https://www.ruby-forum.com/t/beating-the-authentication-horse-dead-yet/97124/8 "2006-07-06T02:27:36Z")

</div>

Thanks to all for the discussion. I’ll likely just go with  
acts\_as\_authenticated and build the features I need around it. I  
appreciate your help.

B.A.

---

<div class="post-metadata">

**Author:** ![BA\_Baracus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e5b9ba/32.png) [@BA\_Baracus](https://www.ruby-forum.com/u/BA_Baracus)\
**Post date:** [July 5, 2006, 4:50pm UTC](https://www.ruby-forum.com/t/beating-the-authentication-horse-dead-yet/97124/9 "2006-07-05T16:50:46Z")

</div>

On 7/5/06, Inge JÃ¸rgensen [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> The solution to blocking session fixation is dead simple: change the  
> session id or start a new session on login.

On that note, does anyone have a clean approach for changing just the  
session id?

My Ruby isn’t quite strong enough to let me enumerate and copy the  
data in conjunction with AR::Base.reset\_session.

Isak
