Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to generate a login token? Is this method of authentication vulnerable to attack?

I have to implement login tokens in my Lithium (the PHP framework) based application. Two reasons:

I want to have a "remember me" function.

I also need a way of tracking logins on the server so that I can verify authenticated users on a node.js socket server like so:

  1. User requests a page
  2. Server returns a view with a session token somewhere in the HTML
  3. The client side JS reads the token and send it to the node.js server in an attempt to establish a connection via web sockets.
  4. The server receives the connect request and verifies the token sent to it with the PHP server.
  5. Allows or denies a connection based on the result.

So this is a two part question, and it's just to verify that I'm not being an idiot because the security on this site is of higher priority than usual.

Is this a reasonable way of creating a login token?

<?php
// String::hash() generates a sha512 (by default) hash. 
String::hash(time() . $user['username']);
?>

Is the web socket authentication system I proposed sane? Can you see any problems arising or any more efficient ways of doing it?

like image 290
rich97 Avatar asked Jul 04 '11 10:07

rich97


People also ask

Why is token-based authentication more secure?

Tokens Offer Robust SecuritySince tokens like JWT are stateless, only a secret key can validate it when received at a server-side application, which was used to create it. Hence they're considered the best and the most secure way of offering authentication.

Is token-based authentication secure?

Token-based authentication is a protocol that generates encrypted security tokens. It enables users to verify their identity to websites, which then generates a unique encrypted authentication token.

Why are personal access tokens better than passwords?

Tokens, such as OAuth, have way more benefits: They don't hang around. They're temporary, stored in the browser, in memory, or a protected cache. Unlike passwords or browser cookies, though, they're automatically destroyed when a session completes or exceeds the expiration time.


2 Answers

First, you should change the way your login token is generated. A hash of the current time concatenated with the username is far from being difficult to guess; which is a necessary condition for it to be secure. There are many ways to do this, what's crucial is that you use a good source of randomness. You could do:

list(,$token) = unpack('H*', openssl_random_pseudo_bytes(15, $safe));
$safe or die("unsafe source");

The overall method you're using is only secure if you the bearer token you're passing around is never sent unencrypted. This means every time it is transmitted it must be transmitted over SSL/TLS.

There's still the problem that you may accidentally send the token to the wrong place, so you must be extra careful if any destination is somehow dynamically generated (e.g. through some discovery protocol). The only way to avoid this problem would be to use cryptography.

like image 175
Artefacto Avatar answered Oct 12 '22 21:10

Artefacto


You should look at the RequestToken class in Lithium: http://li3.me/docs/lithium/security/validation/RequestToken::check()#source

It handles CSRF protection, and uses cryptographically secure random tokens, based on principles similar to the above, but with an extra layer of protection with bcrypt, which can match any number of unique hashes.

like image 26
Nate Abele Avatar answered Oct 12 '22 22:10

Nate Abele