I need to provide store's clients with a tool to check the status of their repair orders.
The clients doesn't have a user or password. They are only a record in the database. Yet I need to give them a way to login to the webpage and check their status (ready or not). Forcing then to register is not an option.

I came with this idea:

  • The user is asked for his email address
  • The system check if this email is registered in the database, generates a hash and emails a special url with the hash.
  • The user check's the email and go to this address
  • When the system gets a request to the special address check if the hash is in the database and retrieves the user_id
  • If it's present, voila! Hello John Doe Your order #3454364 is ready for pickup

The Hash generation algorithm would be.

SELECT clients set hash = SUBSTRING(PASSWORD(UUID()), 2);

The hash/password is salted and Bcrypt(ed) in the server.
I could add a timeout (hash valid for 1 day or something like that)

Is there something horribly wrong with this idea?

UPDATE: Corrected the wording so it's less confusing.

What work factor should I use for Bcrypt? It seems to be like the general idea is to increase the number until it takes ~1 second.

I like the output of MySQL's PASSWORD for the hash generation because it's very url friendly. But that's really the only reason. Any other suggestion?

  • 1
    Could you please explain on how/where the BCrypting and salting happens? Because as far as I can see you're directly generating the hash in the SQL query and storing it in the table. Not that this solution needs salting or anything, but I'm just curious.
    – Adi
    May 18, 2013 at 13:48
  • The salting idea came after I wrote the rest, so the sentences aren't in the correct order :-\ May 18, 2013 at 20:47
  • If you already have the user's email address, why not just e-mail the user as soon as the order is completed?
    – Lie Ryan
    Dec 13, 2016 at 10:03

2 Answers 2


The idea itself is fine, your users are performing non-critical actions using a special URL. However, there are two things that could go wrong here:

  • Your identifier is SUBSTRING(PASSWORD(UUID()), 2), the problem is that UUID() isn't very reliable to generate unpredictable and unguessable identifiers.

WARNING: Although UUID() values are intended to be unique, they are not necessarily unguessable or unpredictable. If unpredictability is required, UUID values should be generated some other way.

It's far better to generate random identifiers based on the output of /dev/urandom

  • By not using SSL (HTTPS) the unique identifier will be transmitted in plaintext (and the order status for that matter) and thus it will be exposed for anybody sniffing your client's connection.

But all in all, I say it's a pretty good solution for your purpose.

  • 1
    I like the output of MySQL's PASSWORD for the hash generation because it's very url friendly (and uuid because RANDOM is anything but random). But that's really the only reason. Any other url friendly suggestion? (no need to be mysql based) May 18, 2013 at 21:01
  • @TheDisintegrator It's already there in the second link. It's what Etsy are using for their password reset URLs.
    – Adi
    May 19, 2013 at 0:27

For the level of security that your service sounds like it requires, I'd say that this sounds like a reasonable solution.

The risks are that someone will intercept a link and get access to the customers information, so you should make sure that access to the status page is encrypted via SSL.

For the timeout you could either go with the approach that you've got (time-based) which seems reasonable under the circumstances, or you could set each hash to only be used once (i.e. the hash needs to be re-created each time the customer uses it)

An alternative that I've seen used for this kind of system which is somewhat less secure but easier for customers to use, is to request information about the order (e.g. Order ID, customer surname, customer postal code). This gets rid of the e-mail step, but is susceptible to a brute-force attack.

How secure you want it largely depends on how sensitive the information is and how annoyed the customers would be if someone else gets access to it.

  • 1
    The information is not really sensitive. But I don't want to see this broken at all. May 18, 2013 at 21:04

You must log in to answer this question.

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