3

I am creating a client access system, to allow manage invoices, make payments, access information about their products and information/functionality alike.

Supposedly there are less than 1000 clients. Would there be any security threat to use only password (UUID v4 strings) to authenticate user?

My thoughts:

Thomas Pornin
  • 322,884
  • 58
  • 787
  • 955
Gajus
  • 543
  • 6
  • 9
  • Using UUID, what happen in the case of one of these get "lost" or "compromised"? – Pipe Jan 11 '13 at 18:50
  • For the [user experience](http://ux.stackexchange.com/) perspective, see [Computer login with password only, without username](http://ux.stackexchange.com/questions/32953/computer-login-with-password-only-without-username) – Gilles 'SO- stop being evil' Jan 16 '13 at 20:23
  • See also related - but not identical - question here: [Why do we authenticate by prompting a user to enter both username and password? Does prompting the password only suffice?](http://security.stackexchange.com/q/2384/33) – AviD Aug 18 '13 at 21:19

4 Answers4

10

Main problem with using only the password is that you cannot apply salts.

In a normal, robust server which authenticates users by password, the passwords themselves are not stored "as is" but hashed. The password hashing process requires some care, because an attacker obtaining a copy of that file full of hashed passwords (e.g. through a SQL injection attack) can run a dictionary attack: this is "trying" potential passwords. Human users tend to choose passwords which are "words" in some language, or simple derivatives from that (e.g. appending one digit), hence the term "dictionary".

To make the task harder for the attacker, the password hashing process must:

  1. be inherently slow by mandating, for instance, one million nested hash function invocations;
  2. be salted: the salt is a parameter which alters the way the hashing works, and each hashed password has its own salt value. This way, when the attacker tries a potential password, he must first choose which hashed password he will target.

The username is the selector for the salt: when the server receives the username, it looks it up in its database, obtaining the hashed password and the salt value which was used to compute that hash (both are stored together). This allows the server to recompute the hash, starting with that salt value and the password which the user provided. If the server gets the same hash value than the one which was stored, the user is authenticated; otherwise, the user is rejected. Good algorithms for that are bcrypt and PBKDF2. I prefer bcrypt (but PBKDF2 is not bad).

Without a username, no salt. The server cannot know what salt value to use for the specific password, hence it must use the same salt (i.e. no salt at all) for all stored passwords. This allows the attackers to attack all passwords at once, which is much more efficient.

It is simpler to see it if you think about an online dictionary attack, where the attacker tries potential passwords on your server. With a username+password, the attacker must send a username and a password, and succeeds if the user with that name indeed has that password. Without the username, the attacker just sends a potential password, and succeeds if any user on the system has that password. If you have 1000 users, you just made the attack 1000 times easier.


Also, when a new user registers, he chooses his password. If that password collides with that of another user, then you have no choice but to reject the registration. At that point, the new user just learned that the password he wanted to use is already a valid password for another user -- you just turned the new user into a successful attacker, and he knows it...


Okay, I must remember not to answer question after eating but before the coffee. I just noticed that your "passwords" are actually UUID with 122 bits of randomly generated entropy. In that case, things will be better. We would not call these UUID "passwords", since they are not "words" and are not chosen by a human either, nor even remembered by a human. These are authentication tokens.

You will still want to do your transactions over SSL. Also, since the customers will not remember them, they will write them down, in files or on paper (more probably files, so that they may cut&paste it -- nobody wants to type whole UUID on a regular basis). This makes the secrecy of these UUID more difficult to maintain. Your clients will have to take responsibility for keeping these values secret; this might be a bit too much to ask of a typical client.

Thomas Pornin
  • 322,884
  • 58
  • 787
  • 955
3

I'd suggest you to stick with a pair of strings, user/password, public/private -- whatever we call it.

While there is practically no chance for collision, I see no reason why a password-only authentication would be that better. On the other hand, with a pair of keys, the public one could be a fixed ID of the user, -- allowing a lot of things, such as logging --, doesn't matter how many times the password is changed.

You didn't explicitly mention this, but I'm under the impression you save the credentials (since "it is not intended to be remembered", much like API-keys), so it wouldn't really matter for the user which method you use.

Máté Gelei
  • 131
  • 1
2

You should have a separate userid & password so you can change the password if required or desired without changing the userid. I would assume for audit requirements you will need to track the particular user performing certain activities - which then means the user will need to authenticate (provide their own password), thus a hidden PC-specific UUID will be insufficient.

ericball
  • 171
  • 2
2

My answer on a related question applies here too:

The simple, basic concept that is missing:

Identification and Authentication are not the same thing.

Simply put, these are two separate requirements, and should not be mixed up.
A username provides for identification, and a password allows you to verify that claimed identity (i.e. authentication).


Now, in your proposed scheme, the situation is slightly different - since you expect the "password" to be unrememberable, you are actually trying to implement what some have called a weak "something you have" - since this URL is intended to be retrieved once, and (I assume) saved as a bookmark/favorite, access to the user's desktop supposedly controls access to the user's account.

However, there are still some problems with this:

  • The "password" cannot easily be changed (as has been mentioned);
  • The "password" cannot be easily hashed, because of the retrieval problem mentioned by @Thomas;
  • it is a weak factor, depending on the system you might not want to rely on the security of the user's machine;
  • some current browsers synchronize browser settings, including favorites, across devices. This would in effect enable any of the synched devices access;
  • Since the "password" is in the URL, this might be exposed via the browser's history or cache (there attacks enabling access to this even without physical access to the user's machine);
  • Many setups cause the URL to be logged, such as the webserver logs, reverse proxies, etc.
  • Accidental HTTP access (instead of HTTPS - even if you redirect, the user will just keep clicking that bookmark, since he still gets to the site either way...).

I could go on, finding additional scenarios where it would be possible to expose such a "password". If you want to avoid any password-based authentication, you'd be better off just issuing client-side certificates, and have the user store those. Browser support for those is mature enough (if not transparent or trivial), and the protocols are already in place to support this securely.

AviD
  • 72,708
  • 22
  • 137
  • 218