views:

450

answers:

10

I'm working on a registration process for an internal application. My initial design is below.

My main question is whether it's really necessary to include a registration_confirmation_code. Does it protect the app from a realistic threat or just add unnecessary complexity? I'm not sure about that.


  • User enters email address. Since this is an internal app, it has to be an agency address.

  • If it's a valid agency address, app creates a new row in the users table.

    • The table has a column registration_confirmed which is false by default. App won't let a user log in unless registration_confirmed is true.

    • The table has a column registration_confirmation_code which is a randomly-generated string.

  • App sends an email to the address the user entered. It contains a link to a page that will let the user confirm their registration and set their username and password.

    The link has the user's id and registration_confirmation_code in the query string:

    http://agencydomain.com/users?id=123&registration_confirmation_code=fab49dk34nw97d

  • By clicking on the link the user verifies that the address they entered is valid and that they have access to it.

  • The app finds the user by ID. Before allowing them to visit the page where they can set their username and password, the app checks that...

    • registration_confirmed is false. They should only be able to confirm their registration once.

    • registration_confirmation_code request param matches the value in the DB for that user. That ensures this is a legitimate registration confirmation by the intended user and not someone else hitting the URL with random IDs trying to hijack a registration.

  • If everything checks out, the app takes them to a page with a form for setting their username and password.

  • When they submit the form with valid data, app sets registration_confirmed to true and they are registered.

+1  A: 

I like sites that use the email address as the login id. Also, why not get the password up front when they register?

Don Branson
For those that implement this - remember never to use that email address as a primary key...otherwise it makes changing your username extremely difficult.
Dan Tanner
+7  A: 

Don't trust people even if they are internal to your organization. It sounds bad but unless you're dealing with a very small group, your method is a wise choice.

One more thing, you may want to ensure their email is unique.

colithium
+1 not trusting internal users.
Kevin
+2  A: 

You do seem to be going through an awful lot of effort for an internal application? How much fraud are you expecting?

James Curran
James: Never assume users will do what you want them to do. Period. :)
Dave
+1  A: 

Protecting your application from even-less-verified-than-usual users is a good thing, but even better is that you're protecting random people from being spammed with email from your system. By requiring opt-in, you're ensuring that X can't sign up for your service claiming to be Y, and causing email to be sent to Y every time you'd like to contact the user. It also gives Y the opportunity to say "what? no, this isn't me" and click reject, send an ARF report, or otherwise let you know that someone is having you on.

If you collect email addresses, you should always verify them.

rjbs
But it's an internal app. If your employees are spam-bombing each other, you have bigger problems than email.
James Curran
+1  A: 

You still need to send them a confirm code via email.

Depending on the app, you dont want people signing up using a coworkers email address.

Neil N
+1  A: 

i'd let the user in right after they click the link from the email, and send them a dummy pass that they can change later. (use email for username)

this eliminates one step from the process, and makes registration that much easier.

roman m
I personally dislike receiving random passwords. It basically doesn't save a step, it adds a few more. After signing up, I am practically forced to go to options/preferences, find the change password option, and then actually change it. Bad usability, I'd say.
Dave
+5  A: 

It's a good practice to verify any kind of input you receive from a visitor. Rule of thumb is to always make sure you're getting what you expect, and nothing else. I'd say you're doing it well, including email verification.

A small question though; why make it a two-step process? why not allow the user to enter a password right away? This usually feels much more comfortable for the user.

Also, instead of using registration_confirmation_code, you might want to consider using a MD5 hash (or the like) of the users' email address. That way, you don't need the extra field, and you can even leave out the ID if you like.

-Dave

Dave
You can't use an md5 hash for the confirmation code, that would defeat the purpose of confirming your email address, as the 'attacker' could enter any email address and just hash it himself to get the confirmation code. The email address wouldn't even have to be valid.
Jens Roland
Not just an MD5 hash, but some sort of hash which is not easily guessable, or a hash of the email and password together. For that matter, since that would require the password entered before hand, I assume you're storing the password as a hash with a salt, use that same salt with the email address.
Ed Marty
+7  A: 

Another approach is using a centralized authentication and skipping the whole registration process.

On first login attempt, create a user profile from a template.

Authentication can be done a number of ways. Ideally, something like LDAP (or Active Directory if that's how you swing). It's also possible to use the mail server for authentication, depending on how it is configured.

Ryan Graham
+1 -- leverage existing credentials whenever possible.
Michael Haren
That would be great. Not an option in this organization though. There is no LDAP or Active directory server available.
Ethan
You could use the mail server for authentication. And you can cache password hashes on success as a fail over method when the mail server fails.
Ryan Graham
+3  A: 

The OpenID system was basically invented to solve this problem. Basically, someone comes to your site and says "I am XYZ, and you can verify that by checking with ABC". You then have their OpenID provider (which would probably be a server in your company; if you have LDAP you're already most of the way there) verify they are who they say they are (by them logging into the OpenID provider's site). If you can trust the OpenID provider, and the OpenID account hasn't been compromised, then you've just verified your user. You can probably get away without a formal registration process... just send them to the account setup screen (assuming you need more than the password + email in your example, as both of those are provided via OpenID) on their first login.

Note that OpenID can only verify that the user has the credentials for the given OpenID, not that the user is unique, or that they are who they say they are. But this is really no different than any existing scheme.

It has the advantages of not requiring the user to give you a password they might forget (and they can change their password with the OpenID provider and it will be changed for all their sites that use OpenID). There are OpenID libraries available for most major languages, and rolling your own shouldn't be too complex.

rmeador
it's probably worth pointing out that if you're using SO, you've already used OpenID...
rmeador
+1  A: 

The only 'attack' you are addressing through email confirmation, is registering new accounts using random email addresses.

IOW, if you leave that step out, an 'attacker' could:

  1. register accounts using just random gibberish addresses
  2. register accounts using other people's addresses

Fortunately, in most applications, such an attack isn't very destructive. It may help the attacker forge someone else's identity in a social networking app, or make life slightly easier for a spambot, or it could be used just to annoy the legitimate owner of an email address -- but that's about it.

I'd say keep the registration requirement just in case, but scrap the two-step process (let the users create username+password right away).

Jens Roland