8

So I want to write my own authentication scheme for a web-app server, as follows. I assume this is a Bad Idea from either security or cost-effectiveness reasons and I know the conventional wisdom is using an existing library, but I'd be happy for pointers as to where exactly I would be going wrong, since this scheme seems both secure and easy to build.

In Pseudo-API, I would respond to the following:

  1. POST /login,signup (+username, passwd) -> create and return token for this user. (Save user<->token relationship on server.)

  2. POST /logout (+token) -> destroy token for this user on server. (Destroy user<->nothing relationship on server.)

  3. POST /any-action (+token) -> perform action if token is correct. (user and token match user<->token on server.)

Is the above an insecure paradigm?

4
  • I'm OP, appreciate all responses, adding details (app would be a content-based social network.) 1. CSRF: should be prevented. 2. Passwords: should be encrypted, unguessable, retrievable via email. 3. HTTPS: desired (but orthogonal to scheme; lacking it would be vulnerability anyway) 4. Session-management: relinquished. Token is persistent forever. 5. Client-side storage of token is out of scope (for this question): It's client's responsibility. 6. BE must defend against SQL-Injection (as well as XSS) Commented Apr 17, 2014 at 9:38
  • I don't see ssl mentioned anywhere in ur post!
    – Songo
    Commented Apr 17, 2014 at 11:44
  • 1
    @Songo it's mentioned in OP's comment on the question, right above where you clicked the "add comment" link: "3. HTTPS: desired (but orthogonal to scheme; lacking it would be vulnerability anyway)"
    – Doktor J
    Commented Apr 17, 2014 at 13:10
  • @DoktorJ I see :D Although such info should have been added to the post itself instead of a comment.
    – Songo
    Commented Apr 17, 2014 at 13:12

3 Answers 3

13

Yes, this is insecure as specified.

Your design seems to be vulnerable to Cross-Site Request Forgery (CSRF also known as XSRF) attacks (need to add a CSRF token with all POST actions that is displayed with the form and stored in a session cookie). Basically, if a user goes to some other website (email, forum, blog) while logged into your website, their browser may be forced (by javascript, by a secret form) to make an unintended POST request to your website doing some action that I don't want.

Your scheme also isn't particularly specific.

  • How are passwords dealt with (bcrypt or PBKDF)? Or at the very least a salted hash? Are they checked with a constant time string comparison right?
  • How is data protected over the network during transit (HTTPS?),
  • How is data inserted/pulled from the database? Prepared statements (also known as parameterized queries) everywhere? (Great!) Or do you execute a string with an SQL command containing user input (Vulnerable!)?
  • How are tokens are stored in the browser (Secure HTTP-only cookies?)

Quite possibly they could be other flaws in the implementation as well.

6
  • 1
    The most pressing information is the "other flaws" clause. CSRF is a no-brainer here but your own auth scheme is far bigger than just 3 posts that you have to worry about. How you create your Session, if you generate a new one, how you manage the session, what cookie flags you set, there is much more than three post requests to worry about
    – user11869
    Commented Apr 16, 2014 at 20:12
  • @Rell3oT - It was not intended to be an exhaustive list, just a quick answer that the vague scheme is already attackable via CSRF. As an aside, listed a few more things that can be done wrong. Session management obviously depends on the application -- being logged into an unimportant account (say reddit as a normal user) doesn't need the same short-lived session requirements that a bank needs. And I did mention the two relevant cookie flags. Granted the number of flaws are innumerable; just gave a few. Others: token guessable, weak passwords allowed, weak pw reset mechanism, etc.
    – dr jimbob
    Commented Apr 16, 2014 at 20:55
  • Of course it wasn't exhaustive. I had actually already upvoted you. I'm not criticizing your answer just explaining why it can't possible be exhaustive (garbage in garbage out).
    – user11869
    Commented Apr 16, 2014 at 22:06
  • SQL injection seems to be orthogonal to the question.
    – user20574
    Commented Apr 17, 2014 at 0:51
  • 1
    I'm OP. Appreciate responses very much. For brevity I skipped enumerating every single security-related topic - of course we should avoid SQL Injections, make passwords unguessable, etc.My major decision, however,is whether to 'roll my own' or use an existing lib. Specifically for a webapp on a Node+Angular stack, a lib like passport.js does not seem to prevent most of the above issues - I'll have to prevent CSRFs anyway, make passwords unguessable anyway... Am I being naive/wrong? I added details via comment enumerating the topics mentioned here. Would appreciate any further comments! :D Commented Apr 17, 2014 at 9:50
