[erlang-questions] web authentication

Banibrata Dutta banibrata.dutta@REDACTED
Fri Jul 8 05:25:45 CEST 2011

Thanks for the amazing, simple-worded, web-authentication run down.

All the other comments so far as as great. Gets my "thread of the month"
award ("movie of the month" award IMHO, goes to the Erlang web-server perf
comparison movie).

Am willing to spend some money on buying a mini e/Book (Wikibooks?) or the
likes if this kind of info is turned into a "Learn You Some
Web-Authentication"... or slightly broader "Learn You Some Practical &
Professional Web-Development" :-). And if it uses Erlang as the lang of
choice for examples, all the more better. [subtle hint ;-)]

2011/7/8 Frédéric Trottier-Hébert <fred.hebert@REDACTED>

> The digest authentication you see at this point is something that's part of
> the HTTP protocol. It is technically unrelated to your application (although
> your application can see it through HTTP values) and the client-side of it
> is implemented by the browser.
> I would consider it highly impractical for how little control it gives you
> (even in terms of visual design) and in general security. The browser being
> in charge of it means the session handling is annoying (no way to
> disconnect, the browser just resubmits the data all the time for you,
> proxies become tedious, etc.)
> If you're okay for a longer read, here's what I know, in condensed format.
> Others can feel free to correct me.
> ======
> ======
> Modern authentication schemes usually work a bit that way
> ----------
> i. The user registers to the website on an HTTPS page (so that the password
> being sent isn't observable by third parties)
> ii. The password is stored in a database after being hashed by bcrypt or
> scrypt with a convenient, but slow work factor as to make brute-force (if
> the DB is compromised) absolutely impractical. These algorithms store their
> own difficulty factor, so that if you want to up the complexity, it can be
> done quite simply even if you have many versions in the DB.
> iii. Avoid using MD5 or SHA-x hashing functions. MD5 is collision-prone,
> some of the SHA functions too. MD5 and SHA hashing functions were made to be
> really fast and we want to avoid that. The reason is that it makes it easier
> to brute-force passwords if the table is compromised. Protect your users
> first. Bcrypt and Scrypt, by comparison, will salt the passwords for you and
> give each of them a work factor. If you take 100 millisecond to check a
> password (something that happens once per session, so it's fine to be slow)
> compared to 10 microseconds, it becomes a real pain for crackers to do their
> thing. During that time, you can warn your users to change their passwords
> in other services.
> iv. bcrypt and scrypt handle salting for you, as mentioned before. If you
> decided not to use them, do remember to salt your passwords to avoid easier
> rainbow table attacks. Do NOT reapply a hash function many times over a
> previous hash results. Because all hash functions have collisions, this
> means that as you go, you increase the chances of collisions. Re-salt at
> each iteration. Again, if you use bcrypt or scrypt, this is handled for you
> and you do not have to worry. Please use bcrypt or scrypt.
> v. If that wasn't obvious, use the hashing function of bcrypt, not the
> encryption that can be decrypted. You do NOT want to use encryption, but
> hashing. The reason is simple. If your system is compromised, you have to
> assume that your keys are also compromised. Encryption is unsafe for
> passwords. Hashing is the king.
> That being said, the actual steps of authentication then become:
> 1. The login page is an HTTPS page so that the password that will be sent
> isn't observable by third parties
> 2. The user enters his own password, submits it
> 3. The server hashes it through the same hashing function used when first
> saving the password
> 4. Compare the two hash values. Note: you want this to be done in O(n) time
> so that it's impossible to know whether you get partial matches or not. This
> makes more sense for clear text passwords, but what the hell.
> 4.a if they're different, the authentication failed
> 4.b if they're the same, go to 5.
> 5. Create some kind of session value in another table or wherever you want.
> The session will have a key that you can choose randomly (UUIDv4 + userid to
> avoid duplicates although the chances are minimal, as an example).
> 6. Put the value in a cookie. You want that cookie to be set with the
> option HttpOnly to avoid having client-side javascript able to read it. Also
> give a reasonable timeout value to the cookie so the user has to
> re-authenticate from time to time. This means both server-time timeouts and
> client-side timeouts.
> When a user loads a page, check the session cookie you defined, and match
> its value to whatever you've got in your session table. If it matches, the
> user has an active session. If it doesn't, have the user authenticate again.
> Note that this scheme (and pretty much any other) is insecure against 3rd
> parties listening to the communications between you and the server. To solve
> this, move everything to HTTPS, although this is harder to optimise for
> performance.
> ---
> Further considerations:
> A. Put a limit on how many times someone can try to log in. You can have
> their account locked for a few minutes in between each time. This is to keep
> people from trying to brute force accounts from the outside.
> B. HTTP cookies alone are not sufficient to know whether someone is
> authenticated or not. A specific kind of attack, named Cross-Site Request
> Forgery (CSRF) works by having someone doing an HTTP request for you, from a
> different domain. In these cases, the browser will automatically send the
> cookies along with the request (it can also be a javascript form that's
> auto-submitted). I've used this in the past to have a site administrator (a
> co-worker) close his own account without him noticing it. Woops.
> This means we need an external value, not coming from HTTP headers to make
> sure the request is good.
> In simple cases, you can try to check the referrer and make sure it's
> coming from your domain. However, flash components or HTTPS connections do
> not always have these settings, and if you have any of these pages on your
> site (and you will, if you do HTTPS authentication), you'll have to look
> somewhere else.
> The safe way to do requires a few elements:
> 1. Never do changes with GET requests. GET is idempotent and free of side
> effects
> 2. Do your changes with POST. This will require a user to use either a)
> Javascript, b) curl, wget or some other tool or c) an HTML form to send your
> data. This restricts the window of opportunity of malevolent users, who can
> no longer just post a link or an image to do CSRF.
> 3. This is the most important point, use something called a token. This
> token is a special value that is added to whatever form you generate. When
> the user sends a POST query (or anything requiring server-side changes) to
> you, check that the token is there and that it is valid. The best tokens
> will have a one-time use, but they're fairly impractical when many different
> queries can be done without refreshing a page. My favourite way to handle
> these otherwise is to create different tokens for different namespaces. The
> admin panel will have its own token, the chat system its own token, the user
> settings will also have its own, etc.
> The tokens have to time out at some point to make sure that someone who
> steals them can not damage the account for too long. Pick between a few
> seconds to a few hours based on how long you expect your user to stay on a
> single page.
> 4. Ask for the user password when changing vital information, such as the
> e-mail attached to the account, the password itself, buying an item, etc.
> C. Never roll out your own encryption schemes or hash functions. Let
> mathematicians specialised in cryptography do their thing.
> ========
> That should be about it for a quick guide. There are more complex issues to
> tackle for good authentication and security of user data, but as a basic
> intro, this should be okay. I hope this is helpful.
> --
> Fred Hébert
> http://www.erlang-solutions.com
> On 2011-07-07, at 15:29 PM, Joe Armstrong wrote:
> > Slightly off topic. But I want to make an erlang web site.
> >
> > 1) How does web authentication work?
> >
> > Let's assume something like:
> >
> >   http://en.wikipedia.org/wiki/Digest_access_authentication
> >
> > This is easy to understand.
> >
> > What I don't understand is what happens if the session socket is closed.
> > Handshaking tales place over an open socket and the client is
> > authenticated - this
> > is easy to understand.
> >
> > What happens if the socket is closed, and reopened in a subsequent
> request?
> > Does the server set and receive a session cookie? Does the client
> remember and
> > replay the authentication protocol?
> >
> > How does this work?
> >
> > 2) I want to make a web thing that requires the user to authenticate
> themself.
> >
> > Should I:
> >
> >    a) Roll my own (some MD5 + cookies should do the job)
> >    b) Implement
> http://en.wikipedia.org/wiki/Digest_access_authentication
> >    c) Something else?
> >
> > Seems like for a real web site there is a lot of cruft involved
> > preventing spammers,
> > false-accounts, forgotten-passwords etc. can I get all of this for
> > free by getting
> > authentication credentials via goole/facebook or something? Is this
> > what OpenID does?
> >
> > Finally is this entire authentication-user management-forgot my
> > password built-in
> > to any of the popular erlang web servers?
> >
> > Cheers
> >
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20110708/cee85bad/attachment.htm>

More information about the erlang-questions mailing list