12

What you present is not an authentication protocol; it is merely a concept, namely the concept of a session token.

In plain words:

  • Server authenticates client, and send back a secret key to that client (the session token).
  • When the client comes back, it shows the token to the server to prove that it is the same client as previously.
  • The client can request the server to forget the token (of course, and contrary to what you show, that "logout" request too should include the token, otherwise anybody could logout everybody else).

There is nothing wrong in this concept, as long as you understand its limitations. For instance, it inherently relies on the client/server communications to be both confidential (so that no passive attacker eavesdrop on the token) and resilient to tampering (so that no active attacker may hijack the connection just after the authentication). In short words, SSL (i.e. HTTPS) is mandatory.

I agree with you: this scheme seems easy to build. But take care: it is an illusion. In fact, it is not easy at all to build a secure authenticated session system, even if the concept is clear and simple. Building a system which works is easy, and can be tested; security, though, cannot be tested and is a lot more work than usually assumed.

There is a stupendously high number of ways the realization may derail. @jimbob gives you a few (and the list is not exhaustive at all). The art of computer security is not about making system works properly under normal conditions; it is more about making sure that systems do not work too improperly under abnormal conditions.

2
  • 1
    +1 @jimbob gives you a few (and the list is not exhaustive at all) -- Said list was not intended to be exhaustive. Started just describing the obvious CSRF vulnerability in the described part and then felt like adding a few other common things that popped to mind just in regard to authentication (ignoring things like XSS, LFI) as well as user access control, restricting access, secure generation random tokens, weak or reused passwords, don't log passwords in plaintext in server logs, etc
    – dr jimbob
    Commented Apr 16, 2014 at 20:07
  • I'm OP. Appreciate very much response; added details in comment to question. Am not saying it would be easy to cover all issues, am wondering whether using an existing library (say, passport.js for an Express.js server) is better than rolling my own. I guess my main thought is: security issues will have to be verified anyway; will it much easier with a 3rd-party lib than by rolling my own? Commented Apr 17, 2014 at 9:54
3

The funny thing about providing a generic 'gist' of an authentication flow is that unless you really screw up the flow, you likely won't find serious issues because there just isn't enough detail to say one way or another. More often than not, its the implementation that is flawed.

This is further complicated by the fact that you don't specify what you're protecting against. Passing just a username and being logged in is perfectly secure* -- under the right conditions. The question you need to ask yourself is who or what you're trying to protect against, and whether or not your authentication flow has provided protective measures against whatever those bad guys will throw at you.

You mention passwords... how are you verifying the passwords?

Session Tokens... how are you generating them, how are you storing them on the server, how are you storing them client-side, how are you validating the token on 'any-action'?

More questions etc...

That is why it's recommended you don't build you own. Odds are pretty good you haven't thought about every angle, whereas developers of a well-known component might have. As an example, to say that generating a session token is 'just an implementation detail' is not totally incorrect, but its a serious detail that will screw you royally if you mess it up.

So my answer to your question is: yes, it's insecure because there isn't enough detail to say one way or another.

*Well maybe not, but you get the point.

2
  • I'm OP. Appreciate response! Handling the issues you mentioned - re: storing & verifying passwords and tokens - is there a single 3rd-party component that handles them all? (Say, for an Express.js webapp server). From my understanding even using, say, passport.js I would have to deal with those issues myself. Commented Apr 17, 2014 at 9:57
  • 2
    One flaw to using a "well-known component" is that, if a vulnerability is found in said component, you need to a) be aware of the vulnerability, b) wait for the component developer to patch it, and c) install the update (and also possibly d) advise your users to reset their passwords). Of course the flip side is that (a) is much easier with a published component because the vulnerabilities get published; with a roll-your-own approach, if/when someone finds a vulnerability the onus is on you to figure out that it's been compromised :P
    – Doktor J
    Commented Apr 17, 2014 at 13:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .